"
dat += "Job Slots Open job Close job Prioritize "
var/ID
- if(scan && (ACCESS_CHANGE_IDS in scan.access) && !target_dept)
+ if(inserted_scan_id && (ACCESS_CHANGE_IDS in inserted_scan_id.access) && !target_dept)
ID = 1
else
ID = 0
@@ -221,33 +260,33 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
var/target_name
var/target_owner
var/target_rank
- if(modify)
- target_name = html_encode(modify.name)
+ if(inserted_modify_id)
+ target_name = html_encode(inserted_modify_id.name)
else
target_name = "--------"
- if(modify && modify.registered_name)
- target_owner = html_encode(modify.registered_name)
+ if(inserted_modify_id && inserted_modify_id.registered_name)
+ target_owner = html_encode(inserted_modify_id.registered_name)
else
target_owner = "--------"
- if(modify && modify.assignment)
- target_rank = html_encode(modify.assignment)
+ if(inserted_modify_id && inserted_modify_id.assignment)
+ target_rank = html_encode(inserted_modify_id.assignment)
else
target_rank = "Unassigned"
var/scan_name
- if(scan)
- scan_name = html_encode(scan.name)
+ if(inserted_scan_id)
+ scan_name = html_encode(inserted_scan_id.name)
else
scan_name = "--------"
if(!authenticated)
header += "Please insert the cards into the slots "
- header += "Target: [target_name] "
- header += "Confirm Identity: [scan_name] "
+ header += "Target: [target_name] "
+ header += "Confirm Identity: [scan_name] "
else
header += ""
@@ -262,7 +301,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
var/body
- if (authenticated && modify)
+ if (authenticated && inserted_modify_id)
var/carddesc = text("")
var/jobs = text("")
@@ -303,7 +342,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
if(istype(src, /obj/machinery/computer/card/centcom))
accesses += "Central Command: "
for(var/A in get_all_centcom_access())
- if(A in modify.access)
+ if(A in inserted_modify_id.access)
accesses += "[replacetext(get_centcom_access_desc(A), " ", " ")] "
else
accesses += "[replacetext(get_centcom_access_desc(A), " ", " ")] "
@@ -321,7 +360,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
continue
accesses += ""
for(var/A in get_region_accesses(i))
- if(A in modify.access)
+ if(A in inserted_modify_id.access)
accesses += "[replacetext(get_access_desc(A), " ", " ")] "
else
accesses += "[replacetext(get_access_desc(A), " ", " ")] "
@@ -353,50 +392,66 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
usr.set_machine(src)
switch(href_list["choice"])
- if ("modify")
- eject_id_modify(usr)
- if ("scan")
- eject_id_scan(usr)
+ if ("inserted_modify_id")
+ if (inserted_modify_id)
+ if(id_eject(usr, inserted_modify_id))
+ inserted_modify_id = null
+ else
+ var/mob/M = usr
+ var/obj/item/card/id/I = M.get_idcard(TRUE)
+ if(id_insert(usr, I, inserted_modify_id))
+ inserted_modify_id = I
+ if ("inserted_scan_id")
+ if (inserted_scan_id)
+ if(id_eject(usr, inserted_scan_id))
+ inserted_scan_id = null
+ else
+ var/mob/M = usr
+ var/obj/item/card/id/I = M.get_idcard(TRUE)
+ if(id_insert(usr, I, inserted_scan_id))
+ inserted_scan_id = I
if ("auth")
- if ((!( authenticated ) && (scan || issilicon(usr)) && (modify || mode)))
- if (check_access(scan))
+ if ((!( authenticated ) && (inserted_scan_id || issilicon(usr)) && (inserted_modify_id || mode)))
+ if (check_access(inserted_scan_id))
region_access = list()
head_subordinates = list()
- if(ACCESS_CHANGE_IDS in scan.access)
+ if(ACCESS_CHANGE_IDS in inserted_scan_id.access)
if(target_dept)
head_subordinates = get_all_jobs()
region_access |= target_dept
authenticated = 1
else
authenticated = 2
- playsound(src, 'sound/machines/terminal_on.ogg', 50, 0)
+ playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE)
else
- if((ACCESS_HOP in scan.access) && ((target_dept==1) || !target_dept))
+ if((ACCESS_HOP in inserted_scan_id.access) && ((target_dept==1) || !target_dept))
region_access |= 1
- region_access |= 6
get_subordinates("Head of Personnel")
- if((ACCESS_HOS in scan.access) && ((target_dept==2) || !target_dept))
+ if((ACCESS_HOS in inserted_scan_id.access) && ((target_dept==2) || !target_dept))
region_access |= 2
get_subordinates("Head of Security")
- if((ACCESS_CMO in scan.access) && ((target_dept==3) || !target_dept))
+ if((ACCESS_CMO in inserted_scan_id.access) && ((target_dept==3) || !target_dept))
region_access |= 3
get_subordinates("Chief Medical Officer")
- if((ACCESS_RD in scan.access) && ((target_dept==4) || !target_dept))
+ if((ACCESS_RD in inserted_scan_id.access) && ((target_dept==4) || !target_dept))
region_access |= 4
get_subordinates("Research Director")
- if((ACCESS_CE in scan.access) && ((target_dept==5) || !target_dept))
+ if((ACCESS_CE in inserted_scan_id.access) && ((target_dept==5) || !target_dept))
region_access |= 5
get_subordinates("Chief Engineer")
+ if((ACCESS_QM in inserted_scan_id.access) && ((target_dept==6) || !target_dept))
+ region_access |= 6
+ get_subordinates("Quartermaster")
if(region_access)
authenticated = 1
- else if ((!( authenticated ) && issilicon(usr)) && (!modify))
+ else if ((!( authenticated ) && issilicon(usr)) && (!inserted_modify_id))
to_chat(usr, "You can't modify an ID without an ID inserted to modify! Once one is in the modify slot on the computer, you can log in. ")
if ("logout")
region_access = null
head_subordinates = null
authenticated = 0
- playsound(src, 'sound/machines/terminal_off.ogg', 50, 0)
+ playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE)
if("access")
if(href_list["allowed"])
@@ -404,20 +459,20 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
var/access_type = text2num(href_list["access_target"])
var/access_allowed = text2num(href_list["allowed"])
if(access_type in (istype(src, /obj/machinery/computer/card/centcom)?get_all_centcom_access() : get_all_accesses()))
- modify.access -= access_type
+ inserted_modify_id.access -= access_type
if(access_allowed == 1)
- modify.access += access_type
- playsound(src, "terminal_type", 50, 0)
+ inserted_modify_id.access += access_type
+ playsound(src, "terminal_type", 50, FALSE)
if ("assign")
if (authenticated == 2)
var/t1 = href_list["assign_target"]
if(t1 == "Custom")
- var/newJob = reject_bad_text(input("Enter a custom job assignment.", "Assignment", modify ? modify.assignment : "Unassigned"), MAX_NAME_LEN)
+ var/newJob = reject_bad_text(input("Enter a custom job assignment.", "Assignment", inserted_modify_id ? inserted_modify_id.assignment : "Unassigned"), MAX_NAME_LEN)
if(newJob)
t1 = newJob
else if(t1 == "Unassigned")
- modify.access -= get_all_accesses()
+ inserted_modify_id.access -= get_all_accesses()
else
var/datum/job/jobdatum
@@ -432,24 +487,24 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
updateUsrDialog()
return
- modify.access = ( istype(src, /obj/machinery/computer/card/centcom) ? get_centcom_access(t1) : jobdatum.get_access() )
- if (modify)
- modify.assignment = t1
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ inserted_modify_id.access = ( istype(src, /obj/machinery/computer/card/centcom) ? get_centcom_access(t1) : jobdatum.get_access() )
+ if (inserted_modify_id)
+ inserted_modify_id.assignment = t1
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if ("demote")
- if(modify.assignment in head_subordinates || modify.assignment == "Assistant")
- modify.assignment = "Unassigned"
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ if(inserted_modify_id.assignment in head_subordinates || inserted_modify_id.assignment == "Assistant")
+ inserted_modify_id.assignment = "Unassigned"
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
else
to_chat(usr, "You are not authorized to demote this position. ")
if ("reg")
if (authenticated)
- var/t2 = modify
- if ((authenticated && modify == t2 && (in_range(src, usr) || issilicon(usr)) && isturf(loc)))
+ var/t2 = inserted_modify_id
+ if ((authenticated && inserted_modify_id == t2 && (in_range(src, usr) || issilicon(usr)) && isturf(loc)))
var/newName = reject_bad_name(href_list["reg"])
if(newName)
- modify.registered_name = newName
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ inserted_modify_id.registered_name = newName
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
else
to_chat(usr, "Invalid name entered. ")
updateUsrDialog()
@@ -460,11 +515,11 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
if("return")
//DISPLAY MAIN MENU
mode = 3;
- playsound(src, "terminal_type", 25, 0)
+ playsound(src, "terminal_type", 25, FALSE)
if("make_job_available")
// MAKE ANOTHER JOB POSITION AVAILABLE FOR LATE JOINERS
- if(scan && (ACCESS_CHANGE_IDS in scan.access) && !target_dept)
+ if(inserted_scan_id && (ACCESS_CHANGE_IDS in inserted_scan_id.access) && !target_dept)
var/edit_job_target = href_list["job"]
var/datum/job/j = SSjob.GetJob(edit_job_target)
if(!j)
@@ -477,11 +532,11 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
GLOB.time_last_changed_position = world.time / 10
j.total_positions++
opened_positions[edit_job_target]++
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if("make_job_unavailable")
// MAKE JOB POSITION UNAVAILABLE FOR LATE JOINERS
- if(scan && (ACCESS_CHANGE_IDS in scan.access) && !target_dept)
+ if(inserted_scan_id && (ACCESS_CHANGE_IDS in inserted_scan_id.access) && !target_dept)
var/edit_job_target = href_list["job"]
var/datum/job/j = SSjob.GetJob(edit_job_target)
if(!j)
@@ -495,11 +550,11 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
GLOB.time_last_changed_position = world.time / 10
j.total_positions--
opened_positions[edit_job_target]--
- playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
if ("prioritize_job")
// TOGGLE WHETHER JOB APPEARS AS PRIORITIZED IN THE LOBBY
- if(scan && (ACCESS_CHANGE_IDS in scan.access) && !target_dept)
+ if(inserted_scan_id && (ACCESS_CHANGE_IDS in inserted_scan_id.access) && !target_dept)
var/priority_target = href_list["job"]
var/datum/job/j = SSjob.GetJob(priority_target)
if(!j)
@@ -516,7 +571,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
else
SSjob.prioritized_jobs += j
to_chat(usr, "[j.title] has been successfully [priority ? "prioritized" : "unprioritized"]. Potential employees will notice your request. ")
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if ("print")
if (!( printing ))
@@ -529,59 +584,9 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
P.info = t1
P.name = "paper- 'Crew Manifest'"
printing = null
- playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- if (modify)
- modify.update_label()
- updateUsrDialog()
-
-/obj/machinery/computer/card/AltClick(mob/user)
- if(!user.canUseTopic(src, !issilicon(user)) || !is_operational())
- return
- if(scan)
- eject_id_scan(user)
- if(modify)
- eject_id_modify(user)
-
-/obj/machinery/computer/card/proc/eject_id_scan(mob/user)
- if(scan)
- scan.forceMove(drop_location())
- if(!issilicon(user) && Adjacent(user))
- user.put_in_hands(scan)
- playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- scan = null
- else //switching the ID with the one you're holding
- if(issilicon(user) || !Adjacent(user))
- return
- var/obj/item/I = user.get_active_held_item()
- if(istype(I, /obj/item/card/id))
- if(!user.transferItemToLoc(I,src))
- return
- playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- scan = I
- authenticated = FALSE
- updateUsrDialog()
-
-/obj/machinery/computer/card/proc/eject_id_modify(mob/user)
- if(modify)
- GLOB.data_core.manifest_modify(modify.registered_name, modify.assignment)
- modify.update_label()
- modify.forceMove(drop_location())
- if(!issilicon(user) && Adjacent(user))
- user.put_in_hands(modify)
- playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- modify = null
- region_access = null
- head_subordinates = null
- else //switching the ID with the one you're holding
- if(issilicon(user) || !Adjacent(user))
- return
- var/obj/item/I = user.get_active_held_item()
- if(istype(I, /obj/item/card/id))
- if (!user.transferItemToLoc(I,src))
- return
- playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, 0)
- modify = I
- authenticated = FALSE
+ playsound(src, 'sound/machines/terminal_insert_disc.ogg', 50, FALSE)
+ if (inserted_modify_id)
+ inserted_modify_id.update_label()
updateUsrDialog()
/obj/machinery/computer/card/proc/get_subordinates(rank)
@@ -607,7 +612,7 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
typed_circuit.target_dept = target_dept
else
target_dept = typed_circuit.target_dept
- var/list/dept_list = list("general","security","medical","science","engineering")
+ var/list/dept_list = list("civilian","security","medical","science","engineering","cargo")
name = "[dept_list[target_dept]] department console"
/obj/machinery/computer/card/minor/hos
@@ -631,3 +636,9 @@ GLOBAL_VAR_INIT(time_last_changed_position, 0)
icon_screen = "idce"
light_color = LIGHT_COLOR_YELLOW
+
+/obj/machinery/computer/card/minor/qm
+ target_dept = 6
+ icon_screen = "idqm"
+
+ light_color = LIGHT_COLOR_ORANGE
\ No newline at end of file
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index 26f0d06ecb..43cfbdb33b 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -159,11 +159,11 @@
if(scanner && HasEfficientPod() && scanner.scan_level >= AUTOCLONING_MINIMAL_LEVEL)
if(!autoprocess)
- dat += "Autoprocess "
+ dat += "Autoclone "
else
- dat += "Stop autoprocess "
+ dat += "Stop autoclone "
else
- dat += "Autoprocess "
+ dat += "Autoclone "
dat += "Cloning Pod Status "
dat += "[temp]
"
@@ -228,7 +228,7 @@
dat += "[src.active_record.fields["name"]] "
dat += "Scan ID [src.active_record.fields["id"]] Clone "
- var/obj/item/implant/health/H = locate(src.active_record.fields["imp"])
+ var/obj/item/implant/health/H = locate(active_record.fields["imp"])
if ((H) && (istype(H)))
dat += "Health Implant Data: [H.sensehealth()] "
@@ -298,13 +298,15 @@
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
say("Initiating scan...")
-
+ var/prev_locked = scanner.locked
+ scanner.locked = TRUE
spawn(20)
src.scan_occupant(scanner.occupant)
loading = 0
src.updateUsrDialog()
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
+ scanner.locked = prev_locked
//No locking an open scanner.
diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm
index 557f2f0636..f3612078d6 100755
--- a/code/game/machinery/computer/communications.dm
+++ b/code/game/machinery/computer/communications.dm
@@ -335,7 +335,7 @@
Nuke_request(input, usr)
to_chat(usr, "Request sent. ")
usr.log_message("has requested the nuclear codes from CentCom", LOG_SAY)
- priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested",'sound/ai/commandreport.ogg')
+ priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested","commandreport")
CM.lastTimeUsed = world.time
diff --git a/code/game/machinery/computer/gulag_teleporter.dm b/code/game/machinery/computer/gulag_teleporter.dm
deleted file mode 100644
index 68cbf03f03..0000000000
--- a/code/game/machinery/computer/gulag_teleporter.dm
+++ /dev/null
@@ -1,163 +0,0 @@
-//computer that handle the points and teleports the prisoner
-/obj/machinery/computer/gulag_teleporter_computer
- name = "labor camp teleporter console"
- desc = "Used to send criminals to the Labor Camp."
- icon_screen = "explosive"
- icon_keyboard = "security_key"
- req_access = list(ACCESS_ARMORY)
- circuit = /obj/item/circuitboard/computer/gulag_teleporter_console
- var/default_goal = 200
- var/obj/item/card/id/prisoner/id = null
- var/obj/machinery/gulag_teleporter/teleporter = null
- var/obj/structure/gulag_beacon/beacon = null
- var/mob/living/carbon/human/prisoner = null
- var/datum/data/record/temporary_record = null
-
- light_color = LIGHT_COLOR_RED
-
-/obj/machinery/computer/gulag_teleporter_computer/Initialize()
- . = ..()
- scan_machinery()
-
-/obj/machinery/computer/gulag_teleporter_computer/Destroy()
- if(id)
- id.forceMove(get_turf(src))
- return ..()
-
-/obj/machinery/computer/gulag_teleporter_computer/attackby(obj/item/W, mob/user)
- if(istype(W, /obj/item/card/id/prisoner))
- if(!id)
- if (!user.transferItemToLoc(W,src))
- return
- id = W
- to_chat(user, "You insert [W]. ")
- return
- else
- to_chat(user, "There's an ID inserted already. ")
- return ..()
-
-/obj/machinery/computer/gulag_teleporter_computer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
- 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, "gulag_console", name, 455, 440, master_ui, state)
- ui.open()
-
-/obj/machinery/computer/gulag_teleporter_computer/ui_data(mob/user)
- var/list/data = list()
-
- var/list/prisoner_list = list()
- var/can_teleport = FALSE
-
- if(teleporter && (teleporter.occupant && ishuman(teleporter.occupant)))
- prisoner = teleporter.occupant
- prisoner_list["name"] = prisoner.real_name
- if(id)
- can_teleport = TRUE
- if(!isnull(GLOB.data_core.general))
- for(var/r in GLOB.data_core.security)
- var/datum/data/record/R = r
- if(R.fields["name"] == prisoner_list["name"])
- temporary_record = R
- prisoner_list["crimstat"] = temporary_record.fields["criminal"]
-
- data["prisoner"] = prisoner_list
-
- if(teleporter)
- data["teleporter"] = teleporter
- data["teleporter_location"] = "([teleporter.x], [teleporter.y], [teleporter.z])"
- data["teleporter_lock"] = teleporter.locked
- data["teleporter_state_open"] = teleporter.state_open
- if(beacon)
- data["beacon"] = beacon
- data["beacon_location"] = "([beacon.x], [beacon.y], [beacon.z])"
- if(id)
- data["id"] = id
- data["id_name"] = id.registered_name
- data["goal"] = id.goal
- data["can_teleport"] = can_teleport
-
- return data
-
-/obj/machinery/computer/gulag_teleporter_computer/ui_act(action, list/params)
- if(..())
- return
- if(!allowed(usr))
- to_chat(usr, "Access denied. ")
- return
- switch(action)
- if("scan_teleporter")
- teleporter = findteleporter()
- if("scan_beacon")
- beacon = findbeacon()
- if("handle_id")
- if(id)
- usr.put_in_hands(id)
- id = null
- else
- var/obj/item/I = usr.is_holding_item_of_type(/obj/item/card/id/prisoner)
- if(I)
- if(!usr.transferItemToLoc(I, src))
- return
- id = I
- if("set_goal")
- var/new_goal = input("Set the amount of points:", "Points", id.goal) as num|null
- if(!isnum(new_goal))
- return
- if(!new_goal)
- new_goal = default_goal
- if (new_goal > 1000)
- to_chat(usr, "The entered amount of points is too large. Points have instead been set to the maximum allowed amount.")
- id.goal = CLAMP(new_goal, 0, 1000) //maximum 1000 points
- if("toggle_open")
- if(teleporter.locked)
- to_chat(usr, "The teleporter is locked")
- return
- teleporter.toggle_open()
- if("teleporter_lock")
- if(teleporter.state_open)
- to_chat(usr, "Close the teleporter before locking!")
- return
- teleporter.locked = !teleporter.locked
- if("teleport")
- if(!teleporter || !beacon)
- return
- addtimer(CALLBACK(src, .proc/teleport, usr), 5)
-
-/obj/machinery/computer/gulag_teleporter_computer/proc/scan_machinery()
- teleporter = findteleporter()
- beacon = findbeacon()
-
-/obj/machinery/computer/gulag_teleporter_computer/proc/findteleporter()
- var/obj/machinery/gulag_teleporter/teleporterf = null
-
- for(var/direction in GLOB.cardinals)
- teleporterf = locate(/obj/machinery/gulag_teleporter, get_step(src, direction))
- if(teleporterf && teleporterf.is_operational())
- return teleporterf
-
-/obj/machinery/computer/gulag_teleporter_computer/proc/findbeacon()
- return locate(/obj/structure/gulag_beacon)
-
-/obj/machinery/computer/gulag_teleporter_computer/proc/teleport(mob/user)
- if(!id) //incase the ID was removed after the transfer timer was set.
- say("Warning: Unable to transfer prisoner without a valid Prisoner ID inserted!")
- return
- var/id_goal_not_set
- if(!id.goal)
- id_goal_not_set = TRUE
- id.goal = default_goal
- say("[id]'s ID card goal defaulting to [id.goal] points.")
- log_game("[key_name(user)] teleported [key_name(prisoner)] to the Labor Camp [COORD(beacon)] for [id_goal_not_set ? "default goal of ":""][id.goal] points.")
- teleporter.handle_prisoner(id, temporary_record)
- playsound(src, 'sound/weapons/emitter.ogg', 50, 1)
- prisoner.forceMove(get_turf(beacon))
- prisoner.Knockdown(40) // small travel dizziness
- to_chat(prisoner, "The teleportation makes you a little dizzy. ")
- new /obj/effect/particle_effect/sparks(get_turf(prisoner))
- playsound(src, "sparks", 50, 1)
- if(teleporter.locked)
- teleporter.locked = FALSE
- teleporter.toggle_open()
- id = null
- temporary_record = null
diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm
index d4fe3e27a2..33de8bfce2 100644
--- a/code/game/machinery/computer/medical.dm
+++ b/code/game/machinery/computer/medical.dm
@@ -22,12 +22,6 @@
/obj/machinery/computer/med_data/syndie
icon_keyboard = "syndie_key"
-/obj/machinery/computer/med_data/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/card/id))
- id_insert_scan(user)
- else
- return ..()
-
/obj/machinery/computer/med_data/ui_interact(mob/user)
. = ..()
if(isliving(user))
@@ -484,7 +478,7 @@
var/counter = 1
while(active2.fields[text("com_[]", counter)])
counter++
- active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], [] []", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
+ active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], [] []", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
else if(href_list["del_c"])
if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]))
@@ -575,7 +569,7 @@
if(user)
if(message)
if(authenticated)
- if(user.canUseTopic(src, BE_CLOSE))
+ if(user.canUseTopic(src, !issilicon(user)))
if(!record1 || record1 == active1)
if(!record2 || record2 == active2)
return 1
diff --git a/code/game/machinery/computer/prisoner.dm b/code/game/machinery/computer/prisoner.dm
deleted file mode 100644
index a852612d9d..0000000000
--- a/code/game/machinery/computer/prisoner.dm
+++ /dev/null
@@ -1 +0,0 @@
-/obj/machinery/computer/prisoner
diff --git a/code/game/machinery/computer/prisoner/management.dm b/code/game/machinery/computer/prisoner/management.dm
index e231a1748a..653f6bf48b 100644
--- a/code/game/machinery/computer/prisoner/management.dm
+++ b/code/game/machinery/computer/prisoner/management.dm
@@ -35,11 +35,11 @@
dat += " Chemical Implants "
var/turf/Tr = null
for(var/obj/item/implant/chem/C in GLOB.tracked_chem_implants)
- Tr = get_turf(C)
- if((Tr) && (Tr.z != src.z))
- continue//Out of range
if(!C.imp_in)
continue
+ Tr = get_turf(C.imp_in)
+ if((Tr) && (Tr.z != src.z))
+ continue//Out of range
dat += "ID: [C.imp_in.name] | Remaining Units: [C.reagents.total_volume] "
dat += "| Inject: "
dat += "((1) ) "
@@ -48,9 +48,9 @@
dat += "******************************** "
dat += " Tracking Implants "
for(var/obj/item/implant/tracking/T in GLOB.tracked_implants)
- if(!isliving(T.imp_in))
+ if(!T.imp_in || !isliving(T.imp_in))
continue
- Tr = get_turf(T)
+ Tr = get_turf(T.imp_in)
if((Tr) && (Tr.z != src.z))
continue//Out of range
diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm
index 1823e34100..c9f2f28ab1 100644
--- a/code/game/machinery/computer/security.dm
+++ b/code/game/machinery/computer/security.dm
@@ -35,7 +35,8 @@
//Someone needs to break down the dat += into chunks instead of long ass lines.
/obj/machinery/computer/secure_data/ui_interact(mob/user)
. = ..()
- playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
+ if(isliving(user))
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if(src.z > 6)
to_chat(user, "Unable to establish a connection : \black You're too far away from the station!")
return
@@ -455,7 +456,7 @@ What a mess.*/
var/counter = 1
while(active2.fields[text("com_[]", counter)])
counter++
- active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], [] []", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
+ active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], [] []", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
if("Delete Record (ALL)")
if(active1)
@@ -801,7 +802,7 @@ What a mess.*/
/obj/machinery/computer/secure_data/proc/canUseSecurityRecordsConsole(mob/user, message1 = 0, record1, record2)
if(user)
if(authenticated)
- if(user.canUseTopic(src, BE_CLOSE))
+ if(user.canUseTopic(src, !issilicon(user)))
if(!trim(message1))
return 0
if(!record1 || record1 == active1)
diff --git a/code/game/machinery/computer/telecrystalconsoles.dm b/code/game/machinery/computer/telecrystalconsoles.dm
index 692bc8f038..67407d220e 100644
--- a/code/game/machinery/computer/telecrystalconsoles.dm
+++ b/code/game/machinery/computer/telecrystalconsoles.dm
@@ -33,7 +33,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
if(uplinkholder)
to_chat(user, "[src] already has an uplink in it. ")
return
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, I)
+ var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink)
if(hidden_uplink)
if(!user.transferItemToLoc(I, src))
return
@@ -57,7 +57,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
/obj/machinery/computer/telecrystals/uplinker/proc/donateTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, uplinkholder)
+ var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
if(amt < 0)
linkedboss.storedcrystals += hidden_uplink.telecrystals
if(addLog)
@@ -71,7 +71,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
/obj/machinery/computer/telecrystals/uplinker/proc/giveTC(amt, addLog = 1)
if(uplinkholder && linkedboss)
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, uplinkholder)
+ var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
if(amt < 0)
hidden_uplink.telecrystals += linkedboss.storedcrystals
if(addLog)
@@ -94,7 +94,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
dat += "No linked management consoles detected. Scan for uplink stations using the management console. "
if(uplinkholder)
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, uplinkholder)
+ var/datum/component/uplink/hidden_uplink = uplinkholder.GetComponent(/datum/component/uplink)
dat += "[hidden_uplink.telecrystals] telecrystals remain in this uplink. "
if(linkedboss)
dat += "Donate TC: 1 | 5 | All "
@@ -170,7 +170,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
for(var/obj/machinery/computer/telecrystals/uplinker/A in TCstations)
dat += "[A.name] | "
if(A.uplinkholder)
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, A.uplinkholder)
+ var/datum/component/uplink/hidden_uplink = A.uplinkholder.GetComponent(/datum/component/uplink)
dat += "[hidden_uplink.telecrystals] telecrystals."
if(storedcrystals)
dat+= " Add TC: 1 | 5 | 10 | All "
diff --git a/code/game/machinery/computer/teleporter.dm b/code/game/machinery/computer/teleporter.dm
index b9b95eecd0..b5869ef36b 100644
--- a/code/game/machinery/computer/teleporter.dm
+++ b/code/game/machinery/computer/teleporter.dm
@@ -10,6 +10,7 @@
var/obj/machinery/teleport/station/power_station
var/calibrating
var/turf/target
+ var/obj/item/implant/imp_t
/obj/machinery/computer/teleporter/Initialize()
. = ..()
@@ -89,6 +90,7 @@
say("Processing hub calibration to target...")
calibrating = 1
+ power_station.update_icon()
spawn(50 * (3 - power_station.teleporter_hub.accurate)) //Better parts mean faster calibration
calibrating = 0
if(check_hub_connection())
@@ -96,6 +98,7 @@
say("Calibration complete.")
else
say("Error: Unable to detect hub.")
+ power_station.update_icon()
updateDialog()
updateDialog()
@@ -109,6 +112,9 @@
/obj/machinery/computer/teleporter/proc/reset_regime()
target = null
+ if(imp_t)
+ UnregisterSignal(imp_t, COMSIG_IMPLANT_REMOVING)
+ imp_t = null
if(regime_set == "Teleporter")
regime_set = "Gate"
else
@@ -124,18 +130,32 @@
L[avoid_assoc_duplicate_keys(A.name, areaindex)] = R
for(var/obj/item/implant/tracking/I in GLOB.tracked_implants)
- if(!I.imp_in || !isliving(I.loc))
+ if(!I.imp_in || !isliving(I.imp_in))
continue
else
- var/mob/living/M = I.loc
+ var/mob/living/M = I.imp_in
if(M.stat == DEAD)
if(M.timeofdeath + 6000 < world.time)
continue
- if(is_eligible(I))
- L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = I
+ if(is_eligible(M))
+ L[avoid_assoc_duplicate_keys(M.real_name, areaindex)] = M
var/desc = input("Please select a location to lock in.", "Locking Computer") as null|anything in L
+ if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //check if we are still around
+ return
target = L[desc]
+ if(imp_t)
+ UnregisterSignal(imp_t, COMSIG_IMPLANT_REMOVING)
+ imp_t = null
+ if(isliving(target)) //make sure the living mob is still implanted to be a valid target
+ var/mob/living/M = target
+ var/obj/item/implant/tracking/I = locate() in M.implants
+ if(I)
+ RegisterSignal(I, COMSIG_IMPLANT_REMOVING, .proc/untarget_implant)
+ imp_t = I
+ else
+ target = null
+ return
var/turf/T = get_turf(target)
log_game("[key_name(user)] has set the teleporter target to [target] at [AREACOORD(T)]")
@@ -149,6 +169,8 @@
to_chat(user, "No active connected stations located. ")
return
var/desc = input("Please select a station to lock in.", "Locking Computer") as null|anything in L
+ if(!user.canUseTopic(src, !issilicon(user), NO_DEXTERY)) //again, check if we are still around
+ return
var/obj/machinery/teleport/station/target_station = L[desc]
if(!target_station || !target_station.teleporter_hub)
return
@@ -164,6 +186,14 @@
target_station.teleporter_console.stat &= ~NOPOWER
target_station.teleporter_console.update_icon()
+/obj/machinery/computer/teleporter/proc/untarget_implant() //untargets from mob the racker was once implanted in to prevent issues.
+ target = null
+ if(power_station)
+ power_station.engaged = FALSE
+ power_station.teleporter_hub?.update_icon()
+ UnregisterSignal(imp_t, COMSIG_IMPLANT_REMOVING)
+ imp_t = null
+
/obj/machinery/computer/teleporter/proc/is_eligible(atom/movable/AM)
var/turf/T = get_turf(AM)
if(!T)
diff --git a/modular_citadel/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm
similarity index 68%
rename from modular_citadel/code/game/machinery/cryopod.dm
rename to code/game/machinery/cryopod.dm
index 15e7d34c65..4d252f1a46 100644
--- a/modular_citadel/code/game/machinery/cryopod.dm
+++ b/code/game/machinery/cryopod.dm
@@ -20,105 +20,146 @@
req_one_access = list(ACCESS_HEADS, ACCESS_ARMORY) //Heads of staff or the warden can go here to claim recover items from their department that people went were cryodormed with.
var/mode = null
+ var/menu = 1 //Which menu screen to display
+
//Used for logging people entering cryosleep and important items they are carrying.
var/list/frozen_crew = list()
var/list/frozen_items = list()
- var/storage_type = "crewmembers"
- var/storage_name = "Cryogenic Oversight Control"
+ // Used for containing rare items traitors need to steal, so it's not
+ // game-over if they get iced
+ var/list/objective_items = list()
+ // A cache of theft datums so you don't have to re-create them for
+ // each item check
+ var/list/theft_cache = list()
+
var/allow_items = TRUE
+/obj/machinery/computer/cryopod/attack_ai()
+ attack_hand()
+
/obj/machinery/computer/cryopod/ui_interact(mob/user = usr)
- . = ..()
+ if(!is_operational())
+ return
user.set_machine(src)
add_fingerprint(user)
- var/dat
+ var/dat = ""
- dat += "[storage_name] "
- dat += "Welcome, [user.real_name]. "
- dat += "View storage log . "
- if(allow_items)
- dat += "View objects . "
- dat += "Recover object . "
- dat += "Recover all objects . "
+ dat += "Welcome, [user.real_name]. "
+ dat += " "
- user << browse(dat, "window=cryopod_console")
- onclose(user, "cryopod_console")
+ switch(src.menu)
+ if(1)
+ dat += "View crew storage log "
+ if(allow_items)
+ dat += "View objects storage log "
+ dat += "Recover object "
+ dat += "Recover all objects "
+ if(2)
+ dat += "<< Back "
+ dat += "Recently stored Crew "
+ if(!frozen_crew.len)
+ dat += "There has been no storage usage at this terminal. "
+ else
+ for(var/person in frozen_crew)
+ dat += "[person] "
+ dat += " "
+ if(3)
+ dat += "<< Back "
+ dat += "Recently stored objects "
+ if(!frozen_items.len)
+ dat += "There has been no storage usage at this terminal. "
+ else
+ for(var/obj/item/I in frozen_items)
+ dat += "[I.name] "
+ dat += " "
+
+ var/datum/browser/popup = new(user, "cryopod_console", "Cryogenic System Control")
+ popup.set_content(dat)
+ popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
+ popup.open()
/obj/machinery/computer/cryopod/Topic(href, href_list)
if(..())
- return 1
+ return TRUE
var/mob/user = usr
add_fingerprint(user)
- if(href_list["log"])
-
- var/dat = "Recently stored [storage_type] "
- for(var/person in frozen_crew)
- dat += "[person] "
- dat += " "
-
- user << browse(dat, "window=cryolog")
-
- if(href_list["view"])
- if(!allow_items) return
-
- var/dat = "Recently stored objects "
- for(var/obj/item/I in frozen_items)
- dat += "[I.name] "
- dat += " "
-
- user << browse(dat, "window=cryoitems")
-
- else if(href_list["item"])
+ if(href_list["item"])
if(!allowed(user))
to_chat(user, "Access Denied. ")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ updateUsrDialog()
return
if(!allow_items) return
if(frozen_items.len == 0)
to_chat(user, "There is nothing to recover from storage. ")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ updateUsrDialog()
return
var/obj/item/I = input(user, "Please choose which object to retrieve.","Object recovery",null) as null|anything in frozen_items
+ playsound(src, "terminal_type", 25, 0)
if(!I)
return
if(!(I in frozen_items))
to_chat(user, "\The [I] is no longer in storage. ")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ updateUsrDialog()
return
visible_message("The console beeps happily as it disgorges \the [I]. ")
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
- I.forceMove(get_turf(src))
+ I.forceMove(drop_location())
+ if(user && Adjacent(user) && !issiliconoradminghost(user))
+ user.put_in_hands(I)
frozen_items -= I
+ updateUsrDialog()
else if(href_list["allitems"])
+ playsound(src, "terminal_type", 25, 0)
if(!allowed(user))
to_chat(user, "Access Denied. ")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
+ updateUsrDialog()
return
if(!allow_items) return
if(frozen_items.len == 0)
to_chat(user, "There is nothing to recover from storage. ")
+ playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
return
visible_message("The console beeps happily as it disgorges the desired objects. ")
+ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
for(var/obj/item/I in frozen_items)
- I.forceMove(get_turf(src))
+ I.forceMove(drop_location())
frozen_items -= I
+ updateUsrDialog()
+ else if (href_list["menu"])
+ src.menu = text2num(href_list["menu"])
+ playsound(src, "terminal_type", 25, 0)
+ updateUsrDialog()
+
+ ui_interact(usr)
updateUsrDialog()
+ return
/obj/item/circuitboard/cryopodcontrol
name = "Circuit board (Cryogenic Oversight Console)"
build_path = "/obj/machinery/computer/cryopod"
+/obj/machinery/computer/cryopod/contents_explosion()
+ return
//Cryopods themselves.
/obj/machinery/cryopod
@@ -176,16 +217,17 @@
/obj/item/gun/energy/laser/cyborg
)
-/obj/machinery/cryopod/Initialize()
+/obj/machinery/cryopod/Initialize(mapload)
. = ..()
update_icon()
- find_control_computer(TRUE)
+ find_control_computer(mapload)
/obj/machinery/cryopod/proc/find_control_computer(urgent = FALSE)
for(var/obj/machinery/computer/cryopod/C in get_area(src))
control_computer = C
if(C)
return C
+ break
// Don't send messages unless we *need* the computer, and less than five minutes have passed since last time we messaged
if(!control_computer && urgent && last_no_computer_message + 5*60*10 < world.time)
@@ -193,7 +235,7 @@
message_admins("Cryopod in [get_area(src)] could not find control computer!")
last_no_computer_message = world.time
- return null
+ return control_computer != null
/obj/machinery/cryopod/close_machine(mob/user)
if(!control_computer)
@@ -242,10 +284,75 @@
despawn_occupant()
+#define CRYO_DESTROY 0
+#define CRYO_PRESERVE 1
+#define CRYO_OBJECTIVE 2
+
+/obj/machinery/cryopod/proc/should_preserve_item(obj/item/I)
+ for(var/datum/objective_item/steal/T in control_computer.theft_cache)
+ if(istype(I, T.targetitem) && T.check_special_completion(I))
+ return CRYO_OBJECTIVE
+ for(var/T in preserve_items)
+ if(istype(I, T) && !(I.type in do_not_preserve_items))
+ return CRYO_PRESERVE
+ return CRYO_DESTROY
+
// This function can not be undone; do not call this unless you are sure
/obj/machinery/cryopod/proc/despawn_occupant()
+ if(!control_computer)
+ find_control_computer()
+
var/mob/living/mob_occupant = occupant
+ //Handle Borg stuff first
+ if(iscyborg(mob_occupant))
+ var/mob/living/silicon/robot/R = mob_occupant
+ if(!istype(R)) return ..()
+
+ R.contents -= R.mmi
+ qdel(R.mmi)
+ for(var/obj/item/I in R.module) // the tools the borg has; metal, glass, guns etc
+ for(var/obj/item/O in I) // the things inside the tools, if anything; mainly for janiborg trash bags
+ if(should_preserve_item(O) != CRYO_DESTROY) // Preserve important things inside the item
+ continue
+ O.forceMove(src)
+ R.module.remove_module(I, TRUE) //delete the module itself so it doesn't transfer over.
+
+ //Drop all items into the pod.
+ for(var/obj/item/I in mob_occupant)
+ mob_occupant.doUnEquip(I)
+ I.forceMove(src)
+
+ if(I.contents.len) //Make sure we catch anything not handled by qdel() on the items.
+ if(should_preserve_item(I) != CRYO_DESTROY) // Don't remove the contents of things that need preservation
+ continue
+ for(var/obj/item/O in I.contents)
+ if(istype(O, /obj/item/tank)) //Stop eating pockets, you fuck!
+ continue
+ O.forceMove(src)
+
+ //Delete all items not on the preservation list.
+ var/list/items = contents
+ items -= mob_occupant // Don't delete the occupant
+
+ for(var/obj/item/I in items)
+ if(istype(I, /obj/item/pda))
+ var/obj/item/pda/P = I
+ QDEL_NULL(P.id)
+ qdel(P)
+ continue
+
+ var/preserve = should_preserve_item(I)
+ if(preserve == CRYO_DESTROY)
+ qdel(I)
+ else if(control_computer && control_computer.allow_items)
+ control_computer.frozen_items += I
+ if(preserve == CRYO_OBJECTIVE)
+ control_computer.objective_items += I
+ I.loc = null
+ else
+ I.forceMove(loc)
+
//Update any existing objectives involving this mob.
for(var/datum/objective/O in GLOB.objectives)
// We don't want revs to get objectives that aren't for heads of staff. Letting
@@ -263,16 +370,14 @@
O.find_target()
O.update_explanation_text()
if(!(O.target))
- O.owner.objectives -= O
qdel(O)
- if(mob_occupant.mind && mob_occupant.mind.assigned_role)
+ if(mob_occupant.mind)
//Handle job slot/tater cleanup.
- var/job = mob_occupant.mind.assigned_role
- SSjob.FreeRole(job)
- if(mob_occupant.mind.objectives.len)
- mob_occupant.mind.objectives.Cut()
- mob_occupant.mind.special_role = null
+ if(mob_occupant.mind.assigned_role)
+ var/job = mob_occupant.mind.assigned_role
+ SSjob.FreeRole(job)
+ mob_occupant.mind.special_role = null
// Delete them from datacore.
@@ -302,30 +407,6 @@
announcer.announce("CRYOSTORAGE", mob_occupant.real_name, announce_rank, list())
visible_message("\The [src] hums and hisses as it moves [mob_occupant.real_name] into storage. ")
-
- for(var/obj/item/W in mob_occupant.GetAllContents())
- if(W.loc.loc && (( W.loc.loc == loc ) || (W.loc.loc == control_computer)))
- continue//means we already moved whatever this thing was in
- //I'm a professional, okay
- for(var/T in preserve_items)
- if(istype(W, T))
- if(control_computer && control_computer.allow_items)
- control_computer.frozen_items += W
- mob_occupant.transferItemToLoc(W, control_computer, TRUE)
- else
- mob_occupant.transferItemToLoc(W, loc, TRUE)
-
- for(var/obj/item/W in mob_occupant.GetAllContents())
- qdel(W)//because we moved all items to preserve away
- //and yes, this totally deletes their bodyparts one by one, I just couldn't bother
-
- if(iscyborg(mob_occupant))
- var/mob/living/silicon/robot/R = occupant
- if(!istype(R)) return ..()
-
- R.contents -= R.mmi
- qdel(R.mmi)
-
// Ghost and delete the mob.
if(!mob_occupant.get_ghost(1))
mob_occupant.ghostize(0) // Players who cryo out may not re-enter the round
@@ -334,6 +415,10 @@
open_machine()
name = initial(name)
+#undef CRYO_DESTROY
+#undef CRYO_PRESERVE
+#undef CRYO_OBJECTIVE
+
/obj/machinery/cryopod/MouseDrop_T(mob/living/target, mob/user)
if(!istype(target) || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || !ismob(target) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled)
return
@@ -358,7 +443,7 @@
var/generic_plsnoleave_message = " Please adminhelp before leaving the round, even if there are no administrators online!"
- if(target == user && world.time - target.client.cryo_warned > 5 * 600)//if we haven't warned them in the last 5 minutes
+ if(target == user && world.time - target.client.cryo_warned > 5 MINUTES)//if we haven't warned them in the last 5 minutes
var/caught = FALSE
if(target.mind.assigned_role in GLOB.command_positions)
alert("You're a Head of Staff![generic_plsnoleave_message] Be sure to put your locker items back into your locker! ")
@@ -366,13 +451,13 @@
if(iscultist(target) || is_servant_of_ratvar(target))
to_chat(target, "You're a Cultist![generic_plsnoleave_message] ")
caught = TRUE
- if(istype(SSticker.mode, /datum/antagonist/blob))
- if(target.mind in GLOB.overminds)
- alert("You're a Blob![generic_plsnoleave_message] ")
- caught = TRUE
if(is_devil(target))
alert("You're a Devil![generic_plsnoleave_message] ")
caught = TRUE
+ if(istype(SSticker.mode, /datum/antagonist/gang))
+ if(target.mind.has_antag_datum(/datum/antagonist/gang))
+ alert("You're a Gangster![generic_plsnoleave_message] ")
+ caught = TRUE
if(istype(SSticker.mode, /datum/antagonist/rev))
if(target.mind.has_antag_datum(/datum/antagonist/rev/head))
alert("You're a Head Revolutionary![generic_plsnoleave_message] ")
@@ -385,8 +470,9 @@
target.client.cryo_warned = world.time
return
- if(!Adjacent(user))
+ if(!target || user.incapacitated() || !target.Adjacent(user) || !Adjacent(user) || (!ishuman(user) && !iscyborg(user)) || !istype(user.loc, /turf) || target.buckled)
return
+ //rerun the checks in case of shenanigans
if(target == user)
visible_message("[user] starts climbing into the cryo pod.")
@@ -396,7 +482,6 @@
if(occupant)
to_chat(user, "\The [src] is in use. ")
return
-
close_machine(target)
to_chat(target, "If you ghost, log out or close your client now, your character will shortly be permanently removed from the round. ")
@@ -407,4 +492,4 @@
//Attacks/effects.
/obj/machinery/cryopod/blob_act()
- return //Sorta gamey, but we don't really want these to be destroyed.
+ return //Sorta gamey, but we don't really want these to be destroyed.
\ No newline at end of file
diff --git a/code/game/machinery/deployable.dm b/code/game/machinery/deployable.dm
index 2e78d72b96..eaf8faef12 100644
--- a/code/game/machinery/deployable.dm
+++ b/code/game/machinery/deployable.dm
@@ -74,7 +74,8 @@
to_chat(user, "You start adding [I] to [src]... ")
if(do_after(user, 50, target=src))
W.use(5)
- new /turf/closed/wall/mineral/wood/nonmetal(get_turf(src))
+ var/turf/T = get_turf(src)
+ T.PlaceOnTop(/turf/closed/wall/mineral/wood/nonmetal)
qdel(src)
return
return ..()
diff --git a/code/game/machinery/dna_scanner.dm b/code/game/machinery/dna_scanner.dm
index 7895fb8c9f..c9e1e7195b 100644
--- a/code/game/machinery/dna_scanner.dm
+++ b/code/game/machinery/dna_scanner.dm
@@ -89,11 +89,11 @@
return C
return null
-/obj/machinery/dna_scannernew/close_machine(mob/living/carbon/user)
+/obj/machinery/dna_scannernew/close_machine(atom/movable/target)
if(!state_open)
return FALSE
- ..(user)
+ ..(target)
// search for ghosts, if the corpse is empty and the scanner is connected to a cloner
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
@@ -111,7 +111,7 @@
return TRUE
/obj/machinery/dna_scannernew/open_machine()
- if(state_open)
+ if(state_open || panel_open)
return FALSE
..()
@@ -126,23 +126,48 @@
return
open_machine()
-/obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params)
-
- if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I))//sent icon_state is irrelevant...
- update_icon()//..since we're updating the icon here, since the scanner can be unpowered when opened/closed
+/obj/machinery/dna_scannernew/screwdriver_act(mob/living/user, obj/item/I)
+ . = TRUE
+ if(..())
return
+ if(occupant)
+ to_chat(user, "[src] is currently occupied! ")
+ return
+ if(state_open)
+ to_chat(user, "[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch! ")
+ return
+ if(default_deconstruction_screwdriver(user, icon_state, icon_state, I)) //sent icon_state is irrelevant...
+ update_icon() //..since we're updating the icon here, since the scanner can be unpowered when opened/closed
+ return
+ return FALSE
+/obj/machinery/dna_scannernew/wrench_act(mob/living/user, obj/item/I)
+ . = ..()
+ if(default_change_direction_wrench(user, I))
+ return TRUE
+
+/obj/machinery/dna_scannernew/crowbar_act(mob/living/user, obj/item/I)
+ . = ..()
if(default_pry_open(I))
- return
-
+ return TRUE
if(default_deconstruction_crowbar(I))
- return
+ return TRUE
- return ..()
+/obj/machinery/dna_scannernew/default_pry_open(obj/item/I) //wew
+ . = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR
+ if(.)
+ I.play_tool_sound(src, 50)
+ visible_message("[usr] pries open [src]. ", "You pry open [src]. ")
+ open_machine()
/obj/machinery/dna_scannernew/interact(mob/user)
toggle_open(user)
+/obj/machinery/dna_scannernew/AltClick(mob/user)
+ if(!user.canUseTopic(src, !issilicon(user)))
+ return
+ interact(user)
+
/obj/machinery/dna_scannernew/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
diff --git a/code/game/machinery/doors/airlock_types.dm b/code/game/machinery/doors/airlock_types.dm
index 8704a4c749..becd89063f 100644
--- a/code/game/machinery/doors/airlock_types.dm
+++ b/code/game/machinery/doors/airlock_types.dm
@@ -249,10 +249,10 @@
return 0
/obj/machinery/door/airlock/plasma/attackby(obj/item/C, mob/user, params)
- if(C.is_hot() > 300)//If the temperature of the object is over 300, then ignite
+ if(C.get_temperature() > 300)//If the temperature of the object is over 300, then ignite
message_admins("Plasma airlock ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(src)]")
log_game("Plasma airlock ignited by [key_name(user)] in [AREACOORD(src)]")
- ignite(C.is_hot())
+ ignite(C.get_temperature())
else
return ..()
@@ -499,7 +499,7 @@
SEND_SOUND(L, sound(pick('sound/hallucinations/turn_around1.ogg','sound/hallucinations/turn_around2.ogg'),0,1,50))
flash_color(L, flash_color="#960000", flash_time=20)
L.Knockdown(40)
- L.throw_at(throwtarget, 5, 1,src)
+ L.throw_at(throwtarget, 5, 1)
return 0
/obj/machinery/door/airlock/cult/proc/conceal()
diff --git a/code/game/machinery/doors/door.dm b/code/game/machinery/doors/door.dm
index a2da7de29a..3ac386e1fb 100644
--- a/code/game/machinery/doors/door.dm
+++ b/code/game/machinery/doors/door.dm
@@ -326,7 +326,7 @@
else //for simple_animals & borgs
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE)
var/turf/location = get_turf(src)
- //add_blood doesn't work for borgs/xenos, but add_blood_floor does.
+ //add_blood_DNA doesn't work for borgs/xenos, but add_blood_floor does.
if(iscarbon(L))
var/mob/living/carbon/C = L
C.bleed(DOOR_CRUSH_DAMAGE)
diff --git a/code/game/machinery/droneDispenser.dm b/code/game/machinery/droneDispenser.dm
index 7c92c158b3..b121057315 100644
--- a/code/game/machinery/droneDispenser.dm
+++ b/code/game/machinery/droneDispenser.dm
@@ -146,7 +146,7 @@
if((stat & (NOPOWER|BROKEN)) || !anchored)
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(!materials.has_materials(using_materials))
return // We require more minerals
@@ -211,7 +211,7 @@
/obj/machinery/droneDispenser/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/crowbar))
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
I.play_tool_sound(src)
to_chat(user, "You retrieve the materials from [src]. ")
diff --git a/code/game/machinery/exp_cloner.dm b/code/game/machinery/exp_cloner.dm
index e8364d2271..25e5948b51 100644
--- a/code/game/machinery/exp_cloner.dm
+++ b/code/game/machinery/exp_cloner.dm
@@ -42,17 +42,18 @@
icon_state = "pod_1"
//Get the clone body ready
maim_clone(H)
- ADD_TRAIT(H, TRAIT_STABLEHEART, "cloning")
- ADD_TRAIT(H, TRAIT_EMOTEMUTE, "cloning")
- ADD_TRAIT(H, TRAIT_MUTE, "cloning")
- ADD_TRAIT(H, TRAIT_NOBREATH, "cloning")
- ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, "cloning")
+ ADD_TRAIT(H, TRAIT_STABLEHEART, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_STABLELIVER, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_EMOTEMUTE, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_MUTE, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_NOBREATH, CLONING_POD_TRAIT)
+ ADD_TRAIT(H, TRAIT_NOCRITDAMAGE, CLONING_POD_TRAIT)
H.Unconscious(80)
- var/list/candidates = pollCandidatesForMob("Do you want to play as [clonename]'s defective clone?", null, null, null, 100, H)
+ var/list/candidates = pollCandidatesForMob("Do you want and agree to play as a [clonename]'s defective clone, respect their character and not engage in ERP without permission from the original?", null, null, null, 100, H, POLL_IGNORE_CLONE)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
- H.key = C.key
+ C.transfer_ckey(H)
if(grab_ghost_when == CLONER_FRESH_CLONE)
H.grab_ghost()
diff --git a/code/game/machinery/gulag_teleporter.dm b/code/game/machinery/gulag_teleporter.dm
index 47136e8c27..a2d0460d25 100644
--- a/code/game/machinery/gulag_teleporter.dm
+++ b/code/game/machinery/gulag_teleporter.dm
@@ -135,17 +135,19 @@ The console is located at computer/gulag_teleporter.dm
if(linked_reclaimer)
linked_reclaimer.stored_items[occupant] = list()
var/mob/living/mob_occupant = occupant
- for(var/obj/item/W in mob_occupant)
- if(!is_type_in_typecache(W, telegulag_required_items) && mob_occupant.temporarilyRemoveItemFromInventory(W))
- if(istype(W, /obj/item/restraints/handcuffs))
- W.forceMove(get_turf(src))
- continue
- if(linked_reclaimer)
- linked_reclaimer.stored_items[mob_occupant] += W
- linked_reclaimer.contents += W
- W.forceMove(linked_reclaimer)
- else
- W.forceMove(src)
+ for(var/A in mob_occupant.get_equipped_items(TRUE))
+ var/obj/item/I = A
+ if(is_type_in_typecache(I, telegulag_required_items) || !mob_occupant.temporarilyRemoveItemFromInventory(I))
+ continue
+ if(istype(I, /obj/item/restraints/handcuffs))
+ I.forceMove(get_turf(src))
+ continue
+ if(linked_reclaimer)
+ linked_reclaimer.stored_items[mob_occupant] += I
+ linked_reclaimer.contents += I
+ I.forceMove(linked_reclaimer)
+ else
+ I.forceMove(src)
/obj/machinery/gulag_teleporter/proc/handle_prisoner(obj/item/id, datum/data/record/R)
if(!ishuman(occupant))
diff --git a/code/game/machinery/harvester.dm b/code/game/machinery/harvester.dm
index 1fccadda21..db015eb7c1 100644
--- a/code/game/machinery/harvester.dm
+++ b/code/game/machinery/harvester.dm
@@ -138,7 +138,7 @@
to_chat(user, "[src] is currently occupied! ")
return
if(state_open)
- to_chat(user, "[src] must be closed to [panel_open ? "close" : "open"] it's maintenance hatch! ")
+ to_chat(user, "[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch! ")
return
if(default_deconstruction_screwdriver(user, "[initial(icon_state)]-o", initial(icon_state), I))
return
diff --git a/code/game/machinery/hologram.dm b/code/game/machinery/hologram.dm
index 893f36acb3..79aef8ba7b 100644
--- a/code/game/machinery/hologram.dm
+++ b/code/game/machinery/hologram.dm
@@ -24,6 +24,8 @@ Possible to do for anyone motivated enough:
* Holopad
*/
+GLOBAL_LIST_EMPTY(network_holopads)
+
#define HOLOPAD_PASSIVE_POWER_USAGE 1
#define HOLOGRAM_POWER_USAGE 2
@@ -55,7 +57,6 @@ Possible to do for anyone motivated enough:
var/record_user //user that inititiated the recording
var/obj/effect/overlay/holo_pad_hologram/replay_holo //replay hologram
var/static/force_answer_call = FALSE //Calls will be automatically answered after a couple rings, here for debugging
- var/static/list/holopads = list()
var/obj/effect/overlay/holoray/ray
var/ringing = FALSE
var/offset = FALSE
@@ -96,7 +97,7 @@ Possible to do for anyone motivated enough:
/obj/machinery/holopad/Initialize()
. = ..()
if(on_network)
- holopads += src
+ GLOB.network_holopads += src
/obj/machinery/holopad/Destroy()
if(outgoing_call)
@@ -116,7 +117,7 @@ Possible to do for anyone motivated enough:
QDEL_NULL(disk)
- holopads -= src
+ GLOB.network_holopads -= src
return ..()
/obj/machinery/holopad/power_change()
@@ -260,7 +261,7 @@ Possible to do for anyone motivated enough:
temp += "Main Menu "
if(usr.loc == loc)
var/list/callnames = list()
- for(var/I in holopads)
+ for(var/I in GLOB.network_holopads)
var/area/A = get_area(I)
if(A)
LAZYADD(callnames[A], I)
@@ -474,7 +475,7 @@ For the other part of the code, check silicon say.dm. Particularly robot talk.*/
var/obj/effect/overlay/holo_pad_hologram/h = masters[holo_owner]
if(!h || h.HC) //Holocalls can't change source.
return FALSE
- for(var/pad in holopads)
+ for(var/pad in GLOB.network_holopads)
var/obj/machinery/holopad/another = pad
if(another == src)
continue
diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm
index b217c14e53..621ca266bb 100644
--- a/code/game/machinery/iv_drip.dm
+++ b/code/game/machinery/iv_drip.dm
@@ -8,14 +8,14 @@
icon_state = "iv_drip"
anchored = FALSE
mouse_drag_pointer = MOUSE_ACTIVE_POINTER
- var/mob/living/carbon/attached = null
+ var/mob/living/carbon/attached
var/mode = IV_INJECTING
- var/obj/item/reagent_containers/beaker = null
+ var/obj/item/reagent_containers/beaker
var/static/list/drip_containers = typecacheof(list(/obj/item/reagent_containers/blood,
/obj/item/reagent_containers/food,
/obj/item/reagent_containers/glass))
-/obj/machinery/iv_drip/Initialize()
+/obj/machinery/iv_drip/Initialize(mapload)
. = ..()
update_icon()
@@ -84,6 +84,8 @@
if(Adjacent(target) && usr.Adjacent(target))
if(beaker)
usr.visible_message("[usr] attaches [src] to [target]. ", "You attach [src] to [target]. ")
+ log_combat(usr, target, "attached", src, "containing: [beaker.name] - ([beaker.reagents.log_list()])")
+ add_fingerprint(usr)
attached = target
START_PROCESSING(SSmachines, src)
update_icon()
@@ -100,6 +102,8 @@
return
beaker = W
to_chat(user, "You attach [W] to [src]. ")
+ user.log_message("attached a [W] to [src] at [AREACOORD(src)] containing ([beaker.reagents.log_list()])", LOG_ATTACK)
+ add_fingerprint(user)
update_icon()
return
else
@@ -142,10 +146,11 @@
if(!amount)
if(prob(5))
visible_message("[src] pings.")
+ playsound(loc, 'sound/machines/beep.ogg', 50, 1)
return
// If the human is losing too much blood, beep.
- if(attached.blood_volume < ( (BLOOD_VOLUME_SAFE*attached.blood_ratio) && prob(5) ) )
+ if(attached.blood_volume < ((BLOOD_VOLUME_SAFE*attached.blood_ratio) && prob(5) && ishuman(attached))) //really couldn't care less about monkeys
visible_message("[src] beeps loudly.")
playsound(loc, 'sound/machines/twobeep.ogg', 50, 1)
attached.transfer_blood_to(beaker, amount)
@@ -178,9 +183,10 @@
if(usr.incapacitated())
return
-
if(beaker)
- beaker.forceMove(drop_location())
+ if(usr && Adjacent(usr) && !issiliconoradminghost(usr))
+ if(!usr.put_in_hands(beaker))
+ beaker.forceMove(drop_location())
beaker = null
update_icon()
@@ -195,27 +201,27 @@
if(usr.incapacitated())
return
-
mode = !mode
to_chat(usr, "The IV drip is now [mode ? "injecting" : "taking blood"].")
update_icon()
/obj/machinery/iv_drip/examine(mob/user)
- ..()
+ . = ..()
if(get_dist(user, src) > 2)
return
- to_chat(user, "The IV drip is [mode ? "injecting" : "taking blood"].")
+ . += "[src] is [mode ? "injecting" : "taking blood"].\n"
if(beaker)
if(beaker.reagents && beaker.reagents.reagent_list.len)
- to_chat(user, "Attached is \a [beaker] with [beaker.reagents.total_volume] units of liquid. ")
+ . += "\tAttached is \a [beaker] with [beaker.reagents.total_volume] units of liquid. \n"
else
- to_chat(user, "Attached is an empty [beaker.name]. ")
+ . += "\tAttached is an empty [beaker.name]. \n"
else
- to_chat(user, "No chemicals are attached. ")
+ . += "\tNo chemicals are attached. \n"
- to_chat(user, "[attached ? attached : "No one"] is attached. ")
+ . += "\t[attached ? attached : "No one"] is attached. "
+ to_chat(user,.)
#undef IV_TAKING
-#undef IV_INJECTING
+#undef IV_INJECTING
\ No newline at end of file
diff --git a/code/game/machinery/porta_turret/portable_turret.dm b/code/game/machinery/porta_turret/portable_turret.dm
index b0a75c99dc..7aaab0d8ea 100644
--- a/code/game/machinery/porta_turret/portable_turret.dm
+++ b/code/game/machinery/porta_turret/portable_turret.dm
@@ -40,6 +40,8 @@
var/stun_projectile = null //stun mode projectile type
var/stun_projectile_sound
+ var/nonlethal_projectile //projectile to use in stun mode when the target is resting, if any
+ var/nonlethal_projectile_sound
var/lethal_projectile = null //lethal mode projectile type
var/lethal_projectile_sound
@@ -535,13 +537,22 @@
T = closer
break
+ var/mob/living/carbon/C
+ if(iscarbon(target))
+ C = target
+
update_icon()
var/obj/item/projectile/A
//any emagged turrets drains 2x power and uses a different projectile?
if(mode == TURRET_STUN)
- use_power(reqpower)
- A = new stun_projectile(T)
- playsound(loc, stun_projectile_sound, 75, 1)
+ if(nonlethal_projectile && C && C.resting)
+ use_power(reqpower*0.5)
+ A = new nonlethal_projectile(T)
+ playsound(loc, nonlethal_projectile_sound, 75, 1)
+ else
+ use_power(reqpower)
+ A = new stun_projectile(T)
+ playsound(loc, stun_projectile_sound, 75, 1)
else
use_power(reqpower * 2)
A = new lethal_projectile(T)
@@ -551,6 +562,7 @@
//Shooting Code:
A.preparePixelProjectile(target, T)
A.firer = src
+ A.fired_from = src
A.fire()
return A
@@ -653,6 +665,8 @@
base_icon_state = "standard"
stun_projectile = /obj/item/projectile/energy/electrode
stun_projectile_sound = 'sound/weapons/taser.ogg'
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
lethal_projectile = /obj/item/projectile/beam/laser
lethal_projectile_sound = 'sound/weapons/laser.ogg'
desc = "An energy blaster auto-turret."
@@ -662,6 +676,8 @@
base_icon_state = "standard"
stun_projectile = /obj/item/projectile/energy/electrode
stun_projectile_sound = 'sound/weapons/taser.ogg'
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
desc = "An energy blaster auto-turret."
@@ -681,6 +697,8 @@
/obj/machinery/porta_turret/ai
faction = list("silicon")
+ nonlethal_projectile = /obj/item/projectile/beam/disabler
+ nonlethal_projectile_sound = 'sound/weapons/taser2.ogg'
/obj/machinery/porta_turret/ai/assess_perp(mob/living/carbon/human/perp)
return 10 //AI turrets shoot at everything not in their faction
diff --git a/code/game/machinery/recycler.dm b/code/game/machinery/recycler.dm
index 9d431487e0..1a8bc7ece4 100644
--- a/code/game/machinery/recycler.dm
+++ b/code/game/machinery/recycler.dm
@@ -32,10 +32,10 @@
mat_mod *= 50000
for(var/obj/item/stock_parts/manipulator/M in component_parts)
amt_made = 12.5 * M.rating //% of materials salvaged
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = mat_mod
amount_produced = min(50, amt_made) + 50
- GET_COMPONENT(butchering, /datum/component/butchering)
+ var/datum/component/butchering/butchering = GetComponent(/datum/component/butchering)
butchering.effectiveness = amount_produced
butchering.bonus_modifier = amount_produced/5
@@ -99,7 +99,7 @@
/obj/machinery/recycler/proc/eat(atom/AM0, sound=TRUE)
var/list/to_eat
if(isitem(AM0))
- to_eat = AM0.GetAllContents()
+ to_eat = AM0.GetAllContentsIgnoring(GLOB.typecache_mob)
else
to_eat = list(AM0)
@@ -144,7 +144,7 @@
qdel(L)
return
else
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/material_amount = materials.get_item_material_amount(I)
if(!material_amount)
qdel(I)
@@ -195,7 +195,7 @@
L.Unconscious(100)
L.adjustBruteLoss(crush_damage)
if(L.stat == DEAD && (L.butcher_results || L.guaranteed_butcher_results))
- GET_COMPONENT(butchering, /datum/component/butchering)
+ var/datum/component/butchering/butchering = GetComponent(/datum/component/butchering)
butchering.Butcher(src,L)
/obj/machinery/recycler/deathtrap
diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm
index 90166dacf0..f35caf514c 100644
--- a/code/game/machinery/suit_storage_unit.dm
+++ b/code/game/machinery/suit_storage_unit.dm
@@ -210,13 +210,13 @@
add_fingerprint(user)
/obj/machinery/suit_storage_unit/proc/cook()
+ var/mob/living/mob_occupant = occupant
if(uv_cycles)
uv_cycles--
uv = TRUE
locked = TRUE
update_icon()
if(occupant)
- var/mob/living/mob_occupant = occupant
if(uv_super)
mob_occupant.adjustFireLoss(rand(20, 36))
else
@@ -245,10 +245,29 @@
visible_message("[src]'s door slides open. The glowing yellow lights dim to a gentle green. ")
else
visible_message("[src]'s door slides open, barraging you with the nauseating smell of charred flesh. ")
+ mob_occupant.radiation = 0
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
- for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
- var/datum/component/radioactive/contamination = I.GetComponent(/datum/component/radioactive)
+ var/list/things_to_clear = list() //Done this way since using GetAllContents on the SSU itself would include circuitry and such.
+ if(suit)
+ things_to_clear += suit
+ things_to_clear += suit.GetAllContents()
+ if(helmet)
+ things_to_clear += helmet
+ things_to_clear += helmet.GetAllContents()
+ if(mask)
+ things_to_clear += mask
+ things_to_clear += mask.GetAllContents()
+ if(storage)
+ things_to_clear += storage
+ things_to_clear += storage.GetAllContents()
+ if(occupant)
+ things_to_clear += occupant
+ things_to_clear += occupant.GetAllContents()
+ for(var/atom/movable/AM in things_to_clear) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
+ SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
+ AM.clean_blood()
+ AM.fingerprints = list()
+ var/datum/component/radioactive/contamination = AM.GetComponent(/datum/component/radioactive)
if(contamination)
qdel(contamination)
open_machine(FALSE)
@@ -418,4 +437,4 @@
if(I)
I.forceMove(loc)
. = TRUE
- update_icon()
+ update_icon()
\ No newline at end of file
diff --git a/code/game/machinery/syndicatebeacon.dm b/code/game/machinery/syndicatebeacon.dm
index a1ed7fb848..8a33241d46 100644
--- a/code/game/machinery/syndicatebeacon.dm
+++ b/code/game/machinery/syndicatebeacon.dm
@@ -1,3 +1,7 @@
+GLOBAL_VAR_INIT(singularity_counter, 0)
+
+#define METEOR_DISASTER_MODIFIER 0.5
+
////////////////////////////////////////
//Singularity beacon
////////////////////////////////////////
@@ -13,39 +17,57 @@
stat = 0
verb_say = "states"
var/cooldown = 0
-
- var/active = 0
+ var/active = FALSE
+ var/meteor_buff = FALSE
var/icontype = "beacon"
-
/obj/machinery/power/singularity_beacon/proc/Activate(mob/user = null)
+ if(active)
+ return FALSE
if(surplus() < 1500)
if(user)
to_chat(user, "The connected wire doesn't have enough current. ")
- return
+ return FALSE
+ if(is_station_level(z))
+ increment_meteor_waves()
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.z == z)
singulo.target = src
icon_state = "[icontype]1"
- active = 1
+ active = TRUE
if(user)
to_chat(user, "You activate the beacon. ")
+ return TRUE
-
-/obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user = null)
+/obj/machinery/power/singularity_beacon/proc/Deactivate(mob/user)
+ if(!active)
+ return FALSE
for(var/obj/singularity/singulo in GLOB.singularities)
if(singulo.target == src)
singulo.target = null
icon_state = "[icontype]0"
- active = 0
+ active = FALSE
if(user)
to_chat(user, "You deactivate the beacon. ")
+ if(meteor_buff)
+ decrement_meteor_waves()
+ return TRUE
+/obj/machinery/power/singularity_beacon/proc/increment_meteor_waves()
+ meteor_buff = TRUE
+ GLOB.singularity_counter++
+ for(var/datum/round_event_control/meteor_wave/W in SSevents.control)
+ W.weight += round(initial(W.weight) * METEOR_DISASTER_MODIFIER)
+
+/obj/machinery/power/singularity_beacon/proc/decrement_meteor_waves()
+ meteor_buff = FALSE
+ GLOB.singularity_counter--
+ for(var/datum/round_event_control/meteor_wave/W in SSevents.control)
+ W.weight -= round(initial(W.weight) * METEOR_DISASTER_MODIFIER)
/obj/machinery/power/singularity_beacon/attack_ai(mob/user)
return
-
/obj/machinery/power/singularity_beacon/attack_hand(mob/user)
. = ..()
if(.)
@@ -86,6 +108,12 @@
if(!active)
return
+ var/is_on_station = is_station_level(z)
+ if(meteor_buff && !is_on_station)
+ decrement_meteor_waves()
+ else if(!meteor_buff && is_on_station)
+ increment_meteor_waves()
+
if(surplus() >= 1500)
add_load(1500)
if(cooldown <= world.time)
@@ -133,3 +161,5 @@
/obj/item/sbeacondrop/clownbomb
desc = "A label on it reads: Warning: Activating this device will send a silly explosive to your location ."
droptype = /obj/machinery/syndicatebomb/badmin/clown
+
+#undef METEOR_DISASTER_MODIFIER
diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm
index 1f1f13ee22..ae71a0b844 100644
--- a/code/game/machinery/teleporter.dm
+++ b/code/game/machinery/teleporter.dm
@@ -209,5 +209,7 @@
icon_state = "controller-o"
else if(stat & (BROKEN|NOPOWER))
icon_state = "controller-p"
+ else if(teleporter_console && teleporter_console.calibrating)
+ icon_state = "controller-c"
else
icon_state = "controller"
diff --git a/code/game/machinery/turnstile.dm b/code/game/machinery/turnstile.dm
new file mode 100644
index 0000000000..1fd78056d4
--- /dev/null
+++ b/code/game/machinery/turnstile.dm
@@ -0,0 +1,84 @@
+/obj/machinery/turnstile
+ name = "turnstile"
+ desc = "A mechanical door that permits one-way access and prevents tailgating."
+ icon = 'icons/obj/turnstile.dmi'
+ icon_state = "turnstile_map"
+ density = FALSE
+ armor = list(melee = 50, bullet = 50, laser = 50, energy = 50, bomb = 10, bio = 100, rad = 100, fire = 90, acid = 70)
+ anchored = TRUE
+ use_power = FALSE
+ idle_power_usage = 2
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ layer = OPEN_DOOR_LAYER
+
+/obj/machinery/turnstile/Initialize()
+ . = ..()
+ icon_state = "turnstile"
+
+/obj/machinery/turnstile/CanAtmosPass(turf/T)
+ return TRUE
+
+/obj/machinery/turnstile/bullet_act(obj/item/projectile/P, def_zone)
+ return -1 //Pass through!
+
+/obj/machinery/turnstile/proc/allowed_access(var/mob/B)
+ if(B.pulledby && ismob(B.pulledby))
+ return allowed(B.pulledby) | allowed(B)
+ else
+ return allowed(B)
+
+/obj/machinery/turnstile/CanPass(atom/movable/AM, turf/T)
+ if(ismob(AM))
+ var/mob/B = AM
+ if(isliving(AM))
+ var/mob/living/M = AM
+
+ if(world.time - M.last_bumped <= 5)
+ return FALSE
+ M.last_bumped = world.time
+
+ var/allowed_access = FALSE
+ var/turf/behind = get_step(src, dir)
+
+ if(B in behind.contents)
+ allowed_access = allowed_access(B)
+ else
+ to_chat(usr, "\the [src] resists your efforts. ")
+ return FALSE
+
+ if(allowed_access)
+ flick("operate", src)
+ playsound(src,'sound/items/ratchet.ogg',50,0,3)
+ return TRUE
+ else
+ flick("deny", src)
+ playsound(src,'sound/machines/deniedbeep.ogg',50,0,3)
+ return FALSE
+ if(ispath(AM, /obj/item/))
+ return TRUE
+ else
+ return FALSE
+
+/obj/machinery/turnstile/CheckExit(atom/movable/AM as mob|obj, target)
+ if(isliving(AM))
+ var/mob/living/M = AM
+ var/outdir = dir
+ if(allowed_access(M))
+ switch(dir)
+ if(NORTH)
+ outdir = SOUTH
+ if(SOUTH)
+ outdir = NORTH
+ if(EAST)
+ outdir = WEST
+ if(WEST)
+ outdir = EAST
+ var/turf/outturf = get_step(src, outdir)
+ var/canexit = (target == src.loc) | (target == outturf)
+
+ if(!canexit && world.time - M.last_bumped <= 5)
+ to_chat(usr, "\the [src] resists your efforts. ")
+ M.last_bumped = world.time
+ return canexit
+ else
+ return TRUE
\ No newline at end of file
diff --git a/code/game/machinery/washing_machine.dm b/code/game/machinery/washing_machine.dm
index 5e8515d3d5..8be079656b 100644
--- a/code/game/machinery/washing_machine.dm
+++ b/code/game/machinery/washing_machine.dm
@@ -11,10 +11,6 @@
var/obj/item/color_source
var/max_wash_capacity = 5
-/obj/machinery/washing_machine/ComponentInitialize()
- . = ..()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
-
/obj/machinery/washing_machine/examine(mob/user)
..()
to_chat(user, "Alt-click it to start a wash cycle. ")
@@ -59,7 +55,8 @@
M.Translate(rand(-3, 3), rand(-1, 3))
animate(src, transform=M, time=2)
-/obj/machinery/washing_machine/proc/clean_blood()
+/obj/machinery/washing_machine/clean_blood()
+ ..()
if(!busy)
bloody_mess = FALSE
update_icon()
@@ -67,7 +64,8 @@
/obj/machinery/washing_machine/proc/wash_cycle()
for(var/X in contents)
var/atom/movable/AM = X
- SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ AM.clean_blood()
AM.machine_wash(src)
busy = FALSE
diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm
index ea51693135..431d4c30b3 100644
--- a/code/game/mecha/combat/combat.dm
+++ b/code/game/mecha/combat/combat.dm
@@ -3,3 +3,9 @@
internal_damage_threshold = 50
armor = list("melee" = 30, "bullet" = 30, "laser" = 15, "energy" = 20, "bomb" = 20, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 100)
mouse_pointer = 'icons/mecha/mecha_mouse.dmi'
+ var/spawn_tracked = TRUE
+
+/obj/mecha/combat/Initialize()
+ . = ..()
+ if(spawn_tracked)
+ trackers += new /obj/item/mecha_parts/mecha_tracking(src)
\ No newline at end of file
diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm
index cd7051d074..caaa3e3a00 100644
--- a/code/game/mecha/combat/durand.dm
+++ b/code/game/mecha/combat/durand.dm
@@ -19,7 +19,3 @@
/obj/mecha/combat/durand/RemoveActions(mob/living/user, human_occupant = 0)
..()
defense_action.Remove(user)
-
-/obj/mecha/combat/Initialize()
- . = ..()
- trackers += new /obj/item/mecha_parts/mecha_tracking(src)
diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm
index 564f308df3..c7c180af41 100644
--- a/code/game/mecha/combat/gygax.dm
+++ b/code/game/mecha/combat/gygax.dm
@@ -29,6 +29,7 @@
operation_req_access = list(ACCESS_SYNDICATE)
wreckage = /obj/structure/mecha_wreckage/gygax/dark
max_equip = 4
+ spawn_tracked = FALSE
/obj/mecha/combat/gygax/dark/loaded/Initialize()
. = ..()
@@ -48,7 +49,6 @@
return
cell = new /obj/item/stock_parts/cell/hyper(src)
-
/obj/mecha/combat/gygax/GrantActions(mob/living/user, human_occupant = 0)
..()
overload_action.Grant(user, src)
@@ -65,7 +65,3 @@
/obj/mecha/combat/gygax/dark/RemoveActions(mob/living/user, human_occupant = 0)
..()
thrusters_action.Remove(user)
-
-/obj/mecha/combat/Initialize()
- . = ..()
- trackers += new /obj/item/mecha_parts/mecha_tracking(src)
diff --git a/code/game/mecha/combat/honker.dm b/code/game/mecha/combat/honker.dm
index 4c32e9c367..ed29809f91 100644
--- a/code/game/mecha/combat/honker.dm
+++ b/code/game/mecha/combat/honker.dm
@@ -152,8 +152,4 @@
var/color=""
for (var/i=0;i<6;i++)
color = color+pick(colors)
- return color
-
-/obj/mecha/combat/Initialize()
- . = ..()
- trackers += new /obj/item/mecha_parts/mecha_tracking(src)
+ return color
\ No newline at end of file
diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm
index 21f8259e69..42817b586c 100644
--- a/code/game/mecha/combat/marauder.dm
+++ b/code/game/mecha/combat/marauder.dm
@@ -16,6 +16,7 @@
force = 45
max_equip = 4
bumpsmash = 1
+ spawn_tracked = FALSE
/obj/mecha/combat/marauder/GrantActions(mob/living/user, human_occupant = 0)
..()
diff --git a/code/game/mecha/combat/neovgre.dm b/code/game/mecha/combat/neovgre.dm
new file mode 100644
index 0000000000..b1f2cdd02a
--- /dev/null
+++ b/code/game/mecha/combat/neovgre.dm
@@ -0,0 +1,97 @@
+/obj/mecha/combat/neovgre
+ name = "Neovgre, the Anima Bulwark"
+ desc = "Nezbere's most powerful creation, a mighty war machine of unmatched power said to have ended wars in a single night."
+ icon = 'icons/mecha/neovgre.dmi'
+ icon_state = "neovgre"
+ max_integrity = 500 //This is THE ratvarian superweaon, its deployment is an investment
+ armor = list("melee" = 50, "bullet" = 40, "laser" = 25, "energy" = 25, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 100) //Its similar to the clockwork armour albeit with a few buffs becuase RATVARIAN SUPERWEAPON!!
+ force = 50 //SMASHY SMASHY!!
+ internal_damage_threshold = 0
+ step_in = 3
+ pixel_x = -16
+ layer = ABOVE_MOB_LAYER
+ breach_time = 100 //ten seconds till all goes to shit
+ recharge_rate = 100
+ wreckage = /obj/structure/mecha_wreckage/durand/neovgre
+ spawn_tracked = FALSE
+
+/obj/mecha/combat/neovgre/GrantActions(mob/living/user, human_occupant = 0) //No Eject action for you sonny jim, your life for Ratvar!
+ internals_action.Grant(user, src)
+ cycle_action.Grant(user, src)
+ lights_action.Grant(user, src)
+ stats_action.Grant(user, src)
+ strafing_action.Grant(user, src)
+
+/obj/mecha/combat/neovgre/RemoveActions(mob/living/user, human_occupant = 0)
+ internals_action.Remove(user)
+ cycle_action.Remove(user)
+ lights_action.Remove(user)
+ stats_action.Remove(user)
+ strafing_action.Remove(user)
+
+/obj/mecha/combat/neovgre/MouseDrop_T(mob/M, mob/user)
+ if(!is_servant_of_ratvar(user))
+ to_chat(user, "BEGONE HERETIC! ")
+ return
+ else
+ ..()
+
+/obj/mecha/combat/neovgre/moved_inside(mob/living/carbon/human/H)
+ var/list/Itemlist = H.get_contents()
+ for(var/obj/item/clockwork/slab/W in Itemlist)
+ to_chat(H, "You safely store [W] inside [src]. ")
+ qdel(W)
+ . = ..()
+
+/obj/mecha/combat/neovgre/obj_destruction()
+ for(var/mob/M in src)
+ to_chat(M, "You are consumed by the fires raging within Neovgre... ")
+ M.dust()
+ playsound(src, 'sound/magic/lightning_chargeup.ogg', 100, 0)
+ src.visible_message("The reactor has gone critical, its going to blow! ")
+ addtimer(CALLBACK(src,.proc/go_critical),breach_time)
+
+/obj/mecha/combat/neovgre/proc/go_critical()
+ explosion(get_turf(loc), 3, 5, 10, 20, 30)
+ Destroy(src)
+
+/obj/mecha/combat/neovgre/container_resist(mob/living/user)
+ to_chat(user, "Neovgre requires a lifetime commitment friend, no backing out now! ")
+ return
+
+/obj/mecha/combat/neovgre/process()
+ ..()
+ if(GLOB.ratvar_awakens) // At this point only timley intervention by lord singulo could hople to stop the superweapon
+ cell.charge = INFINITY
+ max_integrity = INFINITY
+ obj_integrity = max_integrity
+ CHECK_TICK //Just to be on the safe side lag wise
+ else if(cell.charge < cell.maxcharge)
+ for(var/obj/effect/clockwork/sigil/transmission/T in range(SIGIL_ACCESS_RANGE, src))
+ var/delta = min(recharge_rate, cell.maxcharge - cell.charge)
+ if (get_clockwork_power() <= delta)
+ cell.charge += delta
+ adjust_clockwork_power(-delta)
+ CHECK_TICK
+
+/obj/mecha/combat/neovgre/Initialize()
+ .=..()
+ GLOB.neovgre_exists ++
+ var/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/N = new
+ N.attach(src)
+
+/obj/structure/mecha_wreckage/durand/neovgre
+ name = "\improper Neovgre wreckage?"
+ desc = "On closer inspection this looks like the wreck of a durand with some spraypainted cardboard duct taped to it!"
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre
+ equip_cooldown = 8 //Rapid fire heavy laser cannon, simple yet elegant
+ energy_drain = 30
+ name = "Aribter Laser Cannon"
+ desc = "Please re-attach this to neovgre and stop asking questions about why it looks like a normal Nanotrasen issue Solaris laser cannon - Nezbere"
+ fire_sound = "sound/weapons/neovgre_laser.ogg"
+
+/obj/item/mecha_parts/mecha_equipment/weapon/energy/laser/heavy/neovgre/can_attach(obj/mecha/combat/neovgre/M)
+ if(istype(M))
+ return 1
+ return 0
diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm
index 1264a647c4..15b865c1e9 100644
--- a/code/game/mecha/combat/phazon.dm
+++ b/code/game/mecha/combat/phazon.dm
@@ -27,7 +27,3 @@
..()
switch_damtype_action.Remove(user)
phasing_action.Remove(user)
-
-/obj/mecha/combat/Initialize()
- . = ..()
- trackers += new /obj/item/mecha_parts/mecha_tracking(src)
diff --git a/code/game/mecha/combat/reticence.dm b/code/game/mecha/combat/reticence.dm
index 4cd8c01517..7e8c865517 100644
--- a/code/game/mecha/combat/reticence.dm
+++ b/code/game/mecha/combat/reticence.dm
@@ -18,6 +18,7 @@
stepsound = null
turnsound = null
opacity = 0
+ spawn_tracked = FALSE
/obj/mecha/combat/reticence/loaded/Initialize()
. = ..()
diff --git a/code/game/mecha/equipment/tools/medical_tools.dm b/code/game/mecha/equipment/tools/medical_tools.dm
index 21bbdfd14b..ae3fdb15b4 100644
--- a/code/game/mecha/equipment/tools/medical_tools.dm
+++ b/code/game/mecha/equipment/tools/medical_tools.dm
@@ -166,7 +166,7 @@
Toxin Content: [patient.getToxLoss()]%
Burn Severity: [patient.getFireLoss()]%
[patient.getCloneLoss() ? "Subject appears to have cellular damage." : ""]
- [patient.getBrainLoss() ? "Significant brain damage detected." : ""]
+ [patient.getOrganLoss(ORGAN_SLOT_BRAIN) ? "Significant brain damage detected." : ""]
[length(patient.get_traumas()) ? "Brain Traumas detected." : ""]
"}
diff --git a/code/game/mecha/equipment/tools/mining_tools.dm b/code/game/mecha/equipment/tools/mining_tools.dm
index d539e0a9d5..4044951c42 100644
--- a/code/game/mecha/equipment/tools/mining_tools.dm
+++ b/code/game/mecha/equipment/tools/mining_tools.dm
@@ -13,6 +13,8 @@
energy_drain = 10
force = 15
harmful = TRUE
+ tool_behaviour = TOOL_DRILL
+ toolspeed = 0.9
var/drill_delay = 7
var/drill_level = DRILL_BASIC
@@ -98,12 +100,12 @@
/obj/item/mecha_parts/mecha_equipment/drill/attach(obj/mecha/M)
..()
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = TRUE
/obj/item/mecha_parts/mecha_equipment/drill/detach(atom/moveto)
..()
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = FALSE
/obj/item/mecha_parts/mecha_equipment/drill/proc/drill_mob(mob/living/target, mob/user)
@@ -113,7 +115,7 @@
if(target.stat == DEAD && target.getBruteLoss() >= 200)
log_combat(user, target, "gibbed", name)
if(LAZYLEN(target.butcher_results) || LAZYLEN(target.guaranteed_butcher_results))
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.Butcher(chassis, target)
else
target.gib()
@@ -141,6 +143,7 @@
drill_delay = 4
drill_level = DRILL_HARDENED
force = 15
+ toolspeed = 0.7
/obj/item/mecha_parts/mecha_equipment/mining_scanner
diff --git a/code/game/mecha/equipment/tools/work_tools.dm b/code/game/mecha/equipment/tools/work_tools.dm
index ea9465184a..36708fcf90 100644
--- a/code/game/mecha/equipment/tools/work_tools.dm
+++ b/code/game/mecha/equipment/tools/work_tools.dm
@@ -11,6 +11,8 @@
var/dam_force = 20
var/obj/mecha/working/ripley/cargo_holder
harmful = TRUE
+ tool_behaviour = TOOL_RETRACTOR
+ toolspeed = 0.8
/obj/item/mecha_parts/mecha_equipment/hydraulic_clamp/can_attach(obj/mecha/working/ripley/M as obj)
if(..())
diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm
index 2e5a13beb2..9f8f3ef742 100644
--- a/code/game/mecha/equipment/weapons/weapons.dm
+++ b/code/game/mecha/equipment/weapons/weapons.dm
@@ -279,12 +279,12 @@
name = "\improper Melon Seed \"Scattershot\""
desc = "A weapon for combat exosuits. Shoots a spread of pellets, shaped as seed."
icon_state = "mecha_scatter"
- equip_cooldown = 30
+ equip_cooldown = 20
projectile = /obj/item/projectile/bullet/seed
- projectiles = 4
- projectile_energy_cost = 55
+ projectiles = 20
+ projectile_energy_cost = 25
projectiles_per_shot = 10
- variance = 20
+ variance = 25
harmful = TRUE
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/lmg
diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm
index e1dc80911f..4acf7981bc 100644
--- a/code/game/mecha/mech_fabricator.dm
+++ b/code/game/mecha/mech_fabricator.dm
@@ -47,7 +47,7 @@
//maximum stocking amount (default 300000, 600000 at T4)
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
T += M.rating
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = (200000 + (T*50000))
//resources adjustment coefficient (1 -> 0.85 -> 0.7 -> 0.55)
@@ -109,7 +109,7 @@
/obj/machinery/mecha_part_fabricator/proc/output_available_resources()
var/output
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
output += "[M.name]: [M.amount] cm³"
@@ -130,7 +130,7 @@
/obj/machinery/mecha_part_fabricator/proc/check_resources(datum/design/D)
if(D.reagents_list.len) // No reagents storage - no reagent designs.
return FALSE
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(materials.has_materials(get_resources_w_coeff(D)))
return TRUE
return FALSE
@@ -140,7 +140,7 @@
desc = "It's building \a [initial(D.name)]."
var/list/res_coef = get_resources_w_coeff(D)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.use_amount(res_coef)
add_overlay("fab-active")
use_power = ACTIVE_POWER_USE
@@ -384,14 +384,14 @@
break
if(href_list["remove_mat"] && href_list["material"])
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_sheets(text2num(href_list["remove_mat"]), href_list["material"])
updateUsrDialog()
return
/obj/machinery/mecha_part_fabricator/on_deconstruction()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
..()
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index 22aac63d2b..717c94362c 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -49,6 +49,8 @@
var/lights = FALSE
var/lights_power = 6
var/last_user_hud = 1 // used to show/hide the mecha hud while preserving previous preference
+ var/breach_time = 0
+ var/recharge_rate = 0
var/bumpsmash = 0 //Whether or not the mech destroys walls by running into it.
//inner atmos
@@ -1023,7 +1025,7 @@
/obj/mecha/log_message(message as text, message_type=LOG_GAME, color=null, log_globally)
log.len++
- log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss")]","date","year"="[GLOB.year_integer+540]","message"="[color?"":null][message][color?" ":null]")
+ log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss")]","date","year"="[GLOB.year_integer]","message"="[color?"":null][message][color?" ":null]")
..()
return log.len
@@ -1032,9 +1034,6 @@
last_entry["message"] += " [red?"":null][message][red?" ":null]"
return
-GLOBAL_VAR_INIT(year, time2text(world.realtime,"YYYY"))
-GLOBAL_VAR_INIT(year_integer, text2num(year)) // = 2013???
-
///////////////////////
///// Power stuff /////
///////////////////////
diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm
index ef3ba969e9..19656f2d7d 100644
--- a/code/game/mecha/working/ripley.dm
+++ b/code/game/mecha/working/ripley.dm
@@ -47,7 +47,7 @@
/obj/mecha/working/ripley/update_icon()
..()
- GET_COMPONENT(C,/datum/component/armor_plate)
+ var/datum/component/armor_plate/C = GetComponent(/datum/component/armor_plate)
if (C.amount)
cut_overlays()
if(C.amount < 3)
diff --git a/code/game/objects/effects/decals/cleanable.dm b/code/game/objects/effects/decals/cleanable.dm
index d5aff99f32..cab4a66fdd 100644
--- a/code/game/objects/effects/decals/cleanable.dm
+++ b/code/game/objects/effects/decals/cleanable.dm
@@ -8,6 +8,7 @@
/obj/effect/decal/cleanable/Initialize(mapload, list/datum/disease/diseases)
. = ..()
+ LAZYINITLIST(blood_DNA) //Kinda needed
if (random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
icon_state = pick(random_icon_states)
create_reagents(300)
@@ -27,7 +28,7 @@
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C) // Returns true if we should give up in favor of the pre-existing decal
if(mergeable_decal)
- return TRUE
+ qdel(C)
/obj/effect/decal/cleanable/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/reagent_containers/glass) || istype(W, /obj/item/reagent_containers/food/drinks))
@@ -44,11 +45,11 @@
if(!reagents.total_volume) //scooped up all of it
qdel(src)
return
- if(W.is_hot()) //todo: make heating a reagent holder proc
+ if(W.get_temperature()) //todo: make heating a reagent holder proc
if(istype(W, /obj/item/clothing/mask/cigarette))
return
else
- var/hotness = W.is_hot()
+ var/hotness = W.get_temperature()
reagents.expose_temperature(hotness)
to_chat(user, "You heat [name] with [W]! ")
else
@@ -81,7 +82,9 @@
add_blood = bloodiness
bloodiness -= add_blood
S.bloody_shoes[blood_state] = min(MAX_SHOE_BLOODINESS,S.bloody_shoes[blood_state]+add_blood)
- S.add_blood_DNA(return_blood_DNA())
+ if(blood_DNA && blood_DNA.len)
+ S.add_blood_DNA(blood_DNA)
+ S.add_blood_overlay()
S.blood_state = blood_state
update_icon()
H.update_inv_shoes()
@@ -90,4 +93,4 @@
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
return bloodiness
else
- return 0
+ return FALSE
diff --git a/code/game/objects/effects/decals/cleanable/aliens.dm b/code/game/objects/effects/decals/cleanable/aliens.dm
index ca2a8ccaff..a4d0da1bbe 100644
--- a/code/game/objects/effects/decals/cleanable/aliens.dm
+++ b/code/game/objects/effects/decals/cleanable/aliens.dm
@@ -1,71 +1,70 @@
-// Note: BYOND is object oriented. There is no reason for this to be copy/pasted blood code.
-/obj/effect/decal/cleanable/xenoblood
+/obj/effect/decal/cleanable/blood/xeno
name = "xeno blood"
desc = "It's green and acidic. It looks like... blood? "
- icon = 'icons/effects/blood.dmi'
- icon_state = "xfloor1"
- random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
- bloodiness = BLOOD_AMOUNT_PER_DECAL
- blood_state = BLOOD_STATE_XENO
+ color = BLOOD_COLOR_XENO
-/obj/effect/decal/cleanable/xenoblood/Initialize()
+/obj/effect/decal/cleanable/blood/splatter/xeno
+ color = BLOOD_COLOR_XENO
+
+/obj/effect/decal/cleanable/blood/gibs/xeno
+ color = BLOOD_COLOR_XENO
+ gibs_reagent_id = "liquidxenogibs"
+ gibs_bloodtype = "X*"
+
+/obj/effect/decal/cleanable/blood/gibs/xeno/Initialize(mapload, list/datum/disease/diseases)
. = ..()
- add_blood_DNA(list("UNKNOWN DNA" = "X*"))
+ update_icon()
-/obj/effect/decal/cleanable/xenoblood/xsplatter
- random_icon_states = list("xgibbl1", "xgibbl2", "xgibbl3", "xgibbl4", "xgibbl5")
+/obj/effect/decal/cleanable/blood/gibs/xeno/update_icon()
+ add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
+ cut_overlays()
+ var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]x_flesh")
+ flesh.appearance_flags = RESET_COLOR
+ flesh.color = body_colors
+ add_overlay(flesh)
-/obj/effect/decal/cleanable/xenoblood/xgibs
- name = "xeno gibs"
- desc = "Gnarly..."
- icon = 'icons/effects/blood.dmi'
- icon_state = "xgib1"
- layer = LOW_OBJ_LAYER
- random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6")
- mergeable_decal = FALSE
-
-/obj/effect/decal/cleanable/xenoblood/xgibs/proc/streak(list/directions)
- set waitfor = 0
+/obj/effect/decal/cleanable/blood/gibs/xeno/streak(list/directions)
+ set waitfor = FALSE
+ var/list/diseases = list()
+ SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
- for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
+ for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
- new /obj/effect/decal/cleanable/xenoblood/xsplatter(loc)
+ var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
+ splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
-/obj/effect/decal/cleanable/xenoblood/xgibs/ex_act()
- return
+/obj/effect/decal/cleanable/blood/gibs/xeno/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
-/obj/effect/decal/cleanable/xenoblood/xgibs/up
- random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibup1","xgibup1","xgibup1")
+/obj/effect/decal/cleanable/blood/gibs/xeno/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
-/obj/effect/decal/cleanable/xenoblood/xgibs/down
- random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6","xgibdown1","xgibdown1","xgibdown1")
+/obj/effect/decal/cleanable/blood/gibs/xeno/body
+ random_icon_states = list("gibhead", "gibtorso")
-/obj/effect/decal/cleanable/xenoblood/xgibs/body
- random_icon_states = list("xgibhead", "xgibtorso")
+/obj/effect/decal/cleanable/blood/gibs/xeno/torso
+ random_icon_states = list("gibtorso")
-/obj/effect/decal/cleanable/xenoblood/xgibs/torso
- random_icon_states = list("xgibtorso")
+/obj/effect/decal/cleanable/blood/gibs/xeno/limb
+ random_icon_states = list("gibleg", "gibarm")
-/obj/effect/decal/cleanable/xenoblood/xgibs/limb
- random_icon_states = list("xgibleg", "xgibarm")
+/obj/effect/decal/cleanable/blood/gibs/xeno/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
-/obj/effect/decal/cleanable/xenoblood/xgibs/core
- random_icon_states = list("xgibmid1", "xgibmid2", "xgibmid3")
-
-/obj/effect/decal/cleanable/xenoblood/xgibs/larva
+/obj/effect/decal/cleanable/blood/gibs/xeno/larva
random_icon_states = list("xgiblarva1", "xgiblarva2")
-/obj/effect/decal/cleanable/xenoblood/xgibs/larva/body
+/obj/effect/decal/cleanable/blood/gibs/xeno/larva/body
random_icon_states = list("xgiblarvahead", "xgiblarvatorso")
/obj/effect/decal/cleanable/blood/xtracks
- icon_state = "xtracks"
+ icon_state = "tracks"
random_icon_states = null
/obj/effect/decal/cleanable/blood/xtracks/Initialize()
- . = ..()
- add_blood_DNA(list("Unknown DNA" = "X*"))
+ add_blood_DNA(list("UNKNOWN DNA" = "X*"))
+ . = ..()
\ No newline at end of file
diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm
new file mode 100644
index 0000000000..03eeca7d0b
--- /dev/null
+++ b/code/game/objects/effects/decals/cleanable/gibs.dm
@@ -0,0 +1,231 @@
+/obj/effect/decal/cleanable/blood/gibs
+ name = "gibs"
+ desc = "They look bloody and gruesome."
+ icon_state = "gibbl5"
+ layer = LOW_OBJ_LAYER
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
+ mergeable_decal = FALSE
+ var/body_colors = "#e3ba84" //a default color just in case.
+ var/gibs_reagent_id = "liquidgibs"
+ var/gibs_bloodtype = "A+"
+
+/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ if(random_icon_states && (icon_state == initial(icon_state)) && length(random_icon_states) > 0)
+ icon_state = pick(random_icon_states)
+ if(gibs_reagent_id)
+ reagents.add_reagent(gibs_reagent_id, 5)
+ if(gibs_bloodtype)
+ add_blood_DNA(list("Non-human DNA" = gibs_bloodtype, diseases))
+ update_icon()
+
+
+/obj/effect/decal/cleanable/blood/gibs/update_icon()
+ add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
+ cut_overlays()
+ var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]_guts")
+ guts.appearance_flags = RESET_COLOR
+ add_overlay(guts)
+ var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]_flesh")
+ flesh.appearance_flags = RESET_COLOR
+ flesh.color = body_colors
+ add_overlay(flesh)
+
+/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
+ return
+
+/obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L)
+ if(istype(L) && has_gravity(loc))
+ playsound(loc, 'sound/effects/gib_step.ogg', !HAS_TRAIT(L,TRAIT_LIGHT_STEP) ? 20 : 50, 1)
+ . = ..()
+
+/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
+ set waitfor = FALSE
+ var/list/diseases = list()
+ SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
+ var/direction = pick(directions)
+ for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
+ sleep(2)
+ if(i > 0)
+ var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
+ splat.transfer_blood_dna(blood_DNA, diseases)
+ if(!step_to(src, get_step(src, direction), 0))
+ break
+
+/obj/effect/decal/cleanable/blood/gibs/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+
+/obj/effect/decal/cleanable/blood/gibs/old
+ name = "old rotting gibs"
+ desc = "Space Jesus, why didn't anyone clean this up? It smells terrible."
+ bloodiness = 0
+
+/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ setDir(pick(GLOB.cardinals))
+ icon_state += "-old"
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/drip
+ name = "drips of blood"
+ desc = "It's gooey."
+ icon_state = "1"
+ random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
+ bloodiness = 0
+ var/drips = 1
+
+/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
+ return TRUE
+
+/obj/effect/decal/cleanable/blood/gibs/human
+
+/obj/effect/decal/cleanable/blood/gibs/human/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/gibs/human/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/human/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/human/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/human/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/human/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/human/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+
+
+//Lizards
+/obj/effect/decal/cleanable/blood/gibs/human/lizard
+ body_colors = "117720"
+ gibs_reagent_id = "liquidgibs"
+ gibs_bloodtype = "L"
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/human/lizard/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+
+// Slime Gibs
+/obj/effect/decal/cleanable/blood/gibs/slime
+ desc = "They look gooey and gruesome."
+ gibs_reagent_id = "liquidslimegibs"
+ gibs_bloodtype = "GEL"
+
+/obj/effect/decal/cleanable/blood/gibs/slime/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/gibs/slime/update_icon()
+ add_atom_colour(body_colors, FIXED_COLOUR_PRIORITY)
+ cut_overlays()
+ var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]s_guts")
+ guts.appearance_flags = RESET_COLOR
+ guts.color = body_colors
+ add_overlay(guts)
+ var/mutable_appearance/flesh = mutable_appearance(icon, "[icon_state]_flesh")
+ flesh.appearance_flags = RESET_COLOR
+ flesh.color = body_colors
+ add_overlay(flesh)
+
+/obj/effect/decal/cleanable/blood/gibs/slime/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/slime/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
+
+/obj/effect/decal/cleanable/blood/gibs/synth
+ desc = "They look sludgy and disgusting."
+ gibs_reagent_id = "liquidsyntheticgibs"
+ gibs_bloodtype = "SY"
+
+/obj/effect/decal/cleanable/blood/gibs/synth/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+//IPCs
+/obj/effect/decal/cleanable/blood/gibs/ipc
+ desc = "They look sharp yet oozing."
+ body_colors = "00ff00"
+ gibs_reagent_id = "liquidoilgibs"
+ gibs_bloodtype = "HF"
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/update_icon()
+ add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
+ cut_overlays()
+ var/mutable_appearance/guts = mutable_appearance(icon, "[icon_state]r-overlay")
+ guts.appearance_flags = RESET_COLOR
+ add_overlay(guts)
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/up
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/down
+ random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/body
+ random_icon_states = list("gibhead", "gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/torso
+ random_icon_states = list("gibtorso")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/limb
+ random_icon_states = list("gibleg", "gibarm")
+
+/obj/effect/decal/cleanable/blood/gibs/ipc/core
+ random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
diff --git a/code/game/objects/effects/decals/cleanable/humans.dm b/code/game/objects/effects/decals/cleanable/humans.dm
index 35f06c2768..842b230b53 100644
--- a/code/game/objects/effects/decals/cleanable/humans.dm
+++ b/code/game/objects/effects/decals/cleanable/humans.dm
@@ -1,31 +1,45 @@
/obj/effect/decal/cleanable/blood
name = "blood"
- desc = "It's red and gooey. Perhaps it's the chef's cooking?"
+ desc = "It's gooey. Perhaps it's the chef's cooking?"
icon = 'icons/effects/blood.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
- blood_state = BLOOD_STATE_HUMAN
- bloodiness = BLOOD_AMOUNT_PER_DECAL
+ blood_state = BLOOD_STATE_BLOOD
+ bloodiness = MAX_SHOE_BLOODINESS
+ color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
- C.add_blood_DNA(return_blood_DNA())
- if (bloodiness)
- if (C.bloodiness < MAX_SHOE_BLOODINESS)
- C.bloodiness += bloodiness
- return ..()
+ if (C.blood_DNA)
+ blood_DNA |= C.blood_DNA.Copy()
+ update_icon()
+ ..()
+
+/obj/effect/decal/cleanable/blood/transfer_blood_dna()
+ ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/transfer_mob_blood_dna()
+ . = ..()
+ update_icon()
+
+/obj/effect/decal/cleanable/blood/update_icon()
+ color = blood_DNA_to_color()
/obj/effect/decal/cleanable/blood/old
name = "dried blood"
- desc = "Looks like it's been here a while. Eew."
+ desc = "Looks like it's been here a while. Eew."
bloodiness = 0
/obj/effect/decal/cleanable/blood/old/Initialize(mapload, list/datum/disease/diseases)
- icon_state += "-old" //This IS necessary because the parent /blood type uses icon randomization.
- add_blood_DNA(list("Non-human DNA" = "A+")) // Needs to happen before ..()
- return ..()
+ ..()
+ icon_state += "-old"
+ add_blood_DNA(list("Non-human DNA" = "A+"))
+
+/obj/effect/decal/cleanable/blood/splats
+ random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
/obj/effect/decal/cleanable/blood/splatter
- random_icon_states = list("gibbl1", "gibbl2", "gibbl3", "gibbl4", "gibbl5")
+ random_icon_states = list("splatter1", "splatter2", "splatter3", "splatter4", "splatter5")
/obj/effect/decal/cleanable/blood/tracks
icon_state = "tracks"
@@ -39,84 +53,23 @@
random_icon_states = null
var/list/existing_dirs = list()
+/obj/effect/decal/cleanable/trail_holder/update_icon()
+ color = blood_DNA_to_color()
+
+/obj/effect/cleanable/trail_holder/Initialize()
+ . = ..()
+ update_icon()
+
/obj/effect/decal/cleanable/trail_holder/can_bloodcrawl_in()
return TRUE
-/obj/effect/decal/cleanable/blood/gibs
- name = "gibs"
- desc = "They look bloody and gruesome."
- icon = 'icons/effects/blood.dmi'
- icon_state = "gibbl5"
- layer = LOW_OBJ_LAYER
- random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
- mergeable_decal = FALSE
+/obj/effect/decal/cleanable/trail_holder/transfer_blood_dna()
+ ..()
+ update_icon()
-/obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases)
+/obj/effect/decal/cleanable/trail_holder/transfer_mob_blood_dna()
. = ..()
- reagents.add_reagent("liquidgibs", 5)
-
-/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
- return
-
-/obj/effect/decal/cleanable/blood/gibs/Crossed(mob/living/L)
- if(istype(L) && has_gravity(loc))
- playsound(loc, 'sound/effects/gib_step.ogg', HAS_TRAIT(L, TRAIT_LIGHT_STEP) ? 20 : 50, 1)
- . = ..()
-
-/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
- set waitfor = 0
- var/direction = pick(directions)
- for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
- sleep(2)
- if(i > 0)
- var/list/datum/disease/diseases
- GET_COMPONENT(infective, /datum/component/infective)
- if(infective)
- diseases = infective.diseases
- new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
- if(!step_to(src, get_step(src, direction), 0))
- break
-
-/obj/effect/decal/cleanable/blood/gibs/up
- random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
-
-/obj/effect/decal/cleanable/blood/gibs/down
- random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibdown1","gibdown1","gibdown1")
-
-/obj/effect/decal/cleanable/blood/gibs/body
- random_icon_states = list("gibhead", "gibtorso")
-
-/obj/effect/decal/cleanable/blood/gibs/torso
- random_icon_states = list("gibtorso")
-
-/obj/effect/decal/cleanable/blood/gibs/limb
- random_icon_states = list("gibleg", "gibarm")
-
-/obj/effect/decal/cleanable/blood/gibs/core
- random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
-
-/obj/effect/decal/cleanable/blood/gibs/old
- name = "old rotting gibs"
- desc = "Space Jesus, why didn't anyone clean this up? It smells terrible."
- bloodiness = 0
-
-/obj/effect/decal/cleanable/blood/gibs/old/Initialize(mapload, list/datum/disease/diseases)
- . = ..()
- setDir(pick(1,2,4,8))
- icon_state += "-old"
- add_blood_DNA(list("Non-human DNA" = "A+"))
-
-/obj/effect/decal/cleanable/blood/drip
- name = "drips of blood"
- desc = "It's red."
- icon_state = "1"
- random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
- bloodiness = 0
- var/drips = 1
-
-/obj/effect/decal/cleanable/blood/drip/can_bloodcrawl_in()
- return TRUE
-
+ update_icon()
//BLOODY FOOTPRINTS
/obj/effect/decal/cleanable/blood/footprints
@@ -127,15 +80,16 @@
random_icon_states = null
var/entered_dirs = 0
var/exited_dirs = 0
- blood_state = BLOOD_STATE_HUMAN //the icon state to load images from
+ blood_state = BLOOD_STATE_BLOOD //the icon state to load images from
var/list/shoe_types = list()
/obj/effect/decal/cleanable/blood/footprints/Crossed(atom/movable/O)
- ..()
if(ishuman(O))
var/mob/living/carbon/human/H = O
var/obj/item/clothing/shoes/S = H.shoes
if(S && S.bloody_shoes[blood_state])
+ if(color != bloodtype_to_color(S.last_bloodtype))
+ return
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
shoe_types |= S.type
if (!(entered_dirs & H.dir))
@@ -143,21 +97,21 @@
update_icon()
/obj/effect/decal/cleanable/blood/footprints/Uncrossed(atom/movable/O)
- ..()
if(ishuman(O))
var/mob/living/carbon/human/H = O
var/obj/item/clothing/shoes/S = H.shoes
if(S && S.bloody_shoes[blood_state])
+ if(color != bloodtype_to_color(S.last_bloodtype))//last entry - we check its color
+ return
S.bloody_shoes[blood_state] = max(S.bloody_shoes[blood_state] - BLOOD_LOSS_PER_STEP, 0)
shoe_types |= S.type
if (!(exited_dirs & H.dir))
exited_dirs |= H.dir
update_icon()
-
/obj/effect/decal/cleanable/blood/footprints/update_icon()
+ ..()
cut_overlays()
-
for(var/Ddir in GLOB.cardinals)
if(entered_dirs & Ddir)
var/image/bloodstep_overlay = GLOB.bloody_footprints_cache["entered-[blood_state]-[Ddir]"]
@@ -170,7 +124,7 @@
GLOB.bloody_footprints_cache["exited-[blood_state]-[Ddir]"] = bloodstep_overlay = image(icon, "[blood_state]2", dir = Ddir)
add_overlay(bloodstep_overlay)
- alpha = BLOODY_FOOTPRINT_BASE_ALPHA+bloodiness
+ alpha = BLOODY_FOOTPRINT_BASE_ALPHA + bloodiness
/obj/effect/decal/cleanable/blood/footprints/examine(mob/user)
@@ -179,16 +133,62 @@
. += "You recognise the footprints as belonging to:\n"
for(var/shoe in shoe_types)
var/obj/item/clothing/shoes/S = shoe
- . += "[icon2html(initial(S.icon), user)] Some [initial(S.name)] .\n"
+ . += "some [initial(S.name)] [icon2html(initial(S.icon), user)]\n"
to_chat(user, .)
/obj/effect/decal/cleanable/blood/footprints/replace_decal(obj/effect/decal/cleanable/C)
if(blood_state != C.blood_state) //We only replace footprints of the same type as us
return
+ if(color != C.color)
+ return
..()
/obj/effect/decal/cleanable/blood/footprints/can_bloodcrawl_in()
if((blood_state != BLOOD_STATE_OIL) && (blood_state != BLOOD_STATE_NOT_BLOODY))
- return 1
- return 0
+ return TRUE
+ return FALSE
+
+/* Eventually TODO: make snowflake trails like baycode's
+/obj/effect/decal/cleanable/blood/footprints/tracks/shoe
+ name = "footprints"
+ desc = "They look like tracks left by footwear."
+ icon_state = FOOTPRINT_SHOE
+ print_state = FOOTPRINT_SHOE
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/foot
+ name = "footprints"
+ desc = "They look like tracks left by a bare foot."
+ icon_state = FOOTPRINT_FOOT
+ print_state = FOOTPRINT_FOOT
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/snake
+ name = "tracks"
+ desc = "They look like tracks left by a giant snake."
+ icon_state = FOOTPRINT_SNAKE
+ print_state = FOOTPRINT_SNAKE
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/paw
+ name = "footprints"
+ desc = "They look like tracks left by paws."
+ icon_state = FOOTPRINT_PAW
+ print_state = FOOTPRINT_PAW
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/claw
+ name = "footprints"
+ desc = "They look like tracks left by claws."
+ icon_state = FOOTPRINT_CLAW
+ print_state = FOOTPRINT_CLAW
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/wheels
+ name = "tracks"
+ desc = "They look like tracks left by wheels."
+ gender = PLURAL
+ icon_state = FOOTPRINT_WHEEL
+ print_state = FOOTPRINT_WHEEL
+
+/obj/effect/decal/cleanable/blood/footprints/tracks/body
+ name = "trails"
+ desc = "A trail left by something being dragged."
+ icon_state = FOOTPRINT_DRAG
+ print_state = FOOTPRINT_DRAG */
diff --git a/code/game/objects/effects/decals/cleanable/robots.dm b/code/game/objects/effects/decals/cleanable/robots.dm
index 484e0438e2..02bf51bdd9 100644
--- a/code/game/objects/effects/decals/cleanable/robots.dm
+++ b/code/game/objects/effects/decals/cleanable/robots.dm
@@ -11,6 +11,10 @@
bloodiness = BLOOD_AMOUNT_PER_DECAL
mergeable_decal = FALSE
+/obj/effect/decal/cleanable/robot_debris/Initialize(mapload, list/datum/disease/diseases)
+ . = ..()
+ reagents.add_reagent("liquidoilgibs", 5)
+
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
@@ -50,6 +54,7 @@
/obj/effect/decal/cleanable/oil/Initialize()
. = ..()
reagents.add_reagent("oil", 30)
+ reagents.add_reagent("liquidoilgibs", 5)
/obj/effect/decal/cleanable/oil/streak
random_icon_states = list("streak1", "streak2", "streak3", "streak4", "streak5")
diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm
index 79deac475b..028110170a 100644
--- a/code/game/objects/effects/effect_system/effects_smoke.dm
+++ b/code/game/objects/effects/effect_system/effects_smoke.dm
@@ -288,7 +288,7 @@
contained = "\[[contained]\]"
var/where = "[AREACOORD(location)]"
- if(carry.my_atom.fingerprintslast)
+ if(carry.my_atom && carry.my_atom.fingerprintslast)
var/mob/M = get_mob_by_key(carry.my_atom.fingerprintslast)
var/more = ""
if(M)
diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm
index 32d91ee76a..08f698e018 100644
--- a/code/game/objects/effects/mines.dm
+++ b/code/game/objects/effects/mines.dm
@@ -170,7 +170,7 @@
if(!victim.client || !istype(victim))
return
to_chat(victim, "You feel fast! ")
- ADD_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
+ victim.add_movespeed_modifier(MOVESPEED_ID_YELLOW_ORB, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING))
sleep(duration)
- REMOVE_TRAIT(victim, TRAIT_GOTTAGOREALLYFAST, "yellow_orb")
+ victim.remove_movespeed_modifier(MOVESPEED_ID_YELLOW_ORB)
to_chat(victim, "You slow down. ")
diff --git a/code/game/objects/effects/proximity.dm b/code/game/objects/effects/proximity.dm
index de17582f27..6c9525008d 100644
--- a/code/game/objects/effects/proximity.dm
+++ b/code/game/objects/effects/proximity.dm
@@ -5,7 +5,6 @@
var/list/checkers //list of /obj/effect/abstract/proximity_checkers
var/current_range
var/ignore_if_not_on_turf //don't check turfs in range if the host's loc isn't a turf
- var/datum/component/movement_tracker
/datum/proximity_monitor/New(atom/_host, range, _ignore_if_not_on_turf = TRUE)
checkers = list()
@@ -15,15 +14,17 @@
SetHost(_host)
/datum/proximity_monitor/proc/SetHost(atom/H,atom/R)
+ if(H == host)
+ return
+ if(host)
+ UnregisterSignal(host, COMSIG_MOVABLE_MOVED)
if(R)
hasprox_receiver = R
else if(hasprox_receiver == host) //Default case
hasprox_receiver = H
host = H
+ RegisterSignal(host, COMSIG_MOVABLE_MOVED, .proc/HandleMove)
last_host_loc = host.loc
- if(movement_tracker)
- QDEL_NULL(movement_tracker)
- movement_tracker = host.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/HandleMove)))
SetRange(current_range,TRUE)
/datum/proximity_monitor/Destroy()
@@ -31,7 +32,6 @@
last_host_loc = null
hasprox_receiver = null
QDEL_LIST(checkers)
- QDEL_NULL(movement_tracker)
return ..()
/datum/proximity_monitor/proc/HandleMove()
diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm
index e99a2fcbc6..dd39bc567a 100644
--- a/code/game/objects/effects/spawners/gibspawner.dm
+++ b/code/game/objects/effects/spawners/gibspawner.dm
@@ -1,25 +1,69 @@
/obj/effect/gibspawner
- var/sparks = 0 //whether sparks spread
+ var/sparks = FALSE //whether sparks spread
var/virusProb = 20 //the chance for viruses to spread on the gibs
+ var/gib_mob_type //generate a fake mob to transfer DNA from if we weren't passed a mob.
+ var/gib_mob_species //We'll want to nip-pick their species for blood type stuff
+ var/sound_to_play = 'sound/effects/blobattack.ogg'
+ var/sound_vol = 60
var/list/gibtypes = list() //typepaths of the gib decals to spawn
var/list/gibamounts = list() //amount to spawn for each gib decal type we'll spawn.
var/list/gibdirections = list() //of lists of possible directions to spread each gib decal type towards.
-/obj/effect/gibspawner/Initialize(mapload, datum/dna/MobDNA, list/datum/disease/diseases)
+/obj/effect/gibspawner/Initialize(mapload, mob/living/source_mob, list/datum/disease/diseases)
. = ..()
-
- if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
- to_chat(world, "Gib list length mismatch! ")
+ if(gibtypes.len != gibamounts.len)
+ stack_trace("Gib list amount length mismatch!")
+ return
+ if(gibamounts.len != gibdirections.len)
+ stack_trace("Gib list dir length mismatch!")
return
var/obj/effect/decal/cleanable/blood/gibs/gib = null
+ if(sound_to_play && isnum(sound_vol))
+ playsound(src, sound_to_play, sound_vol, TRUE)
+
if(sparks)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, loc)
s.start()
+ var/list/dna_to_add //find the dna to pass to the spawned gibs. do note this can be null if the mob doesn't have blood. add_blood_DNA() has built in null handling.
+ var/body_coloring = ""
+ if(source_mob)
+ dna_to_add = source_mob.get_blood_dna_list() //ez pz
+ if(ishuman(source_mob))
+ var/mob/living/carbon/human/H = source_mob
+ if(H.dna.species.use_skintones)
+ body_coloring = "#[skintone2hex(H.skin_tone)]"
+ else
+ body_coloring = "#[H.dna.features["mcolor"]]"
+
+ else if(gib_mob_type)
+ var/mob/living/temp_mob = new gib_mob_type(src) //generate a fake mob so that we pull the right type of DNA for the gibs.
+ if(gib_mob_species)
+ if(ishuman(temp_mob))
+ var/mob/living/carbon/human/H = temp_mob
+ H.set_species(gib_mob_species)
+ dna_to_add = temp_mob.get_blood_dna_list()
+ if(H.dna.species.use_skintones)
+ body_coloring = "#[skintone2hex(H.skin_tone)]"
+ else
+ body_coloring = "#[H.dna.features["mcolor"]]"
+ qdel(H)
+ else
+ dna_to_add = temp_mob.get_blood_dna_list()
+ qdel(temp_mob)
+ else if(!issilicon(temp_mob))
+ dna_to_add = temp_mob.get_blood_dna_list()
+ qdel(temp_mob)
+ else
+ qdel(temp_mob)
+ else
+ dna_to_add = list("Non-human DNA" = random_blood_type()) //else, generate a random bloodtype for it.
+
+
for(var/i = 1, i<= gibtypes.len, i++)
if(gibamounts[i])
for(var/j = 1, j<= gibamounts[i], j++)
@@ -29,10 +73,11 @@
var/mob/living/carbon/digester = loc
digester.stomach_contents += gib
- if(MobDNA)
+ if(dna_to_add && dna_to_add.len)
+ gib.add_blood_DNA(dna_to_add)
+ gib.body_colors = body_coloring
+ gib.update_icon()
- else if(istype(src, /obj/effect/gibspawner/generic)) // Probably a monkey
- gib.add_blood_DNA(list("Non-human DNA" = "A+"))
var/list/directions = gibdirections[i]
if(isturf(loc))
if(directions.len)
@@ -41,80 +86,158 @@
return INITIALIZE_HINT_QDEL
-
/obj/effect/gibspawner/generic
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core)
- gibamounts = list(2,2,1)
+ gibamounts = list(2, 2, 1)
+ sound_vol = 40
/obj/effect/gibspawner/generic/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 40, 1)
- gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(WEST, NORTHWEST, SOUTHWEST, NORTH),list(EAST, NORTHEAST, SOUTHEAST, SOUTH), list())
+ return ..()
+
+/obj/effect/gibspawner/generic/animal
+ gib_mob_type = /mob/living/simple_animal/pet
/obj/effect/gibspawner/human
- gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/up, /obj/effect/decal/cleanable/blood/gibs/down, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/body, /obj/effect/decal/cleanable/blood/gibs/limb, /obj/effect/decal/cleanable/blood/gibs/core)
- gibamounts = list(1,1,1,1,1,1,1)
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/up, /obj/effect/decal/cleanable/blood/gibs/human/down, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/body, /obj/effect/decal/cleanable/blood/gibs/human/limb, /obj/effect/decal/cleanable/blood/gibs/human/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/human
+ gib_mob_species = /datum/species/human
+ sound_vol = 50
/obj/effect/gibspawner/human/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 50, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
-
-/obj/effect/gibspawner/humanbodypartless //only the gibs that don't look like actual full bodyparts (except torso).
- gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/torso)
+/obj/effect/gibspawner/human/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/core, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/core, /obj/effect/decal/cleanable/blood/gibs/human, /obj/effect/decal/cleanable/blood/gibs/human/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
-/obj/effect/gibspawner/humanbodypartless/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 50, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
- . = ..()
+/obj/effect/gibspawner/human/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
+/obj/effect/gibspawner/lizard
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/lizard/up, /obj/effect/decal/cleanable/blood/gibs/human/lizard/down, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/body, /obj/effect/decal/cleanable/blood/gibs/human/lizard/limb, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/human/species/lizard
+ gib_mob_species = /datum/species/lizard
+ sound_vol = 50
+
+/obj/effect/gibspawner/lizard/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/lizard/bodypartless
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/core, /obj/effect/decal/cleanable/blood/gibs/human/lizard, /obj/effect/decal/cleanable/blood/gibs/human/lizard/torso)
+ gibamounts = list(1, 1, 1, 1, 1, 1)
+
+/obj/effect/gibspawner/lizard/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/slime
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/slime/up, /obj/effect/decal/cleanable/blood/gibs/slime/down, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/body, /obj/effect/decal/cleanable/blood/gibs/slime/limb, /obj/effect/decal/cleanable/blood/gibs/slime/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/human/species/roundstartslime
+ gib_mob_species = /datum/species/jelly/roundstartslime
+ sound_vol = 50
+
+/obj/effect/gibspawner/slime/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/slime/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/core, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/core, /obj/effect/decal/cleanable/blood/gibs/slime, /obj/effect/decal/cleanable/blood/gibs/slime/torso)
+ gibamounts = list(1, 1, 1, 1, 1, 1)
+
+/obj/effect/gibspawner/slime/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/ipc
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/ipc/up, /obj/effect/decal/cleanable/blood/gibs/ipc/down, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/body, /obj/effect/decal/cleanable/blood/gibs/ipc/limb, /obj/effect/decal/cleanable/blood/gibs/ipc/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/human/species/ipc
+ gib_mob_species = /datum/species/ipc
+ sound_vol = 50
+ sparks = TRUE
+ sound_to_play = 'sound/effects/bang.ogg'
+
+/obj/effect/gibspawner/ipc/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
+
+/obj/effect/gibspawner/ipc/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/core, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/core, /obj/effect/decal/cleanable/blood/gibs/ipc, /obj/effect/decal/cleanable/blood/gibs/ipc/torso)
+ gibamounts = list(1, 1, 1, 1, 1, 1)
+
+/obj/effect/gibspawner/ipc/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
/obj/effect/gibspawner/xeno
- gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/up, /obj/effect/decal/cleanable/xenoblood/xgibs/down, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/body, /obj/effect/decal/cleanable/xenoblood/xgibs/limb, /obj/effect/decal/cleanable/xenoblood/xgibs/core)
- gibamounts = list(1,1,1,1,1,1,1)
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/up, /obj/effect/decal/cleanable/blood/gibs/xeno/down, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/body, /obj/effect/decal/cleanable/blood/gibs/xeno/limb, /obj/effect/decal/cleanable/blood/gibs/xeno/core)
+ gibamounts = list(1, 1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/alien
/obj/effect/gibspawner/xeno/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs, list())
+ return ..()
-
-/obj/effect/gibspawner/xenobodypartless //only the gibs that don't look like actual full bodyparts (except torso).
- gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/torso)
+/obj/effect/gibspawner/xeno/bodypartless //only the gibs that don't look like actual full bodyparts (except torso).
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/core, /obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/xeno/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
+/obj/effect/gibspawner/xeno/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
+ return ..()
-/obj/effect/gibspawner/xenobodypartless/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, list())
- . = ..()
+/obj/effect/gibspawner/xeno/xenoperson
+ gib_mob_type = /mob/living/carbon/human/species/xeno
+ gib_mob_species = /datum/species/xeno
+
+/obj/effect/gibspawner/xeno/xenoperson/bodypartless
/obj/effect/gibspawner/larva
- gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva/body, /obj/effect/decal/cleanable/xenoblood/xgibs/larva/body)
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva/body, /obj/effect/decal/cleanable/blood/gibs/xeno/larva/body)
gibamounts = list(1, 1, 1, 1)
+ gib_mob_type = /mob/living/carbon/alien/larva
/obj/effect/gibspawner/larva/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list(), GLOB.alldirs)
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list(), GLOB.alldirs)
+ return ..()
-/obj/effect/gibspawner/larvabodypartless
- gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva)
+/obj/effect/gibspawner/larva/bodypartless
+ gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva, /obj/effect/decal/cleanable/blood/gibs/xeno/larva)
gibamounts = list(1, 1, 1)
-/obj/effect/gibspawner/larvabodypartless/Initialize()
- playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list())
- . = ..()
+/obj/effect/gibspawner/larva/bodypartless/Initialize()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list())
+ return ..()
/obj/effect/gibspawner/robot
- sparks = 1
+ sparks = TRUE
gibtypes = list(/obj/effect/decal/cleanable/robot_debris/up, /obj/effect/decal/cleanable/robot_debris/down, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris, /obj/effect/decal/cleanable/robot_debris/limb)
- gibamounts = list(1,1,1,1,1,1)
+ gibamounts = list(1, 1, 1, 1, 1, 1)
+ gib_mob_type = /mob/living/silicon/robot
/obj/effect/gibspawner/robot/Initialize()
- gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs)
- gibamounts[6] = pick(0,1,2)
- . = ..()
+ if(!gibdirections.len)
+ gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), GLOB.alldirs, GLOB.alldirs)
+ gibamounts[6] = pick(0, 1, 2)
+ return ..()
+
diff --git a/code/game/objects/effects/temporary_visuals/miscellaneous.dm b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
index 7d02d9d383..fbad000098 100644
--- a/code/game/objects/effects/temporary_visuals/miscellaneous.dm
+++ b/code/game/objects/effects/temporary_visuals/miscellaneous.dm
@@ -6,7 +6,9 @@
layer = BELOW_MOB_LAYER
var/splatter_type = "splatter"
-/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir)
+/obj/effect/temp_visual/dir_setting/bloodsplatter/Initialize(mapload, set_dir, new_color)
+ if(new_color)
+ color = new_color
if(set_dir in GLOB.diagonals)
icon_state = "[splatter_type][pick(1, 2, 6)]"
else
@@ -41,7 +43,7 @@
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
/obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter
- splatter_type = "xsplatter"
+ color = BLOOD_COLOR_XENO
/obj/effect/temp_visual/dir_setting/speedbike_trail
name = "speedbike trails"
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index c98cef2b87..953036e970 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -97,9 +97,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
// non-clothing items
var/datum/dog_fashion/dog_fashion = null
- var/datum/rpg_loot/rpg_loot = null
-
-
//Tooltip vars
var/force_string //string form of an item's force. Edit this var only to set a custom force string
var/last_force_string_check = 0
@@ -111,7 +108,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
var/list/grind_results //A reagent list containing the reagents this item produces when ground up in a grinder - this can be an empty list to allow for reagent transferring only
var/list/juice_results //A reagent list containing blah blah... but when JUICED in a grinder!
-
/obj/item/Initialize()
materials = typelist("materials", materials)
@@ -125,7 +121,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
actions_types = null
if(GLOB.rpg_loot_items)
- rpg_loot = new(src)
+ AddComponent(/datum/component/fantasy)
if(force_string)
item_flags |= FORCE_STRING_OVERRIDE
@@ -150,7 +146,6 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
m.temporarilyRemoveItemFromInventory(src, TRUE)
for(var/X in actions)
qdel(X)
- QDEL_NULL(rpg_loot)
return ..()
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
@@ -408,12 +403,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
SEND_SIGNAL(src, COMSIG_ITEM_EQUIPPED, user, slot)
for(var/X in actions)
var/datum/action/A = X
- if(item_action_slot_check(slot, user)) //some items only give their actions buttons when in a specific slot.
+ if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot.
A.Grant(user)
item_flags |= IN_INVENTORY
//sometimes we only want to grant the item's action if it's equipped in a specific slot.
-/obj/item/proc/item_action_slot_check(slot, mob/user)
+/obj/item/proc/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_IN_BACKPACK || slot == SLOT_LEGCUFFED) //these aren't true slots, so avoid granting actions there
return FALSE
return TRUE
@@ -421,10 +416,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't.
//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise.
//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen.
-//Set disable_warning to 1 if you wish it to not give you outputs.
+//Set disable_warning to TRUE if you wish it to not give you outputs.
/obj/item/proc/mob_can_equip(mob/living/M, mob/living/equipper, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
if(!M)
- return 0
+ return FALSE
return M.can_equip(src, slot, disable_warning, bypass_equip_delay_self)
@@ -514,12 +509,12 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
log_combat(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])")
- M.adjust_blurriness(3)
- M.adjust_eye_damage(rand(2,4))
var/obj/item/organ/eyes/eyes = M.getorganslot(ORGAN_SLOT_EYES)
if (!eyes)
return
- if(eyes.eye_damage >= 10)
+ M.adjust_blurriness(3)
+ eyes.applyOrganDamage(rand(2,4))
+ if(eyes.damage >= 10)
M.adjust_blurriness(15)
if(M.stat != DEAD)
to_chat(M, "Your eyes start to bleed profusely! ")
@@ -533,10 +528,21 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
M.adjust_blurriness(10)
M.Unconscious(20)
M.Knockdown(40)
- if (prob(eyes.eye_damage - 10 + 1))
+ if (prob(eyes.damage - 10 + 1))
M.become_blind(EYE_DAMAGE)
to_chat(M, "You go blind! ")
+/obj/item/clean_blood()
+ . = ..()
+ if(.)
+ if(blood_splatter_icon)
+ cut_overlay(blood_splatter_icon)
+
+/obj/item/clothing/gloves/clean_blood()
+ . = ..()
+ if(.)
+ transfer_blood = 0
+
/obj/item/singularity_pull(S, current_size)
..()
if(current_size >= STAGE_FOUR)
@@ -547,7 +553,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/throw_impact(atom/A, datum/thrownthing/throwingdatum)
if(A && !QDELETED(A))
SEND_SIGNAL(src, COMSIG_MOVABLE_IMPACT, A, throwingdatum)
- if(is_hot() && isliving(A))
+ if(get_temperature() && isliving(A))
var/mob/living/L = A
L.IgniteMob()
var/itempush = 1
@@ -614,10 +620,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
if(flags & ITEM_SLOT_NECK)
owner.update_inv_neck()
-/obj/item/proc/is_hot()
+/obj/item/proc/get_temperature()
return heat
-/obj/item/proc/is_sharp()
+/obj/item/proc/get_sharpness()
return sharpness
/obj/item/proc/get_dismemberment_chance(obj/item/bodypart/affecting)
@@ -644,7 +650,7 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
location.hotspot_expose(flame_heat, 1)
/obj/item/proc/ignition_effect(atom/A, mob/user)
- if(is_hot())
+ if(get_temperature())
. = "[user] lights [A] with [src]. "
else
. = ""
diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm
index cf706359f7..8763089464 100644
--- a/code/game/objects/items/RCD.dm
+++ b/code/game/objects/items/RCD.dm
@@ -441,13 +441,16 @@ RLD
var/list/rcd_results = A.rcd_vals(user, src)
if(!rcd_results)
return FALSE
+ var/turf/the_turf = get_turf(A)
+ var/turf_coords = "[COORD(the_turf)]"
+ investigate_log("[user] is attempting to use [src] on [A] (loc [turf_coords] at [the_turf]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD)
if(do_after(user, rcd_results["delay"] * delay_mod, target = A))
if(checkResource(rcd_results["cost"], user))
var/atom/cached = A
if(A.rcd_act(user, src, rcd_results["mode"]))
useResource(rcd_results["cost"], user)
activate()
- investigate_log("[user] used [src] on [cached] (now [A]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD)
+ investigate_log("[user] used [src] on [cached] (loc [turf_coords] at [the_turf]) with cost [rcd_results["cost"]], delay [rcd_results["delay"]], mode [rcd_results["mode"]].", INVESTIGATE_RCD)
playsound(src, 'sound/machines/click.ogg', 50, 1)
return TRUE
diff --git a/code/game/objects/items/RCL.dm b/code/game/objects/items/RCL.dm
index 63f460f9aa..93293155a3 100644
--- a/code/game/objects/items/RCL.dm
+++ b/code/game/objects/items/RCL.dm
@@ -20,8 +20,8 @@
var/ghetto = FALSE
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
- var/datum/component/mobhook
var/datum/radial_menu/persistent/wiring_gui_menu
+ var/mob/listeningTo
/obj/item/twohanded/rcl/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/cable_coil))
@@ -86,7 +86,7 @@
/obj/item/twohanded/rcl/Destroy()
QDEL_NULL(loaded)
last = null
- QDEL_NULL(mobhook)
+ listeningTo = null
QDEL_NULL(wiring_gui_menu)
return ..()
@@ -141,9 +141,8 @@
/obj/item/twohanded/rcl/dropped(mob/wearer)
..()
- if(mobhook)
- active = FALSE
- QDEL_NULL(mobhook)
+ UnregisterSignal(wearer, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
last = null
/obj/item/twohanded/rcl/attack_self(mob/user)
@@ -158,13 +157,12 @@
break
obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
- if(to_hook)
- if(mobhook && mobhook.parent != to_hook)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = to_hook.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/trigger)))
- else
- QDEL_NULL(mobhook)
+ if(listeningTo == to_hook)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ RegisterSignal(to_hook, COMSIG_MOVABLE_MOVED, .proc/trigger)
+ listeningTo = to_hook
/obj/item/twohanded/rcl/proc/trigger(mob/user)
if(active)
diff --git a/code/game/objects/items/blueprints.dm b/code/game/objects/items/blueprints.dm
index 699efaac2e..10fbab56be 100644
--- a/code/game/objects/items/blueprints.dm
+++ b/code/game/objects/items/blueprints.dm
@@ -153,7 +153,9 @@
/area/centcom,
/area/asteroid,
/area/tdome,
- /area/wizard_station
+ /area/wizard_station,
+ /area/hilbertshotel,
+ /area/hilbertshotelstorage
)
for (var/type in SPECIALS)
if ( istype(A,type) )
diff --git a/code/game/objects/items/body_egg.dm b/code/game/objects/items/body_egg.dm
index 80fc0f43fd..f0d20afbbd 100644
--- a/code/game/objects/items/body_egg.dm
+++ b/code/game/objects/items/body_egg.dm
@@ -17,26 +17,27 @@
/obj/item/organ/body_egg/Insert(var/mob/living/carbon/M, special = 0)
..()
ADD_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
- START_PROCESSING(SSobj, src)
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/AddInfectionImages, owner)
/obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0)
- STOP_PROCESSING(SSobj, src)
if(owner)
REMOVE_TRAIT(owner, TRAIT_XENO_HOST, TRAIT_GENERIC)
owner.med_hud_set_status()
INVOKE_ASYNC(src, .proc/RemoveInfectionImages, owner)
..()
-/obj/item/organ/body_egg/process()
+/obj/item/organ/body_egg/on_death()
+ . = ..()
if(!owner)
return
- if(!(src in owner.internal_organs))
- Remove(owner)
- return
egg_process()
+/obj/item/organ/body_egg/on_life()
+ . = ..()
+ egg_process()
+
+
/obj/item/organ/body_egg/proc/egg_process()
return
@@ -44,8 +45,8 @@
RemoveInfectionImages()
AddInfectionImages()
-/obj/item/organ/body_egg/proc/AddInfectionImages()
+/obj/item/organ/body_egg/proc/AddInfectionImages(mob/living/carbon/C)
return
-/obj/item/organ/body_egg/proc/RemoveInfectionImages()
+/obj/item/organ/body_egg/proc/RemoveInfectionImages(mob/living/carbon/C)
return
diff --git a/code/game/objects/items/candle.dm b/code/game/objects/items/candle.dm
index 1165501d9a..fa9c25960a 100644
--- a/code/game/objects/items/candle.dm
+++ b/code/game/objects/items/candle.dm
@@ -34,7 +34,7 @@
light() //honk
return ..()
-/obj/item/candle/is_hot()
+/obj/item/candle/get_temperature()
return lit * heat
/obj/item/candle/proc/light(show_message)
diff --git a/code/game/objects/items/cards_ids.dm b/code/game/objects/items/cards_ids.dm
index 05ffcbf2fd..0e422a3fe9 100644
--- a/code/game/objects/items/cards_ids.dm
+++ b/code/game/objects/items/cards_ids.dm
@@ -80,6 +80,7 @@
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
item_flags = NO_MAT_REDEMPTION | NOBLUDGEON
var/prox_check = TRUE //If the emag requires you to be in range
+ var/uses = 15
/obj/item/card/emag/bluespace
name = "bluespace cryptographic sequencer"
@@ -110,6 +111,37 @@
user.visible_message("[src] fizzles and sparks. It seems like it's out of charges. ")
playsound(src, 'sound/effects/light_flicker.ogg', 100, 1)
+/obj/item/card/emag/examine(mob/user)
+ . = ..()
+ to_chat(user, "It has [uses ? uses : "no"] charges left. ")
+
+/obj/item/card/emag/attackby(obj/item/W, mob/user, params)
+ if(istype(W, /obj/item/emagrecharge))
+ var/obj/item/emagrecharge/ER = W
+ if(ER.uses)
+ uses += ER.uses
+ to_chat(user, "You have added [ER.uses] charges to [src]. It now has [uses] charges. ")
+ playsound(src, "sparks", 100, 1)
+ ER.uses = 0
+ else
+ to_chat(user, "[ER] has no charges left. ")
+ return
+ . = ..()
+
+/obj/item/emagrecharge
+ name = "electromagnet charging device"
+ desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell."
+ icon = 'icons/obj/module.dmi'
+ icon_state = "cell_mini"
+ item_flags = NOBLUDGEON
+ var/uses = 5 //Dictates how many charges the device adds to compatible items
+
+/obj/item/emagrecharge/examine(mob/user)
+ . = ..()
+ if(uses)
+ to_chat(user, "It can add up to [uses] charges to compatible devices ")
+ else
+ to_chat(user, "It has a small, red, blinking light coming from inside of it. It's spent. ")
/obj/item/card/emagfake
desc = "It's a card with a magnetic strip attached to some circuitry. Closer inspection shows that this card is a poorly made replica, with a \"DonkCo\" logo stamped on the back."
@@ -342,12 +374,41 @@ update_label("John Doe", "Clowny")
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
assignment = "Prisoner"
- registered_name = "Scum"
+ access = list(ACCESS_ENTER_GENPOP)
+
+ //Lavaland labor camp
var/goal = 0 //How far from freedom?
var/points = 0
+ //Genpop
+ var/sentence = 0 //When world.time is greater than this number, the card will have its ACCESS_ENTER_GENPOP access replaced with ACCESS_LEAVE_GENPOP the next time it's checked, unless this value is 0/null
+ var/crime= "\[REDACTED\]"
-/obj/item/card/id/prisoner/attack_self(mob/user)
- to_chat(usr, "You have accumulated [points] out of the [goal] points you need for freedom. ")
+/obj/item/card/id/prisoner/GetAccess()
+ if((sentence && world.time >= sentence) || (goal && points >= goal))
+ access = list(ACCESS_LEAVE_GENPOP)
+ return ..()
+
+/obj/item/card/id/prisoner/process()
+ if(!sentence)
+ STOP_PROCESSING(SSobj, src)
+ return
+ if(world.time >= sentence)
+ playsound(loc, 'sound/machines/ping.ogg', 50, 1)
+ if(isliving(loc))
+ to_chat(loc, "[src] buzzes: You have served your sentence! You may now exit prison through the turnstiles and collect your belongings. ")
+ STOP_PROCESSING(SSobj, src)
+ return
+
+/obj/item/card/id/prisoner/examine(mob/user)
+ . = ..()
+ if(sentence && world.time < sentence)
+ to_chat(user, "You're currently serving a sentence for [crime]. [DisplayTimeText(sentence - world.time)] left. ")
+ else if(goal)
+ to_chat(user, "You have accumulated [points] out of the [goal] points you need for freedom. ")
+ else if(!sentence)
+ to_chat(user, "You are currently serving a permanent sentence for [crime]. ")
+ else
+ to_chat(user, "Your sentence is up! You're free! ")
/obj/item/card/id/prisoner/one
name = "Prisoner #13-001"
@@ -422,3 +483,58 @@ update_label("John Doe", "Clowny")
name = "APC Access ID"
desc = "A special ID card that allows access to APC terminals."
access = list(ACCESS_ENGINE_EQUIP)
+
+//Polychromatic Knight Badge
+
+/obj/item/card/id/knight
+ var/id_color = "#00FF00" //defaults to green
+ name = "knight badge"
+ icon_state = "knight"
+ desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID"
+
+/obj/item/card/id/knight/update_label(newname, newjob)
+ if(newname || newjob)
+ name = "[(!newname) ? "knight badge" : "[newname]'s Knight Badge"][(!newjob) ? "" : " ([newjob])"]"
+ return
+
+ name = "[(!registered_name) ? "knight badge" : "[registered_name]'s Knight Badge"][(!assignment) ? "" : " ([assignment])"]"
+
+/obj/item/card/id/knight/update_icon()
+ var/mutable_appearance/id_overlay = mutable_appearance(icon, "knight_overlay")
+
+ if(id_color)
+ id_overlay.color = id_color
+ cut_overlays()
+
+ add_overlay(id_overlay)
+
+/obj/item/card/id/knight/AltClick(mob/living/user)
+ . = ..()
+ if(!in_range(src, user)) //Basic checks to prevent abuse
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now! ")
+ return
+ if(alert("Are you sure you want to recolor your id?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",id_color) as color|null
+ if(!in_range(src, user) || !energy_color_input)
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now! ")
+ return
+ id_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+
+/obj/item/card/id/knight/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/card/id/knight/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to recolor it. ")
+
+/obj/item/card/id/knight/blue
+ id_color = "#0000FF"
+
+/obj/item/card/id/knight/captain
+ id_color = "#FFD700"
\ No newline at end of file
diff --git a/code/game/objects/items/chrono_eraser.dm b/code/game/objects/items/chrono_eraser.dm
index 5db5aa416e..911a07c288 100644
--- a/code/game/objects/items/chrono_eraser.dm
+++ b/code/game/objects/items/chrono_eraser.dm
@@ -37,7 +37,7 @@
PA = new(src)
user.put_in_hands(PA)
-/obj/item/chrono_eraser/item_action_slot_check(slot, mob/user)
+/obj/item/chrono_eraser/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_BACK)
return 1
diff --git a/code/game/objects/items/cigs_lighters.dm b/code/game/objects/items/cigs_lighters.dm
index 09a128c558..cf8d38d9c9 100644
--- a/code/game/objects/items/cigs_lighters.dm
+++ b/code/game/objects/items/cigs_lighters.dm
@@ -90,7 +90,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
if(istype(mask_item, /obj/item/clothing/mask/cigarette))
return mask_item
-/obj/item/match/is_hot()
+/obj/item/match/get_temperature()
return lit * heat
//////////////////
@@ -255,7 +255,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/clothing/mask/cigarette/fire_act(exposed_temperature, exposed_volume)
light()
-/obj/item/clothing/mask/cigarette/is_hot()
+/obj/item/clothing/mask/cigarette/get_temperature()
return lit * heat
// Cigarette brands.
@@ -530,7 +530,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
add_overlay(lighter_overlay)
/obj/item/lighter/ignition_effect(atom/A, mob/user)
- if(is_hot())
+ if(get_temperature())
. = "With a single flick of [user.p_their()] wrist, [user] smoothly lights [A] with [src]. Damn [user.p_theyre()] cool. "
/obj/item/lighter/proc/set_lit(new_lit)
@@ -605,7 +605,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
/obj/item/lighter/process()
open_flame()
-/obj/item/lighter/is_hot()
+/obj/item/lighter/get_temperature()
return lit * heat
@@ -654,7 +654,7 @@ CIGARETTE PACKETS ARE IN FANCY.DM
add_overlay(lighter_overlay)
/obj/item/lighter/greyscale/ignition_effect(atom/A, mob/user)
- if(is_hot())
+ if(get_temperature())
. = "After some fiddling, [user] manages to light [A] with [src]. "
diff --git a/code/game/objects/items/circuitboards/computer_circuitboards.dm b/code/game/objects/items/circuitboards/computer_circuitboards.dm
index c260a95afd..ac7879f9ec 100644
--- a/code/game/objects/items/circuitboards/computer_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/computer_circuitboards.dm
@@ -59,7 +59,7 @@
name = "Department Management Console (Computer Board)"
build_path = /obj/machinery/computer/card/minor
var/target_dept = 1
- var/list/dept_list = list("General","Security","Medical","Science","Engineering")
+ var/list/dept_list = list("Civilian","Security","Medical","Science","Engineering","Cargo")
/obj/item/circuitboard/computer/card/minor/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/screwdriver))
diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm
index 2a01a7e18f..1059a310eb 100644
--- a/code/game/objects/items/circuitboards/machine_circuitboards.dm
+++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm
@@ -31,6 +31,15 @@
/obj/item/stock_parts/manipulator = 1,
/obj/item/stack/sheet/glass = 1)
+/obj/item/circuitboard/machine/bloodbankgen
+ name = "Blood Bank Generator (Machine Board)"
+ build_path = /obj/machinery/bloodbankgen
+ req_components = list(
+ /obj/item/stock_parts/matter_bin = 1,
+ /obj/item/stock_parts/manipulator = 1,
+ /obj/item/stack/cable_coil = 5,
+ /obj/item/stack/sheet/glass = 1)
+
/obj/item/circuitboard/machine/clonepod
name = "Clone Pod (Machine Board)"
build_path = /obj/machinery/clonepod
@@ -399,6 +408,7 @@
/obj/machinery/smartfridge/food = "food",
/obj/machinery/smartfridge/drinks = "drinks",
/obj/machinery/smartfridge/extract = "slimes",
+ /obj/machinery/smartfridge/organ = "organs",
/obj/machinery/smartfridge/chemistry = "chems",
/obj/machinery/smartfridge/chemistry/virology = "viruses",
/obj/machinery/smartfridge/disks = "disks")
diff --git a/code/game/objects/items/control_wand.dm b/code/game/objects/items/control_wand.dm
index fa4524528b..c98484b81e 100644
--- a/code/game/objects/items/control_wand.dm
+++ b/code/game/objects/items/control_wand.dm
@@ -33,7 +33,7 @@
// Airlock remote works by sending NTNet packets to whatever it's pointed at.
/obj/item/door_remote/afterattack(atom/A, mob/user)
. = ..()
- GET_COMPONENT_FROM(target_interface, /datum/component/ntnet_interface, A)
+ var/datum/component/ntnet_interface/target_interface = A.GetComponent(/datum/component/ntnet_interface)
if(!target_interface)
return
diff --git a/code/game/objects/items/crayons.dm b/code/game/objects/items/crayons.dm
index db26f643b5..d014f70315 100644
--- a/code/game/objects/items/crayons.dm
+++ b/code/game/objects/items/crayons.dm
@@ -234,8 +234,13 @@
paint_mode = PAINT_NORMAL
if("select_colour")
if(can_change_colour)
- paint_color = input(usr,"","Choose Color",paint_color) as color|null
- . = TRUE
+ var/chosen_colour = input(usr,"","Choose Color",paint_color) as color|null
+
+ if (!isnull(chosen_colour))
+ paint_color = chosen_colour
+ . = TRUE
+ else
+ . = FALSE
if("enter_text")
var/txt = stripped_input(usr,"Choose what to write.",
"Scribbles",default = text_buffer)
@@ -298,9 +303,10 @@
drawing = pick(all_drawables)
var/temp = "rune"
- if(is_alpha(drawing))
+ var/ascii = (length(drawing) == 1) ? TRUE : FALSE
+ if(ascii && is_alpha(drawing))
temp = "letter"
- else if(is_digit(drawing))
+ else if(ascii && is_digit(drawing))
temp = "number"
else if(drawing in punctuation)
temp = "punctuation mark"
@@ -555,7 +561,7 @@
/obj/item/storage/crayons/Initialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 7
STR.can_hold = typecacheof(list(/obj/item/toy/crayon))
@@ -703,12 +709,18 @@
if(isobj(target))
if(actually_paints)
+ if(color_hex2num(paint_color) < 350 && !istype(target, /obj/structure/window) && !istype(target, /obj/effect/decal/cleanable/crayon)) //Colors too dark are rejected
+ to_chat(usr, "A color that dark on an object like this? Surely not... ")
+ return FALSE
+
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
+
if(istype(target, /obj/structure/window))
if(color_hex2num(paint_color) < 255)
target.set_opacity(255)
else
target.set_opacity(initial(target.opacity))
+
. = use_charges(user, 2)
var/fraction = min(1, . / reagents.maximum_volume)
reagents.reaction(target, TOUCH, fraction * volume_multiplier)
@@ -819,6 +831,11 @@
if(user.mind && user.mind.has_antag_datum(/datum/antagonist/gang) || isobserver(user))
to_chat(user, "This spraycan has been specially modified with a stage 2 nozzle kit, making it faster.")
+/obj/item/toy/crayon/spraycan/infinite
+ name = "infinite spraycan"
+ charges = -1
+ desc = "Now with 30% more bluespace technology."
+
#undef RANDOM_GRAFFITI
#undef RANDOM_LETTER
#undef RANDOM_PUNCTUATION
diff --git a/code/game/objects/items/defib.dm b/code/game/objects/items/defib.dm
index 5bef86c6d2..f5799e1a22 100644
--- a/code/game/objects/items/defib.dm
+++ b/code/game/objects/items/defib.dm
@@ -39,7 +39,6 @@
/obj/item/defibrillator/loaded/Initialize() //starts with hicap
. = ..()
- paddles = make_paddles()
cell = new(src)
update_icon()
return
@@ -193,7 +192,7 @@
remove_paddles(user)
update_icon()
-/obj/item/defibrillator/item_action_slot_check(slot, mob/user)
+/obj/item/defibrillator/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == user.getBackSlot())
return 1
@@ -208,8 +207,8 @@
var/M = get(paddles, /mob)
remove_paddles(M)
QDEL_NULL(paddles)
- . = ..()
- update_icon()
+ QDEL_NULL(cell)
+ return ..()
/obj/item/defibrillator/proc/deductcharge(chrgdeductamt)
if(cell)
@@ -244,13 +243,12 @@
w_class = WEIGHT_CLASS_NORMAL
slot_flags = ITEM_SLOT_BELT
-/obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user)
+/obj/item/defibrillator/compact/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == user.getBeltSlot())
return TRUE
/obj/item/defibrillator/compact/loaded/Initialize()
. = ..()
- paddles = make_paddles()
cell = new(src)
update_icon()
@@ -262,7 +260,6 @@
/obj/item/defibrillator/compact/combat/loaded/Initialize()
. = ..()
- paddles = make_paddles()
cell = new /obj/item/stock_parts/cell/infinite(src)
update_icon()
@@ -297,31 +294,28 @@
var/grab_ghost = FALSE
var/tlimit = DEFIB_TIME_LIMIT * 10
- var/datum/component/mobhook
+ var/mob/listeningTo
/obj/item/twohanded/shockpaddles/equipped(mob/user, slot)
. = ..()
- if(req_defib)
- if (mobhook && mobhook.parent != user)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/check_range)))
+ if(!req_defib)
+ return
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/check_range)
/obj/item/twohanded/shockpaddles/Moved()
. = ..()
check_range()
/obj/item/twohanded/shockpaddles/proc/check_range()
- if(!req_defib)
+ if(!req_defib || !defib)
return
if(!in_range(src,defib))
var/mob/living/L = loc
if(istype(L))
to_chat(L, "[defib]'s paddles overextend and come out of your hands! ")
- L.temporarilyRemoveItemFromInventory(src,TRUE)
else
visible_message("[src] snap back into [defib]. ")
- snap_back()
+ snap_back()
/obj/item/twohanded/shockpaddles/proc/recharge(var/time)
if(req_defib || !time)
@@ -362,14 +356,14 @@
/obj/item/twohanded/shockpaddles/dropped(mob/user)
if(!req_defib)
return ..()
- if (mobhook)
- QDEL_NULL(mobhook)
if(user)
+ UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
var/obj/item/twohanded/offhand/O = user.get_inactive_held_item()
if(istype(O))
O.unwield()
- to_chat(user, "The paddles snap back into the main unit. ")
- snap_back()
+ if(user != loc)
+ to_chat(user, "The paddles snap back into the main unit. ")
+ snap_back()
return unwield(user)
/obj/item/twohanded/shockpaddles/proc/snap_back()
@@ -440,9 +434,20 @@
do_help(H, user)
-/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H)
+/obj/item/twohanded/shockpaddles/proc/can_defib(mob/living/carbon/H) //Our code here is different than tg, if it breaks in testing; BUG_PROBABLE_CAUSE
+ var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
+ if(H.suiciding || H.hellbound || HAS_TRAIT(H, TRAIT_HUSK))
+ return
+ if((world.time - H.timeofdeath) > tlimit)
+ return
+ if((H.getBruteLoss() >= MAX_REVIVE_BRUTE_DAMAGE) || (H.getFireLoss() >= MAX_REVIVE_FIRE_DAMAGE))
+ return
+ if(!heart || (heart.organ_flags & ORGAN_FAILING))
+ return
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
- return (!H.suiciding && !(HAS_TRAIT(H, TRAIT_NOCLONE)) && !H.hellbound && ((world.time - H.timeofdeath) < tlimit) && (H.getBruteLoss() < 180) && (H.getFireLoss() < 180) && H.getorgan(/obj/item/organ/heart) && BR && !BR.damaged_brain)
+ if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || H.suiciding)
+ return
+ return TRUE
/obj/item/twohanded/shockpaddles/proc/shock_touching(dmg, mob/H)
if(req_defib)
@@ -557,14 +562,12 @@
if(do_after(user, primetimer, target = H)) //beginning to place the paddles on patient's chest to allow some time for people to move away to stop the process
user.visible_message("[user] places [src] on [H]'s chest. ", "You place [src] on [H]'s chest. ")
playsound(src, 'sound/machines/defib_charge.ogg', 75, 0)
- var/tplus = world.time - H.timeofdeath
- // past this much time the patient is unrecoverable
- // (in deciseconds)
- // brain damage starts setting in on the patient after
- // some time left rotting
+ // patients rot when they are killed, and die when they are dead
+ var/tplus = world.time - H.timeofdeath //length of time spent dead
var/tloss = deathtimer
var/total_burn = 0
var/total_brute = 0
+ var/obj/item/organ/heart = H.getorgan(/obj/item/organ/heart)
if(do_after(user, primetimer2, target = H)) //placed on chest and short delay to shock for dramatic effect, revive time is 5sec total
for(var/obj/item/carried_item in H.contents)
if(istype(carried_item, /obj/item/clothing/suit/space))
@@ -589,16 +592,26 @@
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's soul appears to be on another plane of existence. Further attempts futile. "
else if (tplus > tlimit)
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Body has decayed for too long. Further attempts futile. "
- else if (!H.getorgan(/obj/item/organ/heart))
+ else if (!heart)
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart is missing. "
+ else if (heart.organ_flags & ORGAN_FAILING)
+ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's heart too damaged. "
else if(total_burn >= 180 || total_brute >= 180)
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile. "
else if(H.get_ghost())
failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful. "
else
var/obj/item/organ/brain/BR = H.getorgan(/obj/item/organ/brain)
- if(!BR || BR.damaged_brain)
- failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing or damaged beyond point of no return. Further attempts futile. "
+ if(BR) //BUG_PROBABLE_CAUSE - slight difference between us and tg
+ if(BR.organ_flags & ORGAN_FAILING)
+ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain tissue is damaged making recovery of patient impossible via defibrillator. Further attempts futile. "
+ if(BR.brain_death)
+ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain damaged beyond point of no return. Further attempts futile. "
+ if(H.suiciding || BR.brainmob?.suiciding)
+ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - No intelligence pattern can be detected in patient's brain. Further attempts futile. "
+ else
+ failed = "[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed - Patient's brain is missing. Further attempts futile. "
+
if(failed)
user.visible_message(failed)
@@ -623,7 +636,7 @@
H.Jitter(100)
SEND_SIGNAL(H, COMSIG_LIVING_MINOR_SHOCK)
if(tplus > tloss)
- H.adjustBrainLoss( max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, max(0, min(99, ((tlimit - tplus) / tlimit * 100))), 150)
log_combat(user, H, "revived", defib)
if(req_defib)
if(defib.healdisk)
@@ -641,7 +654,11 @@
playsound(src, 'sound/machines/defib_failed.ogg', 50, 0)
else if(H.undergoing_cardiac_arrest())
H.set_heartattack(FALSE)
- user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again. ")
+ if(!(heart.organ_flags & ORGAN_FAILING))
+ H.set_heartattack(FALSE)
+ user.visible_message("[req_defib ? "[defib]" : "[src]"] pings: Patient's heart is now beating again. ")
+ else
+ user.visible_message("[req_defib ? "[defib]" : "[src]"] buzzes: Resuscitation failed, heart damage detected. ")
playsound(src, 'sound/machines/defib_zap.ogg', 50, 1, -1)
diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm
index b0494539ce..92d936e0d4 100644
--- a/code/game/objects/items/devices/PDA/PDA.dm
+++ b/code/game/objects/items/devices/PDA/PDA.dm
@@ -274,7 +274,7 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += text("[id ? "Update PDA Info" : ""] ")
dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss")] " //:[world.time / 100 % 6][world.time / 100 % 10]"
- dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer+540]"
+ dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]"
dat += " "
diff --git a/code/game/objects/items/devices/PDA/virus_cart.dm b/code/game/objects/items/devices/PDA/virus_cart.dm
index d85c5d72d8..28bc559b93 100644
--- a/code/game/objects/items/devices/PDA/virus_cart.dm
+++ b/code/game/objects/items/devices/PDA/virus_cart.dm
@@ -70,7 +70,7 @@
difficulty++ //if cartridge has manifest access it has extra snowflake difficulty
else
difficulty += 2
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, target)
+ var/datum/component/uplink/hidden_uplink = target.GetComponent(/datum/component/uplink)
if(!target.detonatable || prob(difficulty * 15) || (hidden_uplink))
U.show_message("An error flashes on your [src]. ", 1)
else
@@ -95,7 +95,7 @@
charges--
var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
to_chat(U, "Virus Sent! The unlock code to the target is: [lock_code] ")
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, target)
+ var/datum/component/uplink/hidden_uplink = target.GetComponent(/datum/component/uplink)
if(!hidden_uplink)
hidden_uplink = target.AddComponent(/datum/component/uplink)
hidden_uplink.unlock_code = lock_code
diff --git a/code/game/objects/items/devices/aicard.dm b/code/game/objects/items/devices/aicard.dm
index 679dbecd10..7c21ac9144 100644
--- a/code/game/objects/items/devices/aicard.dm
+++ b/code/game/objects/items/devices/aicard.dm
@@ -17,6 +17,11 @@
desc = "A stylish upgrade (?) to the intelliCard."
icon_state = "aitater"
+/obj/item/aicard/aispook
+ name = "intelliLantern"
+ desc = "A spoOoOoky upgrade to the intelliCard."
+ icon_state = "aispook"
+
/obj/item/aicard/suicide_act(mob/living/user)
user.visible_message("[user] is trying to upload [user.p_them()]self into [src]! That's not going to work out well! ")
return BRUTELOSS
@@ -26,16 +31,18 @@
if(!proximity || !target)
return
if(AI) //AI is on the card, implies user wants to upload it.
- target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
log_combat(user, AI, "carded", src)
+ target.transfer_ai(AI_TRANS_FROM_CARD, user, AI, src)
else //No AI on the card, therefore the user wants to download one.
target.transfer_ai(AI_TRANS_TO_CARD, user, null, src)
+ if(AI)
+ log_combat(user, AI, "carded", src)
update_icon() //Whatever happened, update the card's state (icon, name) to match.
/obj/item/aicard/update_icon()
cut_overlays()
if(AI)
- name = "[initial(name)]- [AI.name]"
+ name = "[initial(name)] - [AI.name]"
if(AI.stat == DEAD)
icon_state = "[initial(icon_state)]-404"
else
diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm
index f39d2ba0d6..dffbb46cbb 100644
--- a/code/game/objects/items/devices/chameleonproj.dm
+++ b/code/game/objects/items/devices/chameleonproj.dm
@@ -116,7 +116,7 @@
appearance = saved_appearance
if(istype(M.buckled, /obj/vehicle))
var/obj/vehicle/V = M.buckled
- GET_COMPONENT_FROM(VRD, /datum/component/riding, V)
+ var/datum/component/riding/VRD = V.GetComponent(/datum/component/riding)
if(VRD)
VRD.force_dismount(M)
else
diff --git a/code/game/objects/items/devices/compressionkit.dm b/code/game/objects/items/devices/compressionkit.dm
index 5ac958328d..a5a9377690 100644
--- a/code/game/objects/items/devices/compressionkit.dm
+++ b/code/game/objects/items/devices/compressionkit.dm
@@ -89,30 +89,23 @@
else
to_chat(user, "Anomalous error. Summon a coder. ")
- if(istype(target, /mob/living))
- var/mob/living/victim = target
- if(istype(victim, /mob/living/carbon/human))
- if(user.zone_selected == "groin") // pp smol. There's probably a smarter way to do this but im retarded. If you have a simpler method let me know.
- var/list/organs = victim.getorganszone("groin")
- for(var/internal_organ in organs)
- if(istype(internal_organ, /obj/item/organ/genital/penis))
- var/obj/item/organ/genital/penis/O = internal_organ
- playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
- victim.visible_message("[user] is preparing to shrink [victim]\'s [O.name] with their bluespace compression kit! ")
- if(do_mob(user, victim, 40) && charges > 0 && O.length > 0)
- victim.visible_message("[user] has shrunk [victim]\'s [O.name]! ")
- playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
- sparks()
- flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
- charges -= 1
- O.length -= 5
- if(O.length < 1)
- victim.visible_message("[user]\'s [O.name] vanishes! ")
- qdel(O) // no pp for you
- else
- O.update_size()
- O.update_appearance()
-
+ else if(ishuman(target) && user.zone_selected == BODY_ZONE_PRECISE_GROIN)
+ var/mob/living/carbon/human/H = target
+ var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
+ if(!P)
+ return
+ playsound(get_turf(src), 'sound/weapons/flash.ogg', 50, 1)
+ H.visible_message("[user] is preparing to shrink [H]\'s [P.name] with their bluespace compression kit! ")
+ if(do_mob(user, H, 40) && charges > 0 && P.length > 0)
+ H.visible_message("[user] has shrunk [H]\'s [P.name]! ")
+ playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 50, 1)
+ sparks()
+ flash_lighting_fx(3, 3, LIGHT_COLOR_CYAN)
+ charges -= 1
+ var/p_name = P.name
+ P.modify_size(-5)
+ if(QDELETED(P))
+ H.visible_message("[H]\'s [p_name] vanishes! ")
/obj/item/compressionkit/attackby(obj/item/I, mob/user, params)
diff --git a/code/game/objects/items/devices/dogborg_sleeper.dm b/code/game/objects/items/devices/dogborg_sleeper.dm
index 7f3c7f3bfc..3c945f464e 100644
--- a/code/game/objects/items/devices/dogborg_sleeper.dm
+++ b/code/game/objects/items/devices/dogborg_sleeper.dm
@@ -6,8 +6,7 @@
icon = 'icons/mob/dogborg.dmi'
icon_state = "sleeper"
w_class = WEIGHT_CLASS_TINY
- var/mob/living/carbon/patient = null
- var/mob/living/silicon/robot/hound = null
+ var/mob/living/carbon/patient
var/inject_amount = 10
var/min_health = -100
var/cleaning = FALSE
@@ -61,8 +60,18 @@
/obj/item/dogborg/sleeper/Exit(atom/movable/O)
return 0
+/obj/item/dogborg/sleeper/proc/get_host()
+ if(!loc)
+ return
+ if(iscyborg(loc))
+ return loc
+ else if(iscyborg(loc.loc))
+ return loc.loc //cursed cyborg code
+
/obj/item/dogborg/sleeper/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity)
- hound = loc
+ var/mob/living/silicon/robot/hound = get_host()
+ if(!hound)
+ return
if(!proximity)
return
if(!iscarbon(target))
@@ -82,7 +91,8 @@
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
return //If they moved away, you can't eat them.
- if(patient) return //If you try to eat two people at once, you can only eat one.
+ if(patient)
+ return //If you try to eat two people at once, you can only eat one.
else //If you don't have someone in you, proceed.
if(!isjellyperson(target) && ("toxin" in injection_chems))
@@ -94,14 +104,17 @@
target.forceMove(src)
target.reset_perspective(src)
target.ExtinguishMob() //The tongue already puts out fire stacks but being put into the sleeper shouldn't allow you to keep burning.
- update_gut()
+ update_gut(hound)
user.visible_message("[voracious ? "[hound]'s [src.name] lights up and expands as [target] slips inside into their [src.name]." : "[hound]'s sleeper indicator lights up as [target] is scooped up into [hound.p_their()] [src]."] ", \
"Your [voracious ? "[src.name] lights up as [target] slips into" : "sleeper indicator light shines brightly as [target] is scooped inside"] your [src]. Life support functions engaged. ")
message_admins("[key_name(hound)] has sleeper'd [key_name(patient)] as a dogborg. [ADMIN_JMP(src)]")
playsound(hound, 'sound/effects/bin_close.ogg', 100, 1)
/obj/item/dogborg/sleeper/container_resist(mob/living/user)
- hound = loc
+ var/mob/living/silicon/robot/hound = get_host()
+ if(!hound)
+ go_out(user)
+ return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
if(user.a_intent == INTENT_HELP)
@@ -113,55 +126,41 @@
"[voracious ? "You start struggling inside of [src]'s tight, flexible confines," : "You start pounding against the metallic walls of [src],"] trying to trigger the release... (this will take about [DisplayTimeText(breakout_time)].) ", \
"You hear a [voracious ? "couple of thumps" : "loud banging noise"] coming from within [hound]. ")
if(do_after(user, breakout_time, target = src))
- if(!user || user.stat != CONSCIOUS || user.loc != src )
- return
user.visible_message("[user] successfully broke out of [hound.name]! ", \
"You successfully break out of [hound.name]! ")
- go_out()
+ go_out(user, hound)
-/obj/item/dogborg/sleeper/proc/go_out(var/target)
- hound = loc
- hound.setClickCooldown(50)
- var/voracious = TRUE
- if(!hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
- voracious = FALSE
- else
- for(var/mob/M in contents)
- if(!M.client || !(M.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
- voracious = FALSE
- if(length(contents) > 0)
- hound.visible_message("[voracious ? "[hound] empties out [hound.p_their()] contents via [hound.p_their()] release port." : "[hound]'s underside slides open with an audible clunk before [hound.p_their()] [src] flips over, carelessly dumping its contents onto the ground below [hound.p_them()] before closing right back up again."] ", \
- "[voracious ? "You empty your contents via your release port." : "You open your sleeper hatch, quickly releasing all of the contents within before closing it again."] ")
- if(target)
- if(iscarbon(target))
- var/mob/living/carbon/person = target
- person.forceMove(get_turf(src))
- person.reset_perspective()
- else
- var/obj/T = target
- T.loc = hound.loc
+/obj/item/dogborg/sleeper/proc/go_out(atom/movable/target, mob/living/silicon/robot/hound)
+ var/voracious = hound ? TRUE : FALSE
+ var/list/targets = target && hound ? list(target) : contents
+ if(hound)
+ hound.setClickCooldown(50)
+ if(!hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
+ voracious = FALSE
else
- for(var/C in contents)
- if(iscarbon(C))
- var/mob/living/carbon/person = C
- person.forceMove(get_turf(src))
- person.reset_perspective()
- else
- var/obj/T = C
- T.loc = hound.loc
- items_preserved.Cut()
- update_gut()
- cleaning = FALSE
+ for(var/mob/M in targets)
+ if(!M.client || !(M.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
+ voracious = FALSE
+ if(length(targets))
+ if(hound)
+ hound.visible_message("[voracious ? "[hound] empties out [hound.p_their()] contents via [hound.p_their()] release port." : "[hound]'s underside slides open with an audible clunk before [hound.p_their()] [src] flips over, carelessly dumping its contents onto the ground below [hound.p_them()] before closing right back up again."] ", \
+ "[voracious ? "You empty your contents via your release port." : "You open your sleeper hatch, quickly releasing all of the contents within before closing it again."] ")
+ for(var/a in contents)
+ var/atom/movable/AM = a
+ AM.forceMove(get_turf(src))
+ if(ismob(AM))
+ var/mob/M = AM
+ M.reset_perspective()
playsound(loc, voracious ? 'sound/effects/splat.ogg' : 'sound/effects/bin_close.ogg', 50, 1)
-
- else //You clicked eject with nothing in you, let's just reset stuff to be sure.
- items_preserved.Cut()
- cleaning = FALSE
- update_gut()
+ items_preserved.Cut()
+ cleaning = FALSE
+ if(hound)
+ update_gut(hound)
/obj/item/dogborg/sleeper/attack_self(mob/user)
- if(..())
+ . = ..()
+ if(. || !iscyborg(user))
return
ui_interact(user)
@@ -211,7 +210,7 @@
data["occupant"]["toxLoss"] = mob_occupant.getToxLoss()
data["occupant"]["fireLoss"] = mob_occupant.getFireLoss()
data["occupant"]["cloneLoss"] = mob_occupant.getCloneLoss()
- data["occupant"]["brainLoss"] = mob_occupant.getBrainLoss()
+ data["occupant"]["brainLoss"] = mob_occupant.getOrganLoss(ORGAN_SLOT_BRAIN)
data["occupant"]["reagents"] = list()
if(mob_occupant.reagents.reagent_list.len)
for(var/datum/reagent/R in mob_occupant.reagents.reagent_list)
@@ -219,30 +218,31 @@
return data
/obj/item/dogborg/sleeper/ui_act(action, params)
- if(..())
+ . = ..()
+ if(. || !iscyborg(usr))
return
switch(action)
if("eject")
- go_out()
+ go_out(null, usr)
. = TRUE
if("inject")
var/chem = params["chem"]
if(!patient)
return
- inject_chem(chem)
+ inject_chem(chem, usr)
. = TRUE
if("cleaning")
if(!contents)
to_chat(src, "Your [src] is already cleaned.")
return
if(patient)
- to_chat(patient, "[hound.name]'s [src] fills with caustic enzymes around you! ")
+ to_chat(patient, "[usr.name]'s [src] fills with caustic enzymes around you! ")
to_chat(src, "Cleaning process enabled. ")
- clean_cycle()
+ clean_cycle(usr)
. = TRUE
-/obj/item/dogborg/sleeper/proc/update_gut()
+/obj/item/dogborg/sleeper/proc/update_gut(mob/living/silicon/robot/hound)
//Well, we HAD one, what happened to them?
var/prociconupdate = FALSE
var/currentenvy = hound.sleeper_nv
@@ -291,7 +291,7 @@
//Update icon and return new patient
hound.update_icons()
- return(C)
+ return
//Cleaning looks better with red on, even with nobody in it
if(cleaning && !patient)
@@ -307,8 +307,10 @@
hound.update_icons()
//Gurgleborg process
-/obj/item/dogborg/sleeper/proc/clean_cycle()
+/obj/item/dogborg/sleeper/proc/clean_cycle(mob/living/silicon/robot/hound)
//Sanity
+ if(!hound)
+ return
for(var/I in items_preserved)
if(!(I in contents))
items_preserved -= I
@@ -320,13 +322,12 @@
if(cleaning_cycles)
cleaning_cycles--
cleaning = TRUE
- for(var/mob/living/carbon/human/T in (touchable_items))
- if((T.status_flags & GODMODE) || !T.digestable)
- items_preserved += T
+ for(var/mob/living/carbon/C in (touchable_items))
+ if((C.status_flags & GODMODE) || !C.digestable)
+ items_preserved += C
else
- T.adjustBruteLoss(2)
- T.adjustFireLoss(3)
- update_gut()
+ C.adjustBruteLoss(2)
+ C.adjustFireLoss(3)
if(contents)
var/atom/target = pick(touchable_items)
if(iscarbon(target)) //Handle the target being a mob
@@ -359,7 +360,6 @@
if(!T.dropItemToGround(W))
qdel(W)
qdel(T)
- update_gut()
//Handle the target being anything but a mob
else if(isobj(target))
var/obj/T = target
@@ -374,12 +374,10 @@
cleaning_cycles = initial(cleaning_cycles)
cleaning = FALSE
to_chat(hound, "Your [src] chimes it ends its self-cleaning cycle. ")//Belly is entirely empty
- update_gut()
if(!length(contents))
to_chat(hound, "Your [src] is now clean. Ending self-cleaning cycle. ")
cleaning = FALSE
- update_gut()
//sound effects
if(prob(50))
@@ -397,13 +395,17 @@
else if(H in contents)
H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
+ update_gut(hound)
+
if(cleaning)
- addtimer(CALLBACK(src, .proc/clean_cycle), 50)
+ addtimer(CALLBACK(src, .proc/clean_cycle, hound), 50)
/obj/item/dogborg/sleeper/proc/CheckAccepted(obj/item/I)
return is_type_in_typecache(I, important_items)
-/obj/item/dogborg/sleeper/proc/inject_chem(chem)
+/obj/item/dogborg/sleeper/proc/inject_chem(chem, mob/living/silicon/robot/hound)
+ if(!hound)
+ return
if(hound.cell.charge <= 800) //This is so borgs don't kill themselves with it. Remember, 750 charge used every injection.
to_chat(hound, "You don't have enough power to synthesize fluids. ")
return
@@ -438,40 +440,27 @@
else
. = ..()
-/obj/item/dogborg/sleeper/K9/afterattack(var/atom/movable/target, mob/living/silicon/user, proximity)
- hound = loc
+/obj/item/dogborg/sleeper/K9/afterattack(mob/living/carbon/target, mob/living/silicon/user, proximity)
+ var/mob/living/silicon/robot/hound = get_host()
+ if(!hound || !istype(target) || !proximity || target.anchored)
+ return
+ if (!target.devourable)
+ to_chat(user, "The target registers an error code. Unable to insert into [src].")
+ return
+ if(target)
+ to_chat(user,"Your [src] is already occupied. ")
+ return
+ if(target.buckled)
+ to_chat(user,"[target] is buckled and can not be put into your [src]. ")
+ return
+ user.visible_message("[hound.name] is ingesting [target] into their [src]. ", "You start ingesting [target] into your [src.name]... ")
+ if(do_after(user, 30, target = target) && !patient && !target.buckled)
+ target.forceMove(src)
+ target.reset_perspective(src)
+ update_gut(hound)
+ user.visible_message("[hound.name]'s mobile brig clunks in series as [target] slips inside. ", "Your mobile brig groans lightly as [target] slips inside. ")
+ playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
- if(!istype(target))
- return
- if(!proximity)
- return
- if(target.anchored)
- return
- if(isobj(target))
- to_chat(user, "You are above putting such trash inside of yourself.")
- return
- if(iscarbon(target))
- var/mob/living/carbon/brigman = target
- if (!brigman.devourable)
- to_chat(user, "The target registers an error code. Unable to insert into [src].")
- return
- if(patient)
- to_chat(user,"Your [src] is already occupied. ")
- return
- if(brigman.buckled)
- to_chat(user,"[brigman] is buckled and can not be put into your [src]. ")
- return
- user.visible_message("[hound.name] is ingesting [brigman] into their [src]. ", "You start ingesting [brigman] into your [src.name]... ")
- if(do_after(user, 30, target = brigman) && !patient && !brigman.buckled)
- if(!in_range(src, brigman)) //Proximity is probably old news by now, do a new check.
- return //If they moved away, you can't eat them.
- brigman.forceMove(src)
- brigman.reset_perspective(src)
- update_gut()
- user.visible_message("[hound.name]'s mobile brig clunks in series as [brigman] slips inside. ", "Your mobile brig groans lightly as [brigman] slips inside. ")
- playsound(hound, 'sound/effects/bin_close.ogg', 80, 1) // Really don't need ERP sound effects for robots
- return
- return
/obj/item/dogborg/sleeper/compactor //Janihound gut.
name = "garbage processor"
@@ -489,31 +478,25 @@
else
. = ..()
-/obj/item/dogborg/sleeper/compactor/afterattack(var/atom/movable/target, mob/living/silicon/user, proximity)//GARBO NOMS
- hound = loc
- var/obj/item/target_obj = target
- if(!istype(target))
- return
- if(!proximity)
- return
- if(target.anchored)
+/obj/item/dogborg/sleeper/compactor/afterattack(atom/movable/target, mob/living/silicon/user, proximity)//GARBO NOMS
+ var/mob/living/silicon/robot/hound = get_host()
+ if(!hound || !istype(target) || !proximity || target.anchored)
return
if(length(contents) > (max_item_count - 1))
to_chat(user,"Your [src] is full. Eject or process contents to continue. ")
return
- if(isobj(target))
- if(CheckAccepted(target))
- to_chat(user,"\The [target] registers an error code to your [src] ")
+ if(isitem(target))
+ var/obj/item/I = target
+ if(CheckAccepted(I))
+ to_chat(user,"[I] registers an error code to your [src] ")
return
- if(target_obj.w_class > WEIGHT_CLASS_NORMAL)
- to_chat(user,"\The [target] is too large to fit into your [src] ")
+ if(I.w_class > WEIGHT_CLASS_NORMAL)
+ to_chat(user,"[I] is too large to fit into your [src] ")
return
- user.visible_message("[hound.name] is ingesting [target.name] into their [src.name]. ", "You start ingesting [target] into your [src.name]... ")
+ user.visible_message("[hound.name] is ingesting [I] into their [src.name]. ", "You start ingesting [target] into your [src.name]... ")
if(do_after(user, 15, target = target) && length(contents) < max_item_count)
- if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
- return //If they moved away, you can't eat them. This still applies to items, don't magically eat things I picked up already.
- target.forceMove(src)
- user.visible_message("[hound.name]'s garbage processor groans lightly as [target.name] slips inside. ", "Your garbage compactor groans lightly as [target] slips inside. ")
+ I.forceMove(src)
+ I.visible_message("[hound.name]'s garbage processor groans lightly as [I] slips inside. ", "Your garbage compactor groans lightly as [I] slips inside. ")
playsound(hound, 'sound/machines/disposalflush.ogg', 50, 1)
if(length(contents) > 11) //grow that tum after a certain junk amount
hound.sleeper_r = 1
@@ -523,9 +506,9 @@
hound.update_icons()
return
- else if(iscarbon(target))
- var/mob/living/carbon/trashman = target
- if (!trashman.devourable)
+ if(iscarbon(target) || issilicon(target))
+ var/mob/living/trashman = target
+ if(!trashman.devourable)
to_chat(user, "[target] registers an error code to your [src] ")
return
if(patient)
@@ -536,12 +519,8 @@
return
user.visible_message("[hound.name] is ingesting [trashman] into their [src]. ", "You start ingesting [trashman] into your [src.name]... ")
if(do_after(user, 30, target = trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
- if(!in_range(src, trashman)) //Proximity is probably old news by now, do a new check.
- return //If they moved away, you can't eat them.
trashman.forceMove(src)
trashman.reset_perspective(src)
update_gut()
user.visible_message("[hound.name]'s garbage processor groans lightly as [trashman] slips inside. ", "Your garbage compactor groans lightly as [trashman] slips inside. ")
playsound(hound, 'sound/effects/bin_close.ogg', 80, 1)
- return
- return
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index 722510dccb..8d7fa05ec6 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -96,7 +96,7 @@
if(BODY_ZONE_PRECISE_MOUTH)
- if((M.head && M.head.flags_cover & HEADCOVERSMOUTH) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
+ if(M.is_mouth_covered())
to_chat(user, "You're going to need to remove that [(M.head && M.head.flags_cover & HEADCOVERSMOUTH) ? "helmet" : "mask"] first. ")
return
@@ -324,7 +324,7 @@
damtype = "fire"
START_PROCESSING(SSobj, src)
-/obj/item/flashlight/flare/is_hot()
+/obj/item/flashlight/flare/get_temperature()
return on * heat
/obj/item/flashlight/flare/torch
diff --git a/code/game/objects/items/devices/geiger_counter.dm b/code/game/objects/items/devices/geiger_counter.dm
index 38133e37bc..110676de1b 100644
--- a/code/game/objects/items/devices/geiger_counter.dm
+++ b/code/game/objects/items/devices/geiger_counter.dm
@@ -158,7 +158,7 @@
if(!M.radiation)
to_chat(user, "[icon2html(src, user)] Radiation levels within normal boundaries. ")
else
- to_chat(user, "[icon2html(src, user)] Subject is irradiated. Radiation levels: [M.radiation]. ")
+ to_chat(user, "[icon2html(src, user)] Subject is irradiated. Radiation levels: [M.radiation] rad. ")
if(rad_strength)
to_chat(user, "[icon2html(src, user)] Target contains radioactive contamination. Radioactive strength: [rad_strength] ")
@@ -203,21 +203,25 @@
return TRUE
/obj/item/geiger_counter/cyborg
- var/datum/component/mobhook
+ var/mob/listeningTo
/obj/item/geiger_counter/cyborg/equipped(mob/user)
. = ..()
- if (mobhook && mobhook.parent != user)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_ATOM_RAD_ACT = CALLBACK(src, .proc/redirect_rad_act)))
+ if(listeningTo == user)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
+ RegisterSignal(user, COMSIG_ATOM_RAD_ACT, .proc/redirect_rad_act)
+ listeningTo = user
/obj/item/geiger_counter/cyborg/proc/redirect_rad_act(datum/source, amount)
rad_act(amount)
/obj/item/geiger_counter/cyborg/dropped()
. = ..()
- QDEL_NULL(mobhook)
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_ATOM_RAD_ACT)
+ listeningTo = null
#undef RAD_LEVEL_NORMAL
#undef RAD_LEVEL_MODERATE
diff --git a/code/game/objects/items/devices/gps.dm b/code/game/objects/items/devices/gps.dm
index 637bb794d3..9d1b670e71 100644
--- a/code/game/objects/items/devices/gps.dm
+++ b/code/game/objects/items/devices/gps.dm
@@ -167,8 +167,19 @@ GLOBAL_LIST_EMPTY(GPS_list)
gpstag = "Eerie Signal"
desc = "Report to a coder immediately."
invisibility = INVISIBILITY_MAXIMUM
+ var/obj/item/implant/gps/implant
-/obj/item/gps/mining/internal
+/obj/item/gps/internal/Initialize(mapload, obj/item/implant/gps/_implant)
+ . = ..()
+ implant = _implant
+
+/obj/item/gps/internal/Destroy()
+ if(implant?.imp_in)
+ qdel(implant)
+ else
+ return ..()
+
+/obj/item/gps/internal/mining
icon_state = "gps-m"
gpstag = "MINER"
desc = "A positioning system helpful for rescuing trapped or injured miners, keeping one on you at all times while mining might just save your life."
diff --git a/code/game/objects/items/devices/multitool.dm b/code/game/objects/items/devices/multitool.dm
index 207497922e..cf55d4178e 100644
--- a/code/game/objects/items/devices/multitool.dm
+++ b/code/game/objects/items/devices/multitool.dm
@@ -48,7 +48,7 @@
/obj/item/multitool/chaplain/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/multitool/examine(mob/user)
..()
diff --git a/code/game/objects/items/devices/paicard.dm b/code/game/objects/items/devices/paicard.dm
index 1f69db1bbc..7dc2f1d60b 100644
--- a/code/game/objects/items/devices/paicard.dm
+++ b/code/game/objects/items/devices/paicard.dm
@@ -148,9 +148,11 @@
if(10)
src.add_overlay("pai-null")
if(11)
- src.add_overlay(mutable_appearance('modular_citadel/icons/obj/aicards.dmi', "pai-exclamation")) // CITADEL EDIT
+ src.add_overlay("pai-exclamation")
if(12)
- src.add_overlay(mutable_appearance('modular_citadel/icons/obj/aicards.dmi', "pai-question")) // CITADEL EDIT
+ src.add_overlay("pai-question")
+ if(13)
+ src.add_overlay("pai-sunglasses")
/obj/item/paicard/proc/alertUpdate()
visible_message("[src] flashes a message across its screen, \"Additional personalities available for download.\"", "[src] bleeps electronically. ")
diff --git a/code/game/objects/items/devices/radio/radio.dm b/code/game/objects/items/devices/radio/radio.dm
index 7c136f556e..926810cfbf 100644
--- a/code/game/objects/items/devices/radio/radio.dm
+++ b/code/game/objects/items/devices/radio/radio.dm
@@ -413,3 +413,16 @@
/obj/item/radio/off // Station bounced radios, their only difference is spawning with the speakers off, this was made to help the lag.
listening = 0 // And it's nice to have a subtype too for future features.
dog_fashion = /datum/dog_fashion/back
+
+/obj/item/radio/internal
+ var/obj/item/implant/radio/implant
+
+/obj/item/radio/internal/Initialize(mapload, obj/item/implant/radio/_implant)
+ . = ..()
+ implant = _implant
+
+/obj/item/radio/internal/Destroy()
+ if(implant?.imp_in)
+ qdel(implant)
+ else
+ return ..()
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 0059938720..5ad5b41e95 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -135,7 +135,7 @@ SLIME SCANNER
var/mob/living/carbon/human/H = M
if(H.undergoing_cardiac_arrest() && H.stat != DEAD)
to_chat(user, "Subject suffering from heart attack: Apply defibrillation or other electric shock immediately! ")
- if(H.undergoing_liver_failure() && H.stat != DEAD)
+ if(H.undergoing_liver_failure() && H.stat != DEAD) //might be depreciated BUG_PROBABLE_CAUSE
to_chat(user, "Subject is suffering from liver failure: Apply Corazone and begin a liver transplant immediately! ")
var/msg = "*---------*\nAnalyzing results for [M]:\n\tOverall status: [mob_status]\n"
@@ -157,12 +157,8 @@ SLIME SCANNER
msg += "\tSubject appears to have [M.getCloneLoss() > 30 ? "Severe" : "Minor"] cellular damage. \n"
if(advanced)
msg += "\tCellular Damage Level: [M.getCloneLoss()]. \n"
- if (M.getBrainLoss() >= 200 || !M.getorgan(/obj/item/organ/brain))
- msg += "\tSubject's brain function is non-existent. \n"
- else if (M.getBrainLoss() >= 120)
- msg += "\tSevere brain damage detected. Subject likely to have mental traumas. \n"
- else if (M.getBrainLoss() >= 45)
- msg += "\tBrain damage detected. \n"
+ if (!M.getorgan(/obj/item/organ/brain))
+ to_chat(user, "\tSubject lacks a brain. ") //Unsure how this won't proc for 50% of the cit playerbase (This is a joke everyone on cit a cute.)
if(ishuman(M) && advanced) // Should I make this not advanced?
var/mob/living/carbon/human/H = M
var/obj/item/organ/liver/L = H.getorganslot("liver")
@@ -194,6 +190,14 @@ SLIME SCANNER
if(Br.cached_size>5)
msg += "\tSubject has a sizeable bosom with a [Br.size] cup. \n"
+ if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 200 || !M.getorgan(/obj/item/organ/brain))
+ msg += "\tSubject's brain function is non-existent. \n"
+ else if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 120)
+ msg += "\tSevere brain damage detected. Subject likely to have mental traumas. \n"
+ else if (M.getOrganLoss(ORGAN_SLOT_BRAIN) >= 45)
+ msg += "\tBrain damage detected. \n"
+
+ if(iscarbon(M))
var/mob/living/carbon/C = M
if(LAZYLEN(C.get_traumas()))
var/list/trauma_text = list()
@@ -212,11 +216,10 @@ SLIME SCANNER
if(C.roundstart_quirks.len)
msg += "\tSubject has the following physiological traits: [C.get_trait_string()]. \n"
if(advanced)
- msg += "\tBrain Activity Level: [(200 - M.getBrainLoss())/2]%. \n"
+ msg += "\tBrain Activity Level: [(200 - M.getOrganLoss(ORGAN_SLOT_BRAIN))/2]%. \n"
if(M.radiation)
msg += "\tSubject is irradiated. \n"
- if(advanced)
- msg += "\tRadiation Level: [M.radiation]%. \n"
+ msg += "\tRadiation Level: [M.radiation] rad \n"
if(advanced && M.hallucinating())
msg += "\tSubject is hallucinating. \n"
@@ -247,11 +250,11 @@ SLIME SCANNER
healthy = FALSE
msg += "\tSubject is deaf. \n"
else
- if(ears.ear_damage)
- msg += "\tSubject has [ears.ear_damage > UNHEALING_EAR_DAMAGE? "permanent ": "temporary "]hearing damage. \n"
+ if(ears.damage)
+ to_chat(user, "\tSubject has [ears.damage > ears.maxHealth ? "permanent ": "temporary "]hearing damage. ")
healthy = FALSE
if(ears.deaf)
- msg += "\tSubject is [ears.ear_damage > UNHEALING_EAR_DAMAGE ? "permanently ": "temporarily "] deaf. \n"
+ to_chat(user, "\tSubject is [ears.damage > ears.maxHealth ? "permanently ": "temporarily "] deaf. ")
healthy = FALSE
if(healthy)
msg += "\tHealthy. \n"
@@ -267,13 +270,13 @@ SLIME SCANNER
if(HAS_TRAIT(C, TRAIT_NEARSIGHT))
msg += "\tSubject is nearsighted. \n"
healthy = FALSE
- if(eyes.eye_damage > 30)
+ if(eyes.damage > 30)
msg += "\tSubject has severe eye damage. \n"
healthy = FALSE
- else if(eyes.eye_damage > 20)
+ else if(eyes.damage > 20)
msg += "\tSubject has significant eye damage. \n"
healthy = FALSE
- else if(eyes.eye_damage)
+ else if(eyes.damage)
msg += "\tSubject has minor eye damage. \n"
healthy = FALSE
if(healthy)
@@ -297,6 +300,59 @@ SLIME SCANNER
for(var/obj/item/bodypart/org in damaged)
msg += "\t\t[capitalize(org.name)]: [(org.brute_dam > 0) ? "[org.brute_dam] " : "0 "]-[(org.burn_dam > 0) ? "[org.burn_dam] " : "0 "]\n"
+ //Organ damages report
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ var/minor_damage
+ var/major_damage
+ var/max_damage
+ var/report_organs = FALSE
+
+ //Piece together the lists to be reported
+ for(var/O in H.internal_organs)
+ var/obj/item/organ/organ = O
+ if(organ.organ_flags & ORGAN_FAILING)
+ report_organs = TRUE //if we report one organ, we report all organs, even if the lists are empty, just for consistency
+ if(max_damage)
+ max_damage += ", " //prelude the organ if we've already reported an organ
+ max_damage += organ.name //this just slaps the organ name into the string of text
+ else
+ max_damage = "\tNon-Functional Organs: " //our initial statement
+ max_damage += organ.name
+ else if(organ.damage > organ.high_threshold)
+ report_organs = TRUE
+ if(major_damage)
+ major_damage += ", "
+ major_damage += organ.name
+ else
+ major_damage = "\tSeverely Damaged Organs: "
+ major_damage += organ.name
+ else if(organ.damage > organ.low_threshold)
+ report_organs = TRUE
+ if(minor_damage)
+ minor_damage += ", "
+ minor_damage += organ.name
+ else
+ minor_damage = "\tMildly Damaged Organs: "
+ minor_damage += organ.name
+
+ if(report_organs) //we either finish the list, or set it to be empty if no organs were reported in that category
+ if(!max_damage)
+ max_damage = "\tNon-Functional Organs: \n"
+ else
+ max_damage += " \n"
+ if(!major_damage)
+ major_damage = "\tSeverely Damaged Organs: \n"
+ else
+ major_damage += " \n"
+ if(!minor_damage)
+ minor_damage = "\tMildly Damaged Organs: \n"
+ else
+ minor_damage += " \n"
+ msg += "[minor_damage]"
+ msg += "[major_damage]"
+ msg += "[max_damage]"
+
// Species and body temperature
if(ishuman(M))
@@ -326,10 +382,11 @@ SLIME SCANNER
else if (S.mutantstomach != initial(S.mutantstomach))
mutant = TRUE
- msg += "Species: [H.dna.custom_species ? H.dna.custom_species : S.name] Base: [S.name] \n"
+ msg += "\tReported Species: [H.dna.custom_species ? H.dna.custom_species : S.name] \n"
+ msg += "\tBase Species: [S.name] \n"
if(mutant)
- msg += "Subject has mutations present. "
- msg += "Body temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F) \n"
+ msg += "\tSubject has mutations present. \n"
+ msg += "\tBody temperature: [round(M.bodytemperature-T0C,0.1)] °C ([round(M.bodytemperature*1.8-459.67,0.1)] °F) \n"
// Time of death
if(M.tod && (M.stat == DEAD || ((HAS_TRAIT(M, TRAIT_FAKEDEATH)) && !advanced)))
@@ -354,7 +411,7 @@ SLIME SCANNER
msg += "Subject is bleeding! \n"
var/blood_percent = round((C.blood_volume / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100)
var/blood_type = C.dna.blood_type
- if(blood_id != "blood")//special blood substance
+ if(blood_id != ("blood" || "jellyblood"))//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
@@ -385,7 +442,7 @@ SLIME SCANNER
if(M.reagents.reagent_list.len)
var/list/datum/reagent/reagents = list()
for(var/datum/reagent/R in M.reagents.reagent_list)
- if(R.invisible)
+ if(R.chemical_flags & REAGENT_INVISIBLE)
continue
reagents += R
@@ -404,6 +461,21 @@ SLIME SCANNER
msg += "[R.name] \n"
else
msg += "Subject is not addicted to any reagents. \n"
+
+ if(M.reagents.has_reagent("fermiTox"))
+ var/datum/reagent/fermiTox = M.reagents.has_reagent("fermiTox")
+ switch(fermiTox.volume)
+ if(5 to 10)
+ msg += "Subject contains a low amount of toxic isomers. \n"
+ if(10 to 25)
+ msg += "Subject contains toxic isomers. \n"
+ if(25 to 50)
+ msg += "Subject contains a substantial amount of toxic isomers. \n"
+ if(50 to 95)
+ msg += "Subject contains a high amount of toxic isomers. \n"
+ if(95 to INFINITY)
+ msg += "Subject contains a extremely dangerous amount of toxic isomers. \n"
+
msg += "*---------* "
to_chat(user, msg)
diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm
index 2c234a59ba..fc768cd38e 100644
--- a/code/game/objects/items/devices/traitordevices.dm
+++ b/code/game/objects/items/devices/traitordevices.dm
@@ -195,7 +195,7 @@ effective or pretty fucking useless.
Deactivate()
return
-/obj/item/shadowcloak/item_action_slot_check(slot, mob/user)
+/obj/item/shadowcloak/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_BELT)
return 1
diff --git a/code/game/objects/items/eightball.dm b/code/game/objects/items/eightball.dm
index bdaa716075..9dc3e421fd 100644
--- a/code/game/objects/items/eightball.dm
+++ b/code/game/objects/items/eightball.dm
@@ -206,7 +206,7 @@
switch(action)
if("vote")
var/selected_answer = params["answer"]
- if(!selected_answer in possible_answers)
+ if(!(selected_answer in possible_answers))
return
else
votes[user.ckey] = selected_answer
diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm
index e4e16fbfb4..6ea68bf548 100644
--- a/code/game/objects/items/granters.dm
+++ b/code/game/objects/items/granters.dm
@@ -302,7 +302,7 @@
spellname = "charge"
icon_state ="bookcharge"
desc = "This book is made of 100% postconsumer wizard."
- remarks = list("I feel ALIVE!", "I CAN TASTE THE MANA!", "What a RUSH!", "I'm FLYING through these pages!", "THIS GENIUS IS MAKING IT!", "This book is ACTION PAcKED!", "HE'S DONE IT", "LETS GOOOOOOOOOOOO")
+ remarks = list("I feel ALIVE!", "I CAN TASTE THE MANA!", "What a RUSH!", "I'm FLYING through these pages!", "THIS GENIUS IS MAKING IT!", "This book is ACTION PAcKED!", "HE'S DONE IT", "LETS GOOOOOOOOOOOO", "Just wait faster is all...")
/obj/item/book/granter/spell/charge/recoil(mob/user)
..()
@@ -432,6 +432,14 @@
user.mind.teach_crafting_recipe(crafting_recipe_type)
to_chat(user,"You learned how to make [initial(R.name)]. ")
+/obj/item/book/granter/crafting_recipe/threads //Durathread crafting book
+ name = "Credible Threads"
+ desc = "A simple book about sewing and usefull clothing crafting with cloth and durathreads."
+ crafting_recipe_types = list(/datum/crafting_recipe/durathread_duffelbag, /datum/crafting_recipe/durathread_toolbelt, /datum/crafting_recipe/durathread_bandolier, /datum/crafting_recipe/durathread_helmet, /datum/crafting_recipe/durathread_vest)
+ icon_state = "tailers_art1"
+ oneuse = FALSE
+ remarks = list("Durathread is cloth thats also fire-resistant?", "Strong threads that can be used with leather for some light weight storage!", "The cloth can withstand a beating it said but not that much...")
+
/obj/item/book/granter/crafting_recipe/cooking_sweets_101 //We start at 101 for 103 and 105
name = "Cooking Desserts 101"
desc = "A cook book that teaches you some more of the newest desserts. AI approved, and a best seller on Honkplanet."
diff --git a/code/game/objects/items/grenades/plastic.dm b/code/game/objects/items/grenades/plastic.dm
index 709fedbe5a..1956a1f317 100644
--- a/code/game/objects/items/grenades/plastic.dm
+++ b/code/game/objects/items/grenades/plastic.dm
@@ -174,6 +174,7 @@
gender = PLURAL
var/open_panel = 0
can_attach_mob = TRUE
+ full_damage_on_mobs = TRUE
/obj/item/grenade/plastic/c4/New()
wires = new /datum/wires/explosive/c4(src)
diff --git a/code/game/objects/items/his_grace.dm b/code/game/objects/items/his_grace.dm
index 3be57d23f1..7e7dddefb6 100644
--- a/code/game/objects/items/his_grace.dm
+++ b/code/game/objects/items/his_grace.dm
@@ -29,7 +29,7 @@
. = ..()
START_PROCESSING(SSprocessing, src)
GLOB.poi_list += src
- AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_POST_THROW = CALLBACK(src, .proc/move_gracefully)))
+ RegisterSignal(src, COMSIG_MOVABLE_POST_THROW, .proc/move_gracefully)
/obj/item/his_grace/Destroy()
STOP_PROCESSING(SSprocessing, src)
diff --git a/code/game/objects/items/holy_weapons.dm b/code/game/objects/items/holy_weapons.dm
index 5e8250ea00..84439985b2 100644
--- a/code/game/objects/items/holy_weapons.dm
+++ b/code/game/objects/items/holy_weapons.dm
@@ -233,7 +233,7 @@
/obj/item/nullrod/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/nullrod/suicide_act(mob/user)
user.visible_message("[user] is killing [user.p_them()]self with [src]! It looks like [user.p_theyre()] trying to get closer to god! ")
@@ -358,6 +358,8 @@
slot_flags = ITEM_SLOT_BELT
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
+ tool_behaviour = TOOL_SAW
+ toolspeed = 1.5 //slower than a real saw
/obj/item/nullrod/claymore/glowing
icon_state = "swordon"
@@ -513,7 +515,8 @@
slot_flags = ITEM_SLOT_BELT
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
-
+ tool_behaviour = TOOL_SAW
+ toolspeed = 0.5
/obj/item/nullrod/hammmer
icon_state = "hammeron"
@@ -539,6 +542,8 @@
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
total_mass = TOTAL_MASS_HAND_REPLACEMENT
+ tool_behaviour = TOOL_SAW
+ toolspeed = 2
/obj/item/nullrod/chainsaw/Initialize()
. = ..()
diff --git a/code/game/objects/items/implants/implant.dm b/code/game/objects/items/implants/implant.dm
index 482cfb0d8e..0786172f25 100644
--- a/code/game/objects/items/implants/implant.dm
+++ b/code/game/objects/items/implants/implant.dm
@@ -72,7 +72,7 @@
else
return FALSE
- forceMove(target)
+ moveToNullspace()
imp_in = target
target.implants += src
if(activated)
@@ -89,12 +89,12 @@
return TRUE
/obj/item/implant/proc/removed(mob/living/source, silent = FALSE, special = 0)
- moveToNullspace()
+ SEND_SIGNAL(src, COMSIG_IMPLANT_REMOVING, args)
imp_in = null
source.implants -= src
for(var/X in actions)
var/datum/action/A = X
- A.Grant(source)
+ A.Remove(source)
if(ishuman(source))
var/mob/living/carbon/human/H = source
H.sec_hud_set_implants()
diff --git a/code/game/objects/items/implants/implant_chem.dm b/code/game/objects/items/implants/implant_chem.dm
index c6c8be1a83..8da1d1e472 100644
--- a/code/game/objects/items/implants/implant_chem.dm
+++ b/code/game/objects/items/implants/implant_chem.dm
@@ -3,6 +3,7 @@
desc = "Injects things."
icon_state = "reagents"
activated = FALSE
+ var/obj/item/imp_chemholder/chemholder
/obj/item/implant/chem/get_data()
var/dat = {"Implant Specifications:
@@ -29,6 +30,26 @@
GLOB.tracked_chem_implants -= src
return ..()
+/obj/item/implant/chem/implant(mob/living/target, mob/user, silent = FALSE)
+ . = ..()
+ if(!.)
+ return
+ if(chemholder)
+ chemholder.forceMove(target)
+ return
+ chemholder = new(imp_in, src)
+ reagents.trans_to(chemholder, reagents.total_volume)
+
+/obj/item/implant/chem/removed(mob/target, silent = FALSE, special = 0)
+ . = ..()
+ if(!.)
+ return
+ if(!special)
+ chemholder.reagents.trans_to(src, chemholder.reagents.total_volume)
+ QDEL_NULL(chemholder)
+ else
+ chemholder?.moveToNullspace()
+
/obj/item/implant/chem/trigger(emote, mob/living/source)
if(emote == "deathgasp")
if(istype(source) && !(source.stat == DEAD))
@@ -45,13 +66,12 @@
injectamount = reagents.total_volume
else
injectamount = cause
- reagents.trans_to(R, injectamount)
+ chemholder.reagents.trans_to(R, injectamount)
to_chat(R, "You hear a faint beep. ")
- if(!reagents.total_volume)
+ if(!chemholder.reagents.total_volume)
to_chat(R, "You hear a faint click from your chest. ")
qdel(src)
-
/obj/item/implantcase/chem
name = "implant case - 'Remote Chemical'"
desc = "A glass case containing a remote chemical implant."
@@ -63,3 +83,17 @@
return TRUE
else
return ..()
+
+/obj/item/imp_chemholder
+ var/obj/item/implant/chem/implant
+
+/obj/item/imp_chemholder/Initialize(mapload, obj/item/implant/chem/_implant)
+ . = ..()
+ create_reagents(50)
+ implant = _implant
+
+/obj/item/imp_chemholder/Destroy()
+ if(implant?.imp_in)
+ qdel(implant)
+ else
+ return ..()
\ No newline at end of file
diff --git a/code/game/objects/items/implants/implant_clown.dm b/code/game/objects/items/implants/implant_clown.dm
index ae1fef109d..bb98e72b30 100644
--- a/code/game/objects/items/implants/implant_clown.dm
+++ b/code/game/objects/items/implants/implant_clown.dm
@@ -11,7 +11,7 @@
/obj/item/implant/sad_trombone/trigger(emote, mob/source)
if(emote == "deathgasp")
- playsound(loc, 'sound/misc/sadtrombone.ogg', 50, 0)
+ playsound(source.loc, 'sound/misc/sadtrombone.ogg', 50, 0)
/obj/item/implanter/sad_trombone
name = "implanter (sad trombone)"
diff --git a/code/game/objects/items/implants/implant_explosive.dm b/code/game/objects/items/implants/implant_explosive.dm
index e749a6c4be..b93c9419a3 100644
--- a/code/game/objects/items/implants/implant_explosive.dm
+++ b/code/game/objects/items/implants/implant_explosive.dm
@@ -11,8 +11,9 @@
var/popup = FALSE // is the DOUWANNABLOWUP window open?
var/active = FALSE
-/obj/item/implant/explosive/on_mob_death(mob/living/L, gibbed)
- activate("death")
+/obj/item/implant/explosive/trigger(emote, mob/source)
+ if(emote == "deathgasp")
+ activate("death")
/obj/item/implant/explosive/get_data()
var/dat = {"Implant Specifications:
@@ -29,32 +30,18 @@
/obj/item/implant/explosive/activate(cause)
. = ..()
if(!cause || !imp_in || active)
- return 0
+ return FALSE
if(cause == "action_button" && !popup)
popup = TRUE
var/response = alert(imp_in, "Are you sure you want to activate your [name]? This will cause you to explode!", "[name] Confirmation", "Yes", "No")
popup = FALSE
if(response == "No")
- return 0
- heavy = round(heavy)
- medium = round(medium)
- weak = round(weak)
- to_chat(imp_in, "You activate your [name]. ")
- active = TRUE
- var/turf/boomturf = get_turf(imp_in)
- message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [ADMIN_VERBOSEJMP(boomturf)], with cause of [cause].")
-//If the delay is short, just blow up already jeez
- if(delay <= 7)
- explosion(src,heavy,medium,weak,weak, flame_range = weak)
- if(imp_in)
- imp_in.gib(1)
- qdel(src)
- return
- timed_explosion()
+ return FALSE
+ addtimer(CALLBACK(src, .proc/timed_explosion, cause), 1)
/obj/item/implant/explosive/implant(mob/living/target)
for(var/X in target.implants)
- if(istype(X, type))
+ if(istype(X, /obj/item/implant/explosive))
var/obj/item/implant/explosive/imp_e = X
imp_e.heavy += heavy
imp_e.medium += medium
@@ -65,22 +52,37 @@
return ..()
-/obj/item/implant/explosive/proc/timed_explosion()
- imp_in.visible_message("[imp_in] starts beeping ominously! ")
- playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay*0.25)
- if(imp_in && !imp_in.stat)
+/obj/item/implant/explosive/proc/timed_explosion(cause)
+ if(cause == "death" && imp_in.stat != DEAD)
+ return FALSE
+ heavy = round(heavy)
+ medium = round(medium)
+ weak = round(weak)
+ to_chat(imp_in, "You activate your [name]. ")
+ active = TRUE
+ var/turf/boomturf = get_turf(imp_in)
+ message_admins("[ADMIN_LOOKUPFLW(imp_in)] has activated their [name] at [ADMIN_VERBOSEJMP(boomturf)], with cause of [cause].")
+ if(delay > 7)
+ imp_in?.visible_message("[imp_in] starts beeping ominously! ")
+ playsound(get_turf(imp_in ? imp_in : src), 'sound/items/timer.ogg', 30, 0)
+ addtimer(CALLBACK(src, .proc/double_pain, TRUE), delay * 0.25)
+ addtimer(CALLBACK(src, .proc/double_pain), delay * 0.5)
+ addtimer(CALLBACK(src, .proc/double_pain), delay * 0.75)
+ addtimer(CALLBACK(src, .proc/boom_goes_the_weasel), delay)
+ else //If the delay is short, just blow up already jeez
+ boom_goes_the_weasel()
+
+/obj/item/implant/explosive/proc/double_pain(message = FALSE)
+ playsound(get_turf(imp_in ? imp_in : src), 'sound/items/timer.ogg', 30, 0)
+ if(!imp_in)
+ return
+ if(message && imp_in.stat == CONSCIOUS)
imp_in.visible_message("[imp_in] doubles over in pain! ")
- imp_in.Knockdown(140)
- playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay*0.25)
- playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay*0.25)
- playsound(loc, 'sound/items/timer.ogg', 30, 0)
- sleep(delay*0.25)
- explosion(src,heavy,medium,weak,weak, flame_range = weak)
- if(imp_in)
- imp_in.gib(1)
+ imp_in.Knockdown(140)
+
+/obj/item/implant/explosive/proc/boom_goes_the_weasel()
+ explosion(get_turf(imp_in ? imp_in : src), heavy, medium, weak, weak, flame_range = weak)
+ imp_in?.gib(TRUE)
qdel(src)
/obj/item/implant/explosive/macro
@@ -95,17 +97,7 @@
/obj/item/implant/explosive/macro/implant(mob/living/target)
for(var/X in target.implants)
if(istype(X, type))
- return 0
-
- for(var/Y in target.implants)
- if(istype(Y, /obj/item/implant/explosive))
- var/obj/item/implant/explosive/imp_e = Y
- heavy += imp_e.heavy
- medium += imp_e.medium
- weak += imp_e.weak
- delay += imp_e.delay
- qdel(imp_e)
- break
+ return FALSE
return ..()
diff --git a/code/game/objects/items/implants/implant_mindshield.dm b/code/game/objects/items/implants/implant_mindshield.dm
index b9907cbfca..2a99c6e1ec 100644
--- a/code/game/objects/items/implants/implant_mindshield.dm
+++ b/code/game/objects/items/implants/implant_mindshield.dm
@@ -1,7 +1,6 @@
/obj/item/implant/mindshield
name = "mindshield implant"
desc = "Protects against brainwashing."
- resistance_flags = INDESTRUCTIBLE
activated = 0
/obj/item/implant/mindshield/get_data()
diff --git a/code/game/objects/items/implants/implant_misc.dm b/code/game/objects/items/implants/implant_misc.dm
index 3a4295c61e..75b0c67798 100644
--- a/code/game/objects/items/implants/implant_misc.dm
+++ b/code/game/objects/items/implants/implant_misc.dm
@@ -69,62 +69,4 @@
healthstring = "Oxygen Deprivation Damage => [round(L.getOxyLoss())] Fire Damage => [round(L.getFireLoss())] Toxin Damage => [round(L.getToxLoss())] Brute Force Damage => [round(L.getBruteLoss())] "
if (!healthstring)
healthstring = "ERROR"
- return healthstring
-
-/obj/item/implant/radio
- name = "internal radio implant"
- activated = TRUE
- var/obj/item/radio/radio
- var/radio_key
- var/subspace_transmission = FALSE
- icon = 'icons/obj/radio.dmi'
- icon_state = "walkietalkie"
-
-/obj/item/implant/radio/activate()
- . = ..()
- // needs to be GLOB.deep_inventory_state otherwise it won't open
- radio.ui_interact(usr, "main", null, FALSE, null, GLOB.deep_inventory_state)
-
-/obj/item/implant/radio/Initialize(mapload)
- . = ..()
-
- radio = new(src)
- // almost like an internal headset, but without the
- // "must be in ears to hear" restriction.
- radio.name = "internal radio"
- radio.subspace_transmission = subspace_transmission
- radio.canhear_range = 0
- if(radio_key)
- radio.keyslot = new radio_key
- radio.recalculateChannels()
-
-/obj/item/implant/radio/mining
- radio_key = /obj/item/encryptionkey/headset_cargo
-
-/obj/item/implant/radio/syndicate
- desc = "Are you there God? It's me, Syndicate Comms Agent."
- radio_key = /obj/item/encryptionkey/syndicate
- subspace_transmission = TRUE
-
-/obj/item/implant/radio/slime
- name = "slime radio"
- icon = 'icons/obj/surgery.dmi'
- icon_state = "adamantine_resonator"
- radio_key = /obj/item/encryptionkey/headset_sci
- subspace_transmission = TRUE
-
-/obj/item/implant/radio/get_data()
- var/dat = {"Implant Specifications:
- Name: Internal Radio Implant
- Life: 24 hours
- Implant Details: Allows user to use an internal radio, useful if user expects equipment loss, or cannot equip conventional radios."}
- return dat
-
-/obj/item/implanter/radio
- name = "implanter (internal radio)"
- imp_type = /obj/item/implant/radio
-
-/obj/item/implanter/radio/syndicate
- name = "implanter (internal syndicate radio)"
- imp_type = /obj/item/implant/radio/syndicate
-
+ return healthstring
\ No newline at end of file
diff --git a/code/game/objects/items/implants/implant_radio.dm b/code/game/objects/items/implants/implant_radio.dm
new file mode 100644
index 0000000000..5d3d579a4e
--- /dev/null
+++ b/code/game/objects/items/implants/implant_radio.dm
@@ -0,0 +1,69 @@
+/obj/item/implant/radio
+ name = "internal radio implant"
+ activated = TRUE
+ var/obj/item/radio/internal/radio
+ var/radio_key
+ var/subspace_transmission = FALSE
+ icon = 'icons/obj/radio.dmi'
+ icon_state = "walkietalkie"
+
+/obj/item/implant/radio/activate()
+ . = ..()
+ // needs to be GLOB.deep_inventory_state otherwise it won't open
+ radio.ui_interact(usr, "main", null, FALSE, null, GLOB.deep_inventory_state)
+
+/obj/item/implant/radio/implant(mob/living/target, mob/user, silent = FALSE)
+ . = ..()
+ if(!.)
+ return
+ if(radio)
+ radio.forceMove(target)
+ return
+ radio = new(target)
+ // almost like an internal headset, but without the
+ // "must be in ears to hear" restriction.
+ radio.name = "internal radio"
+ radio.subspace_transmission = subspace_transmission
+ radio.canhear_range = 0
+ if(radio_key)
+ radio.keyslot = new radio_key
+ radio.recalculateChannels()
+
+/obj/item/implant/radio/removed(mob/target, silent = FALSE, special = 0)
+ . = ..()
+ if(!.)
+ return
+ if(!special)
+ qdel(radio)
+ else
+ radio?.moveToNullspace()
+
+/obj/item/implant/radio/mining
+ radio_key = /obj/item/encryptionkey/headset_cargo
+
+/obj/item/implant/radio/syndicate
+ desc = "Are you there God? It's me, Syndicate Comms Agent."
+ radio_key = /obj/item/encryptionkey/syndicate
+ subspace_transmission = TRUE
+
+/obj/item/implant/radio/slime
+ name = "slime radio"
+ icon = 'icons/obj/surgery.dmi'
+ icon_state = "adamantine_resonator"
+ radio_key = /obj/item/encryptionkey/headset_sci
+ subspace_transmission = TRUE
+
+/obj/item/implant/radio/get_data()
+ var/dat = {"Implant Specifications:
+ Name: Internal Radio Implant
+ Life: 24 hours
+ Implant Details: Allows user to use an internal radio, useful if user expects equipment loss, or cannot equip conventional radios."}
+ return dat
+
+/obj/item/implanter/radio
+ name = "implanter (internal radio)"
+ imp_type = /obj/item/implant/radio
+
+/obj/item/implanter/radio/syndicate
+ name = "implanter (internal syndicate radio)"
+ imp_type = /obj/item/implant/radio/syndicate
\ No newline at end of file
diff --git a/code/game/objects/items/implants/implant_storage.dm b/code/game/objects/items/implants/implant_storage.dm
index ec6b4d64c3..1dfc0b4580 100644
--- a/code/game/objects/items/implants/implant_storage.dm
+++ b/code/game/objects/items/implants/implant_storage.dm
@@ -4,30 +4,43 @@
icon_state = "storage"
item_color = "r"
var/max_slot_stacking = 4
+ var/obj/item/storage/bluespace_pocket/pocket
/obj/item/implant/storage/activate()
. = ..()
- SEND_SIGNAL(src, COMSIG_TRY_STORAGE_SHOW, imp_in, TRUE)
+ SEND_SIGNAL(pocket, COMSIG_TRY_STORAGE_SHOW, imp_in, TRUE)
/obj/item/implant/storage/removed(source, silent = FALSE, special = 0)
- . = ..()
- if(.)
- if(!special)
- qdel(GetComponent(/datum/component/storage/concrete/implant))
+ if(!special)
+ QDEL_NULL(pocket)
+ else
+ pocket?.moveToNullspace()
+ return ..()
/obj/item/implant/storage/implant(mob/living/target, mob/user, silent = FALSE)
for(var/X in target.implants)
if(istype(X, type))
var/obj/item/implant/storage/imp_e = X
- GET_COMPONENT_FROM(STR, /datum/component/storage, imp_e)
+ var/datum/component/storage/STR = imp_e.pocket.GetComponent(/datum/component/storage)
if(!STR || (STR && STR.max_items < max_slot_stacking))
- imp_e.AddComponent(/datum/component/storage/concrete/implant)
+ imp_e.pocket.AddComponent(/datum/component/storage/concrete/implant)
qdel(src)
return TRUE
return FALSE
- AddComponent(/datum/component/storage/concrete/implant)
+ . = ..()
+ if(.)
+ if(!QDELETED(pocket))
+ pocket.forceMove(target)
+ else
+ pocket = new(target)
- return ..()
+/obj/item/storage/bluespace_pocket
+ name = "internal bluespace pocket"
+ icon_state = "pillbox"
+ w_class = WEIGHT_CLASS_TINY
+ desc = "A tiny yet spacious pocket, usually found implanted inside sneaky syndicate agents and nowhere else."
+ component_type = /datum/component/storage/concrete/implant
+ resistance_flags = INDESTRUCTIBLE //A bomb!
/obj/item/implanter/storage
name = "implanter (storage)"
diff --git a/code/game/objects/items/implants/implant_track.dm b/code/game/objects/items/implants/implant_track.dm
index 913c577f2c..4b7ae3bbac 100644
--- a/code/game/objects/items/implants/implant_track.dm
+++ b/code/game/objects/items/implants/implant_track.dm
@@ -3,8 +3,8 @@
desc = "Track with this."
activated = 0
-/obj/item/implant/tracking/New()
- ..()
+/obj/item/implant/tracking/Initialize()
+ . = ..()
GLOB.tracked_implants += src
/obj/item/implant/tracking/Destroy()
@@ -15,7 +15,31 @@
imp_type = /obj/item/implant/tracking
/obj/item/implanter/tracking/gps
- imp_type = /obj/item/gps/mining/internal
+ imp_type = /obj/item/implant/gps
+
+/obj/item/implant/gps
+ name = "\improper GPS implant"
+ desc = "Track with this and a GPS."
+ activated = FALSE
+ var/obj/item/gps/internal/mining/real_gps
+
+/obj/item/implant/gps/implant(mob/living/target, mob/user, silent = FALSE)
+ . = ..()
+ if(!.)
+ return
+ if(real_gps)
+ real_gps.forceMove(target)
+ else
+ real_gps = new(target)
+
+/obj/item/implant/gps/removed(mob/living/source, silent = FALSE, special = 0)
+ . = ..()
+ if(!.)
+ return
+ if(!special)
+ qdel(real_gps)
+ else
+ real_gps?.moveToNullspace()
/obj/item/implant/tracking/get_data()
var/dat = {"Implant Specifications:
diff --git a/code/game/objects/items/implants/implantuplink.dm b/code/game/objects/items/implants/implant_uplink.dm
similarity index 93%
rename from code/game/objects/items/implants/implantuplink.dm
rename to code/game/objects/items/implants/implant_uplink.dm
index 9000fbbe34..9895c1e34c 100644
--- a/code/game/objects/items/implants/implantuplink.dm
+++ b/code/game/objects/items/implants/implant_uplink.dm
@@ -1,23 +1,23 @@
-/obj/item/implant/uplink
- name = "uplink implant"
- desc = "Sneeki breeki."
- icon = 'icons/obj/radio.dmi'
- icon_state = "radio"
- lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
- var/starting_tc = 0
-
-/obj/item/implant/uplink/Initialize(mapload, _owner)
- . = ..()
- AddComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc)
-
-/obj/item/implanter/uplink
- name = "implanter (uplink)"
- imp_type = /obj/item/implant/uplink
-
-/obj/item/implanter/uplink/precharged
- name = "implanter (precharged uplink)"
- imp_type = /obj/item/implant/uplink/precharged
-
-/obj/item/implant/uplink/precharged
- starting_tc = 10
+/obj/item/implant/uplink
+ name = "uplink implant"
+ desc = "Sneeki breeki."
+ icon = 'icons/obj/radio.dmi'
+ icon_state = "radio"
+ lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
+ var/starting_tc = 0
+
+/obj/item/implant/uplink/Initialize(mapload, _owner)
+ . = ..()
+ AddComponent(/datum/component/uplink, _owner, TRUE, FALSE, null, starting_tc, GLOB.not_incapacitated_state)
+
+/obj/item/implanter/uplink
+ name = "implanter (uplink)"
+ imp_type = /obj/item/implant/uplink
+
+/obj/item/implanter/uplink/precharged
+ name = "implanter (precharged uplink)"
+ imp_type = /obj/item/implant/uplink/precharged
+
+/obj/item/implant/uplink/precharged
+ starting_tc = 10
diff --git a/code/game/objects/items/latexballoon.dm b/code/game/objects/items/latexballoon.dm
index 709bc6662a..11be6b88e9 100644
--- a/code/game/objects/items/latexballoon.dm
+++ b/code/game/objects/items/latexballoon.dm
@@ -52,5 +52,5 @@
var/obj/item/tank/T = W
blow(T, user)
return
- if (W.is_sharp() || W.is_hot() || is_pointed(W))
+ if (W.get_sharpness() || W.get_temperature() || is_pointed(W))
burst()
diff --git a/code/game/objects/items/manuals.dm b/code/game/objects/items/manuals.dm
index 02d0a1c36a..6ae34e9ca2 100644
--- a/code/game/objects/items/manuals.dm
+++ b/code/game/objects/items/manuals.dm
@@ -244,7 +244,7 @@
..()
/obj/item/book/manual/wiki/proc/initialize_wikibook()
- var/wikiurl = CONFIG_GET(string/wikiurl)
+ var/wikiurl = CONFIG_GET(string/wikiurltg)
if(wikiurl)
dat = {"
@@ -270,13 +270,67 @@
"}
-/obj/item/book/manual/wiki/chemistry
+/obj/item/book/manual/wiki/cit
+ name = "Citadel infobook"
+ icon_state ="book8"
+ author = "Nanotrasen"
+ title = "Citadel infobook"
+ page_link = ""
+ window_size = "1500x800" //Too squashed otherwise
+
+/obj/item/book/manual/wiki/cit/initialize_wikibook()
+ var/wikiurl = CONFIG_GET(string/wikiurl)
+ if(wikiurl)
+ dat = {"
+
+
+
+
+
+
+ You start skimming through the manual...
+
+
+
+
+
+ "}
+
+/obj/item/book/manual/wiki/cit/chemistry
name = "Chemistry Textbook"
icon_state ="chemistrybook"
author = "Nanotrasen"
title = "Chemistry Textbook"
+ page_link = "main/guides/guide_chemistry"
+
+/obj/item/book/manual/wiki/cit/chem_recipies
+ name = "Chemistry Recipies"
+ icon_state ="chemrecibook"
+ author = "Chemcat"
+ title = "Chemistry Recipies"
+ page_link = "main/guides/chem_recipies"
+
+/obj/item/book/manual/wiki/chemistry
+ name = "Outdated Chemistry Textbook"
+ icon_state ="chemistrybook_old"
+ author = "Nanotrasen"
+ title = "Outdated Chemistry Textbook"
page_link = "Guide_to_chemistry"
+/obj/item/book/manual/wiki/chemistry/Initialize()
+ ..()
+ new /obj/item/book/manual/wiki/cit/chemistry(loc)
+ new /obj/item/book/manual/wiki/cit/chem_recipies(loc)
+
/obj/item/book/manual/wiki/engineering_construction
name = "Station Repairs and Construction"
icon_state ="bookEngineering"
diff --git a/code/game/objects/items/melee/energy.dm b/code/game/objects/items/melee/energy.dm
index d854ab9f5a..51fd2c50d8 100644
--- a/code/game/objects/items/melee/energy.dm
+++ b/code/game/objects/items/melee/energy.dm
@@ -28,7 +28,7 @@
/obj/item/melee/transforming/energy/add_blood_DNA(list/blood_dna)
return FALSE
-/obj/item/melee/transforming/energy/is_sharp()
+/obj/item/melee/transforming/energy/get_sharpness()
return active * sharpness
/obj/item/melee/transforming/energy/process()
@@ -46,7 +46,7 @@
STOP_PROCESSING(SSobj, src)
set_light(0)
-/obj/item/melee/transforming/energy/is_hot()
+/obj/item/melee/transforming/energy/get_temperature()
return active * heat
/obj/item/melee/transforming/energy/ignition_effect(atom/A, mob/user)
@@ -142,6 +142,8 @@
w_class = WEIGHT_CLASS_NORMAL
sharpness = IS_SHARP
light_color = "#40ceff"
+ tool_behaviour = TOOL_SAW
+ toolspeed = 0.7
/obj/item/melee/transforming/energy/sword/cyborg/saw/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
return 0
@@ -231,3 +233,152 @@
desc = "An extremely sharp blade made out of hard light. Packs quite a punch."
icon_state = "lightblade"
item_state = "lightblade"
+
+/*/////////////////////////////////////////////////////////////////////////
+///////////// The TRUE Energy Sword ///////////////////////////
+*//////////////////////////////////////////////////////////////////////////
+
+/obj/item/melee/transforming/energy/sword/cx
+ name = "non-eutactic blade"
+ desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable."
+ icon_state = "cxsword_hilt"
+ item_state = "cxsword"
+ force = 3
+ force_on = 21
+ throwforce = 5
+ throwforce_on = 20
+ hitsound = "swing_hit" //it starts deactivated
+ hitsound_on = 'sound/weapons/nebhit.ogg'
+ attack_verb_off = list("tapped", "poked")
+ throw_speed = 3
+ throw_range = 5
+ sharpness = IS_SHARP
+ embedding = list("embedded_pain_multiplier" = 6, "embed_chance" = 20, "embedded_fall_chance" = 60)
+ armour_penetration = 10
+ block_chance = 35
+ light_color = "#37FFF7"
+ actions_types = list()
+
+/obj/item/melee/transforming/energy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
+ altafterattack(A, user, TRUE, params)
+ return TRUE
+
+/obj/item/melee/transforming/energy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
+ if(istype(user))
+ user.visible_message("[user] points the tip of [src] at [target]. ", "You point the tip of [src] at [target]. ")
+ return TRUE
+
+/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
+ active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
+ if(active) //also I'd need to rip out the iconstate changing bits
+ force = force_on
+ throwforce = throwforce_on
+ hitsound = hitsound_on
+ throw_speed = 4
+ if(attack_verb_on.len)
+ attack_verb = attack_verb_on
+ w_class = w_class_on
+ START_PROCESSING(SSobj, src)
+ set_light(brightness_on)
+ update_icon()
+ else
+ force = initial(force)
+ throwforce = initial(throwforce)
+ hitsound = initial(hitsound)
+ throw_speed = initial(throw_speed)
+ if(attack_verb_off.len)
+ attack_verb = attack_verb_off
+ w_class = initial(w_class)
+ STOP_PROCESSING(SSobj, src)
+ set_light(0)
+ update_icon()
+ transform_messages(user, supress_message_text)
+ add_fingerprint(user)
+ return TRUE
+
+/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
+ playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1)
+ if(!supress_message_text)
+ to_chat(user, "[src] [active ? "is now active":"can now be concealed"]. ")
+
+/obj/item/melee/transforming/energy/sword/cx/update_icon()
+ var/mutable_appearance/blade_overlay = mutable_appearance(icon, "cxsword_blade")
+ var/mutable_appearance/gem_overlay = mutable_appearance(icon, "cxsword_gem")
+
+ if(light_color)
+ blade_overlay.color = light_color
+ gem_overlay.color = light_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(gem_overlay)
+
+ if(active)
+ add_overlay(blade_overlay)
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+
+/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user)
+ if(!in_range(src, user)) //Basic checks to prevent abuse
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now! ")
+ return
+
+ if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
+ if(energy_color_input)
+ light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ update_light()
+
+/obj/item/melee/transforming/energy/sword/cx/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to recolor it. ")
+
+/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(active)
+ if(isinhands)
+ var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
+ blade_inhand.color = light_color
+ . += blade_inhand
+
+//Broken version. Not a toy, but not as strong.
+/obj/item/melee/transforming/energy/sword/cx/broken
+ name = "misaligned non-eutactic blade"
+ desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. This one seems to have a damaged handle and misaligned components, causing the blade to be unstable at best"
+ force_on = 15 //As strong a survival knife/bone dagger
+
+/obj/item/melee/transforming/energy/sword/cx/attackby(obj/item/W, mob/living/user, params)
+ if(istype(W, /obj/item/melee/transforming/energy/sword/cx))
+ if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
+ to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]! ")
+ return
+ else
+ to_chat(user, "You combine the two light swords, making a single supermassive blade! You're cool. ")
+ new /obj/item/twohanded/dualsaber/hypereutactic(user.drop_location())
+ qdel(W)
+ qdel(src)
+ else
+ return ..()
+
+//////// Tatortot NEB /////////////// (same stats as regular esword)
+/obj/item/melee/transforming/energy/sword/cx/traitor
+ name = "\improper Dragon's Tooth Sword"
+ desc = "The Dragon's Tooth sword is a blackmarket modification of a Non-Eutactic Blade, \
+ which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \
+ It appears to have a wooden grip and a shaved down guard."
+ icon_state = "cxsword_hilt_traitor"
+ force_on = 30
+ armour_penetration = 50
+ embedding = list("embedded_pain_multiplier" = 10, "embed_chance" = 75, "embedded_fall_chance" = 0, "embedded_impact_pain_multiplier" = 10)
+ block_chance = 50
+ hitsound_on = 'sound/weapons/blade1.ogg'
+ light_color = "#37F0FF"
+
+/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text)
+ playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1)
+ if(!supress_message_text)
+ to_chat(user, "[src] [active ? "is now active":"can now be concealed"]. ")
diff --git a/code/game/objects/items/melee/transforming.dm b/code/game/objects/items/melee/transforming.dm
index aabb930bb2..7eb35ed06b 100644
--- a/code/game/objects/items/melee/transforming.dm
+++ b/code/game/objects/items/melee/transforming.dm
@@ -23,7 +23,7 @@
else
if(attack_verb_off.len)
attack_verb = attack_verb_off
- if(is_sharp())
+ if(get_sharpness())
AddComponent(/datum/component/butchering, 50, 100, 0, hitsound, !active)
/obj/item/melee/transforming/attack_self(mob/living/carbon/user)
@@ -65,11 +65,11 @@
icon_state = initial(icon_state)
w_class = initial(w_class)
total_mass = initial(total_mass)
- if(is_sharp())
+ if(get_sharpness())
var/datum/component/butchering/BT = LoadComponent(/datum/component/butchering)
BT.butchering_enabled = TRUE
else
- GET_COMPONENT(BT, /datum/component/butchering)
+ var/datum/component/butchering/BT = GetComponent(/datum/component/butchering)
if(BT)
BT.butchering_enabled = FALSE
transform_messages(user, supress_message_text)
diff --git a/code/game/objects/items/mop.dm b/code/game/objects/items/mop.dm
index 7524fc9007..3f7fe7ee8d 100644
--- a/code/game/objects/items/mop.dm
+++ b/code/game/objects/items/mop.dm
@@ -27,6 +27,7 @@
/obj/item/mop/proc/clean(turf/A)
if(reagents.has_reagent("water", 1) || reagents.has_reagent("holywater", 1) || reagents.has_reagent("vodka", 1) || reagents.has_reagent("cleaner", 1))
SEND_SIGNAL(A, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
+ A.clean_blood()
for(var/obj/effect/O in A)
if(is_cleanable(O))
qdel(O)
diff --git a/code/game/objects/items/pet_carrier.dm b/code/game/objects/items/pet_carrier.dm
index a73be6e12e..30442d7304 100644
--- a/code/game/objects/items/pet_carrier.dm
+++ b/code/game/objects/items/pet_carrier.dm
@@ -122,7 +122,7 @@
if(user.mob_size <= MOB_SIZE_SMALL)
to_chat(user, "You poke a limb through [src]'s bars and start fumbling for the lock switch... (This will take some time.) ")
to_chat(loc, "You see [user] reach through the bars and fumble for the lock switch! ")
- if(!do_after(user, rand(300, 400), target = user) || open || !locked || !user in occupants)
+ if(!do_after(user, rand(300, 400), target = user) || open || !locked || !(user in occupants))
return
loc.visible_message("[user] flips the lock switch on [src] by reaching through! ", null, null, null, user)
to_chat(user, "Bingo! The lock pops open! ")
@@ -132,7 +132,7 @@
else
loc.visible_message("[src] starts rattling as something pushes against the door! ", null, null, null, user)
to_chat(user, "You start pushing out of [src]... (This will take about 20 seconds.) ")
- if(!do_after(user, 200, target = user) || open || !locked || !user in occupants)
+ if(!do_after(user, 200, target = user) || open || !locked || !(user in occupants))
return
loc.visible_message("[user] shoves out of [src]! ", null, null, null, user)
to_chat(user, "You shove open [src]'s door against the lock's resistance and fall out! ")
@@ -185,7 +185,7 @@
occupant_weight += occupant.mob_size
/obj/item/pet_carrier/proc/remove_occupant(mob/living/occupant, turf/new_turf)
- if(!occupant in occupants || !istype(occupant))
+ if(!(occupant in occupants) || !istype(occupant))
return
occupant.forceMove(new_turf ? new_turf : drop_location())
occupants -= occupant
diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm
index 48588cf9f3..973fb0c0ab 100644
--- a/code/game/objects/items/plushes.dm
+++ b/code/game/objects/items/plushes.dm
@@ -117,7 +117,7 @@
to_chat(user, "You try to pet [src], but it has no stuffing. Aww... ")
/obj/item/toy/plush/attackby(obj/item/I, mob/living/user, params)
- if(I.is_sharp())
+ if(I.get_sharpness())
if(!grenade)
if(!stuffed)
to_chat(user, "You already murdered it! ")
@@ -366,10 +366,10 @@
/obj/item/toy/plush/random
name = "Illegal plushie"
desc = "Something fucked up"
+ var/blacklisted_plushes = list(/obj/item/toy/plush/carpplushie/dehy_carp, /obj/item/toy/plush/awakenedplushie, /obj/item/toy/plush/random)
/obj/item/toy/plush/random/Initialize()
- ..()
- var/newtype = pick(subtypesof(/obj/item/toy/plush))
+ var/newtype = pick(subtypesof(/obj/item/toy/plush) - typecacheof(blacklisted_plushes))
new newtype(loc)
return INITIALIZE_HINT_QDEL
diff --git a/code/game/objects/items/religion.dm b/code/game/objects/items/religion.dm
index 8582725cda..7b3dcb1e00 100644
--- a/code/game/objects/items/religion.dm
+++ b/code/game/objects/items/religion.dm
@@ -82,14 +82,6 @@
/obj/item/banner/security/mundane
inspiration_available = FALSE
-/datum/crafting_recipe/security_banner
- name = "Securistan Banner"
- result = /obj/item/banner/security/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/security = 1)
- category = CAT_MISC
-
/obj/item/banner/medical
name = "meditopia banner"
desc = "The banner of Meditopia, generous benefactors that cure wounds and shelter the weak."
@@ -103,14 +95,6 @@
/obj/item/banner/medical/check_inspiration(mob/living/carbon/human/H)
return H.stat //Meditopia is moved to help those in need
-/datum/crafting_recipe/medical_banner
- name = "Meditopia Banner"
- result = /obj/item/banner/medical/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/medical = 1)
- category = CAT_MISC
-
/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
H.adjustToxLoss(-15)
H.setOxyLoss(0)
@@ -129,14 +113,6 @@
/obj/item/banner/science/check_inspiration(mob/living/carbon/human/H)
return H.on_fire //Sciencia is pleased by dedication to the art of Toxins
-/datum/crafting_recipe/science_banner
- name = "Sciencia Banner"
- result = /obj/item/banner/science/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/scientist = 1)
- category = CAT_MISC
-
/obj/item/banner/cargo
name = "cargonia banner"
desc = "The banner of the eternal Cargonia, with the mystical power of conjuring any object into existence."
@@ -147,14 +123,6 @@
/obj/item/banner/cargo/mundane
inspiration_available = FALSE
-/datum/crafting_recipe/cargo_banner
- name = "Cargonia Banner"
- result = /obj/item/banner/cargo/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/cargotech = 1)
- category = CAT_MISC
-
/obj/item/banner/engineering
name = "engitopia banner"
desc = "The banner of Engitopia, wielders of limitless power."
@@ -168,14 +136,6 @@
/obj/item/banner/engineering/special_inspiration(mob/living/carbon/human/H)
H.radiation = 0
-/datum/crafting_recipe/engineering_banner
- name = "Engitopia Banner"
- result = /obj/item/banner/engineering/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/rank/engineer = 1)
- category = CAT_MISC
-
/obj/item/banner/command
name = "command banner"
desc = "The banner of Command, a staunch and ancient line of bueraucratic kings and queens."
@@ -189,14 +149,6 @@
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
return HAS_TRAIT(H, TRAIT_MINDSHIELD) //Command is stalwart but rewards their allies.
-/datum/crafting_recipe/command_banner
- name = "Command Banner"
- result = /obj/item/banner/command/mundane
- time = 40
- reqs = list(/obj/item/stack/rods = 2,
- /obj/item/clothing/under/captainparade = 1)
- category = CAT_MISC
-
/obj/item/banner/red
name = "red banner"
icon_state = "banner-red"
@@ -216,7 +168,7 @@
/obj/item/storage/backpack/bannerpack/Initialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times.
/obj/item/storage/backpack/bannerpack/red
@@ -286,7 +238,6 @@
var/staffcooldown = 0
var/staffwait = 30
-
/obj/item/godstaff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
if(staffcooldown + staffwait > world.time)
@@ -332,19 +283,16 @@
heat_protection = FEET
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
-
/obj/item/clothing/shoes/plate/red
icon_state = "crusader-red"
/obj/item/clothing/shoes/plate/blue
icon_state = "crusader-blue"
-
/obj/item/storage/box/itemset/crusader
name = "Crusader's Armour Set" //i can't into ck2 references
desc = "This armour is said to be based on the armor of kings on another world thousands of years ago, who tended to assassinate, conspire, and plot against everyone who tried to do the same to them. Some things never change."
-
/obj/item/storage/box/itemset/crusader/blue/New()
..()
contents = list()
@@ -354,7 +302,6 @@
new /obj/item/clothing/gloves/plate/blue(src)
new /obj/item/clothing/shoes/plate/blue(src)
-
/obj/item/storage/box/itemset/crusader/red/New()
..()
contents = list()
@@ -364,7 +311,6 @@
new /obj/item/clothing/gloves/plate/red(src)
new /obj/item/clothing/shoes/plate/red(src)
-
/obj/item/claymore/weak
desc = "This one is rusted."
force = 30
diff --git a/code/game/objects/items/robot/robot_items.dm b/code/game/objects/items/robot/robot_items.dm
index 5454b0fdb8..77bc7ed810 100644
--- a/code/game/objects/items/robot/robot_items.dm
+++ b/code/game/objects/items/robot/robot_items.dm
@@ -313,7 +313,7 @@
if(M.get_ear_protection() == FALSE)
M.confused += 6
audible_message("HUMAN HARM ")
- playsound(get_turf(src), 'sound/ai/harmalarm.ogg', 70, 3)
+ playsound(get_turf(src), 'sound/effects/harmalarm.ogg', 70, 3)
cooldown = world.time + 200
log_game("[key_name(user)] used a Cyborg Harm Alarm in [AREACOORD(user)]")
if(iscyborg(user))
@@ -430,7 +430,7 @@
A.BB.nodamage = FALSE
A.BB.speed = 0.5
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
- A.fire_casing(target, user, params, 0, 0, null, 0)
+ A.fire_casing(target, user, params, 0, 0, null, 0, src)
user.visible_message("[user] blasts a flying lollipop at [target]! ")
check_amount()
@@ -446,7 +446,7 @@
A.BB.speed = 0.5
A.BB.color = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
playsound(src.loc, 'sound/weapons/bulletflyby3.ogg', 50, 1)
- A.fire_casing(target, user, params, 0, 0, null, 0)
+ A.fire_casing(target, user, params, 0, 0, null, 0, src)
user.visible_message("[user] shoots a high-velocity gumball at [target]! ")
check_amount()
@@ -746,3 +746,73 @@
..()
hud = new /obj/item/clothing/glasses/hud/security(src)
return
+
+
+/**********************************************************************
+ Grippers oh god oh fuck
+***********************************************************************/
+
+/obj/item/weapon/gripper
+ name = "circuit gripper"
+ desc = "A simple grasping tool for inserting circuitboards into machinary."
+ icon = 'icons/obj/device.dmi'
+ icon_state = "gripper"
+
+ item_flags = NOBLUDGEON
+
+ //Has a list of items that it can hold.
+ var/list/can_hold = list(
+ /obj/item/circuitboard
+ )
+
+ var/obj/item/wrapped = null // Item currently being held.
+
+/obj/item/weapon/gripper/attack_self()
+ if(wrapped)
+ wrapped.forceMove(get_turf(wrapped))
+ wrapped = null
+ return ..()
+
+/obj/item/weapon/gripper/afterattack(var/atom/target, var/mob/living/user, proximity, params)
+
+ if(!proximity)
+ return
+
+ if(!wrapped)
+ for(var/obj/item/thing in src.contents)
+ wrapped = thing
+ break
+
+ if(wrapped) //Already have an item.
+ //Temporary put wrapped into user so target's attackby() checks pass.
+ wrapped.loc = user
+
+ //Pass the attack on to the target. This might delete/relocate wrapped.
+ var/resolved = target.attackby(wrapped,user)
+ if(!resolved && wrapped && target)
+ wrapped.afterattack(target,user,1)
+ //If wrapped was neither deleted nor put into target, put it back into the gripper.
+ if(wrapped && user && (wrapped.loc == user))
+ wrapped.loc = src
+ else
+ wrapped = null
+ return
+
+ else if(istype(target,/obj/item))
+
+ var/obj/item/I = target
+
+ var/grab = 0
+ for(var/typepath in can_hold)
+ if(istype(I,typepath))
+ grab = 1
+ break
+
+ //We can grab the item, finally.
+ if(grab)
+ to_chat(user, "You collect \the [I].")
+ I.loc = src
+ wrapped = I
+ return
+ else
+ to_chat(user, "Your gripper cannot hold \the [target]. ")
diff --git a/code/game/objects/items/robot/robot_parts.dm b/code/game/objects/items/robot/robot_parts.dm
index cd2ccff170..95110692c9 100644
--- a/code/game/objects/items/robot/robot_parts.dm
+++ b/code/game/objects/items/robot/robot_parts.dm
@@ -254,7 +254,7 @@
to_chat(user, "The MMI indicates that their mind is currently inactive; it might change! ")
return
- if(BM.stat == DEAD || (M.brain && M.brain.damaged_brain))
+ if(BM.stat == DEAD || (M.brain && M.brain.organ_flags & ORGAN_FAILING))
to_chat(user, "Sticking a dead brain into the frame would sort of defeat the purpose! ")
return
diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm
index 9c929a6ebf..d9045a7a34 100644
--- a/code/game/objects/items/robot/robot_upgrades.dm
+++ b/code/game/objects/items/robot/robot_upgrades.dm
@@ -89,32 +89,36 @@
R.speed = initial(R.speed)
/obj/item/borg/upgrade/disablercooler
- name = "cyborg rapid disabler cooling module"
- desc = "Used to cool a mounted disabler, increasing the potential current in it and thus its recharge rate."
+ name = "cyborg rapid energy blaster cooling module"
+ desc = "Used to cool a mounted energy-based firearm, increasing the potential current in it and thus its recharge rate."
icon_state = "cyborg_upgrade3"
require_module = 1
/obj/item/borg/upgrade/disablercooler/action(mob/living/silicon/robot/R, user = usr)
. = ..()
if(.)
- var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.module.modules
- if(!T)
- to_chat(user, "There's no disabler in this unit! ")
+ var/successflag
+ for(var/obj/item/gun/energy/T in R.module.modules)
+ if(T.charge_delay <= 2)
+ successflag = successflag || 2
+ continue
+ T.charge_delay = max(2, T.charge_delay - 4)
+ successflag = 1
+ if(!successflag)
+ to_chat(user, "There's no energy-based firearm in this unit! ")
return FALSE
- if(T.charge_delay <= 2)
+ if(successflag == 2)
to_chat(R, "A cooling unit is already installed! ")
to_chat(user, "There's no room for another cooling unit! ")
return FALSE
- T.charge_delay = max(2 , T.charge_delay - 4)
-
/obj/item/borg/upgrade/disablercooler/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..()
if (.)
- var/obj/item/gun/energy/disabler/cyborg/T = locate() in R.module.modules
- if(!T)
- return FALSE
- T.charge_delay = initial(T.charge_delay)
+ for(var/obj/item/gun/energy/T in R.module.modules)
+ T.charge_delay = initial(T.charge_delay)
+ return .
+ return FALSE
/obj/item/borg/upgrade/thrusters
name = "ion thruster upgrade"
@@ -598,10 +602,10 @@
R.update_transform()
/obj/item/borg/upgrade/rped
- name = "engineering cyborg RPED"
+ name = "engineering cyborg BSRPED"
desc = "A rapid part exchange device for the engineering cyborg."
icon = 'icons/obj/storage.dmi'
- icon_state = "borgrped"
+ icon_state = "borg_BS_RPED"
require_module = TRUE
module_type = list(/obj/item/robot_module/engineering)
@@ -609,14 +613,21 @@
. = ..()
if(.)
+ var/obj/item/storage/part_replacer/bluespace/cyborg/BSRPED = locate() in R
var/obj/item/storage/part_replacer/cyborg/RPED = locate() in R
- if(RPED)
- to_chat(user, "This unit is already equipped with a RPED module. ")
+ if(!RPED)
+ RPED = locate() in R.module
+ if(!BSRPED)
+ BSRPED = locate() in R.module //There's gotta be a smarter way to do this.
+ if(BSRPED)
+ to_chat(user, "This unit is already equipped with a BSRPED module. ")
return FALSE
- RPED = new(R.module)
- R.module.basic_modules += RPED
- R.module.add_module(RPED, FALSE, TRUE)
+ BSRPED = new(R.module)
+ SEND_SIGNAL(RPED, COMSIG_TRY_STORAGE_QUICK_EMPTY)
+ qdel(RPED)
+ R.module.basic_modules += BSRPED
+ R.module.add_module(BSRPED, FALSE, TRUE)
/obj/item/borg/upgrade/rped/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..()
@@ -680,7 +691,7 @@
action_icon_state = "Chevron_State_0"
var/currentState = 0
- var/maxReduction = 2
+ var/maxReduction = 1
/obj/effect/proc_holder/silicon/cyborg/vtecControl/Click(mob/living/silicon/robot/user)
@@ -688,14 +699,14 @@
currentState = (currentState + 1) % 3
- if(usr)
+ if(istype(self))
switch(currentState)
if (0)
- self.speed = maxReduction
+ self.speed = initial(self.speed)
if (1)
- self.speed -= maxReduction*0.5
+ self.speed = initial(self.speed) - maxReduction * 0.5
if (2)
- self.speed -= maxReduction*1.25
+ self.speed = initial(self.speed) - maxReduction * 1
action.button_icon_state = "Chevron_State_[currentState]"
action.UpdateButtonIcon()
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 5610cbad9a..9f3e5f6bd4 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -17,7 +17,6 @@
var/self_delay = 50
/obj/item/stack/medical/attack(mob/living/M, mob/user)
-
if(M.stat == DEAD && !stop_bleeding)
var/t_him = "it"
if(M.gender == MALE)
@@ -129,7 +128,7 @@
/obj/item/stack/medical/gauze/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/wirecutters) || I.is_sharp())
+ if(istype(I, /obj/item/wirecutters) || I.get_sharpness())
if(get_amount() < 2)
to_chat(user, "You need at least two gauzes to do this! ")
return
diff --git a/code/game/objects/items/stacks/sheets/glass.dm b/code/game/objects/items/stacks/sheets/glass.dm
index 47c881bbdf..c9fc59a3fe 100644
--- a/code/game/objects/items/stacks/sheets/glass.dm
+++ b/code/game/objects/items/stacks/sheets/glass.dm
@@ -25,6 +25,7 @@ GLOBAL_LIST_INIT(glass_recipes, list ( \
merge_type = /obj/item/stack/sheet/glass
grind_results = list(/datum/reagent/silicon = 20)
point_value = 1
+ tableVariant = /obj/structure/table/glass
/obj/item/stack/sheet/glass/suicide_act(mob/living/carbon/user)
user.visible_message("[user] begins to slice [user.p_their()] neck with \the [src]! It looks like [user.p_theyre()] trying to commit suicide! ")
@@ -88,6 +89,7 @@ GLOBAL_LIST_INIT(pglass_recipes, list ( \
resistance_flags = ACID_PROOF
merge_type = /obj/item/stack/sheet/plasmaglass
grind_results = list(/datum/reagent/silicon = 20, /datum/reagent/toxin/plasma = 10)
+ tableVariant = /obj/structure/table/plasmaglass
/obj/item/stack/sheet/plasmaglass/fifty
amount = 50
diff --git a/code/game/objects/items/stacks/sheets/leather.dm b/code/game/objects/items/stacks/sheets/leather.dm
index 01351ab2e2..7297bb3aae 100644
--- a/code/game/objects/items/stacks/sheets/leather.dm
+++ b/code/game/objects/items/stacks/sheets/leather.dm
@@ -219,7 +219,7 @@ GLOBAL_LIST_INIT(sinew_recipes, list ( \
//Step one - dehairing.
/obj/item/stack/sheet/animalhide/attackby(obj/item/W, mob/user, params)
- if(W.is_sharp())
+ if(W.get_sharpness())
playsound(loc, 'sound/weapons/slice.ogg', 50, 1, -1)
user.visible_message("[user] starts cutting hair off \the [src].", "You start cutting the hair off \the [src]... ", "You hear the sound of a knife rubbing against flesh. ")
if(do_after(user, 50, target = src))
diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm
index 7df165461b..96546d6eb6 100644
--- a/code/game/objects/items/stacks/sheets/mineral.dm
+++ b/code/game/objects/items/stacks/sheets/mineral.dm
@@ -178,11 +178,11 @@ GLOBAL_LIST_INIT(plasma_recipes, list ( \
. = ..()
/obj/item/stack/sheet/mineral/plasma/attackby(obj/item/W as obj, mob/user as mob, params)
- if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
+ if(W.get_temperature() > 300)//If the temperature of the object is over 300, then ignite
var/turf/T = get_turf(src)
message_admins("Plasma sheets ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma sheets ignited by [key_name(user)] in [AREACOORD(T)]")
- fire_act(W.is_hot())
+ fire_act(W.get_temperature())
else
return ..()
@@ -232,6 +232,7 @@ GLOBAL_LIST_INIT(gold_recipes, list ( \
grind_results = list("silver" = 20)
point_value = 20
merge_type = /obj/item/stack/sheet/mineral/silver
+ tableVariant = /obj/structure/table/optable
GLOBAL_LIST_INIT(silver_recipes, list ( \
new/datum/stack_recipe("silver door", /obj/structure/mineral_door/silver, 10, one_per_turf = 1, on_floor = 1), \
diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm
index 8c808d0e5f..c085306892 100644
--- a/code/game/objects/items/stacks/sheets/sheet_types.dm
+++ b/code/game/objects/items/stacks/sheets/sheet_types.dm
@@ -107,6 +107,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
merge_type = /obj/item/stack/sheet/metal
grind_results = list("iron" = 20)
point_value = 2
+ tableVariant = /obj/structure/table
/obj/item/stack/sheet/metal/ratvar_act()
new /obj/item/stack/tile/brass(loc, amount)
@@ -168,6 +169,7 @@ GLOBAL_LIST_INIT(plasteel_recipes, list ( \
merge_type = /obj/item/stack/sheet/plasteel
grind_results = list("iron" = 20, "plasma" = 20)
point_value = 23
+ tableVariant = /obj/structure/table/reinforced
/obj/item/stack/sheet/plasteel/Initialize(mapload, new_amount, merge = TRUE)
recipes = GLOB.plasteel_recipes
@@ -474,6 +476,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
novariants = FALSE
grind_results = list("iron" = 5, "teslium" = 15, "holyoil" = 1)
merge_type = /obj/item/stack/tile/brass
+ tableVariant = /obj/structure/table/reinforced/brass
/obj/item/stack/tile/brass/narsie_act()
new /obj/item/stack/sheet/runed_metal(loc, amount)
@@ -526,6 +529,7 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
novariants = FALSE
grind_results = list("iron" = 5, "copper" = 3) //we have no "tin" reagent so this is the closest thing
merge_type = /obj/item/stack/tile/bronze
+ tableVariant = /obj/structure/table/bronze
/obj/item/stack/tile/bronze/attack_self(mob/living/user)
if(is_servant_of_ratvar(user)) //still lets them build with it, just gives a message
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 4217a58f81..7654199cf5 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -22,6 +22,7 @@
var/full_w_class = WEIGHT_CLASS_NORMAL //The weight class the stack should have at amount > 2/3rds max_amount
var/novariants = TRUE //Determines whether the item should update it's sprites based on amount.
//NOTE: When adding grind_results, the amounts should be for an INDIVIDUAL ITEM - these amounts will be multiplied by the stack size in on_grind()
+ var/obj/structure/table/tableVariant // we tables now (stores table variant to be built from this stack)
/obj/item/stack/on_grind()
for(var/i in 1 to grind_results.len) //This should only call if it's ground, so no need to check if grind_results exists
@@ -389,9 +390,9 @@
. = ..()
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
- add_blood_DNA(from.return_blood_DNA())
- add_fingerprint_list(from.return_fingerprints())
- add_hiddenprint_list(from.return_hiddenprints())
+ blood_DNA = from.blood_DNA
+ fingerprints = from.fingerprints
+ fingerprintshidden = from.fingerprintshidden
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
@@ -436,4 +437,4 @@
/datum/stack_recipe_list/New(title, recipes)
src.title = title
- src.recipes = recipes
+ src.recipes = recipes
\ No newline at end of file
diff --git a/code/game/objects/items/stacks/telecrystal.dm b/code/game/objects/items/stacks/telecrystal.dm
index c1fb396529..9b5ca2b066 100644
--- a/code/game/objects/items/stacks/telecrystal.dm
+++ b/code/game/objects/items/stacks/telecrystal.dm
@@ -9,10 +9,11 @@
item_flags = NOBLUDGEON
/obj/item/stack/telecrystal/attack(mob/target, mob/user)
- if(target == user) //You can't go around smacking people with crystals to find out if they have an uplink or not.
- for(var/obj/item/implant/uplink/I in target)
- if(I && I.imp_in)
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, I)
+ if(target == user && isliving(user)) //You can't go around smacking people with crystals to find out if they have an uplink or not.
+ var/mob/living/L = user
+ for(var/obj/item/implant/uplink/I in L.implants)
+ if(I?.imp_in)
+ var/datum/component/uplink/hidden_uplink = I.GetComponent(/datum/component/uplink)
if(hidden_uplink)
hidden_uplink.telecrystals += amount
use(amount)
diff --git a/code/game/objects/items/stacks/tiles/tile_types.dm b/code/game/objects/items/stacks/tiles/tile_types.dm
index 3b28c30402..847e1b521e 100644
--- a/code/game/objects/items/stacks/tiles/tile_types.dm
+++ b/code/game/objects/items/stacks/tiles/tile_types.dm
@@ -99,33 +99,117 @@
icon_state = "tile-carpet"
turf_type = /turf/open/floor/carpet
resistance_flags = FLAMMABLE
-
-/obj/item/stack/tile/carpet/fifty
- amount = 50
+ tableVariant = /obj/structure/table/wood/fancy
/obj/item/stack/tile/carpet/black
name = "black carpet"
icon_state = "tile-carpet-black"
turf_type = /turf/open/floor/carpet/black
+ tableVariant = /obj/structure/table/wood/fancy/black
+
+/obj/item/stack/tile/carpet/blackred
+ name = "red carpet"
+ icon_state = "tile-carpet-blackred"
+ turf_type = /turf/open/floor/carpet/blackred
+ tableVariant = /obj/structure/table/wood/fancy/blackred
+
+/obj/item/stack/tile/carpet/monochrome
+ name = "monochrome carpet"
+ icon_state = "tile-carpet-monochrome"
+ turf_type = /turf/open/floor/carpet/monochrome
+ tableVariant = /obj/structure/table/wood/fancy/monochrome
+
+/obj/item/stack/tile/carpet/blue
+ name = "blue carpet"
+ icon_state = "tile-carpet-blue"
+ item_state = "tile-carpet-blue"
+ turf_type = /turf/open/floor/carpet/blue
+ tableVariant = /obj/structure/table/wood/fancy/blue
+
+/obj/item/stack/tile/carpet/cyan
+ name = "cyan carpet"
+ icon_state = "tile-carpet-cyan"
+ item_state = "tile-carpet-cyan"
+ turf_type = /turf/open/floor/carpet/cyan
+ tableVariant = /obj/structure/table/wood/fancy/cyan
+
+/obj/item/stack/tile/carpet/green
+ name = "green carpet"
+ icon_state = "tile-carpet-green"
+ item_state = "tile-carpet-green"
+ turf_type = /turf/open/floor/carpet/green
+ tableVariant = /obj/structure/table/wood/fancy/green
+
+/obj/item/stack/tile/carpet/orange
+ name = "orange carpet"
+ icon_state = "tile-carpet-orange"
+ item_state = "tile-carpet-orange"
+ turf_type = /turf/open/floor/carpet/orange
+ tableVariant = /obj/structure/table/wood/fancy/orange
+
+/obj/item/stack/tile/carpet/purple
+ name = "purple carpet"
+ icon_state = "tile-carpet-purple"
+ item_state = "tile-carpet-purple"
+ turf_type = /turf/open/floor/carpet/purple
+ tableVariant = /obj/structure/table/wood/fancy/purple
+
+/obj/item/stack/tile/carpet/red
+ name = "red carpet"
+ icon_state = "tile-carpet-red"
+ item_state = "tile-carpet-red"
+ turf_type = /turf/open/floor/carpet/red
+ tableVariant = /obj/structure/table/wood/fancy/red
+
+/obj/item/stack/tile/carpet/royalblack
+ name = "royal black carpet"
+ icon_state = "tile-carpet-royalblack"
+ item_state = "tile-carpet-royalblack"
+ turf_type = /turf/open/floor/carpet/royalblack
+ tableVariant = /obj/structure/table/wood/fancy/royalblack
+
+/obj/item/stack/tile/carpet/royalblue
+ name = "royal blue carpet"
+ icon_state = "tile-carpet-royalblue"
+ item_state = "tile-carpet-royalblue"
+ turf_type = /turf/open/floor/carpet/royalblue
+ tableVariant = /obj/structure/table/wood/fancy/royalblue
+
+/obj/item/stack/tile/carpet/fifty
+ amount = 50
/obj/item/stack/tile/carpet/black/fifty
amount = 50
-/obj/item/stack/tile/carpet/blackred
- name = "red carpet"
- icon_state = "tile-carpet-blackred"
- turf_type = /turf/open/floor/carpet/blackred
-
/obj/item/stack/tile/carpet/blackred/fifty
- amount = 50
-
-/obj/item/stack/tile/carpet/monochrome
- name = "monochrome carpet"
- icon_state = "tile-carpet-monochrome"
- turf_type = /turf/open/floor/carpet/monochrome
+ amount = 50
/obj/item/stack/tile/carpet/monochrome/fifty
- amount = 50
+ amount = 50
+
+/obj/item/stack/tile/carpet/blue/fifty
+ amount = 50
+
+/obj/item/stack/tile/carpet/cyan/fifty
+ amount = 50
+
+/obj/item/stack/tile/carpet/green/fifty
+ amount = 50
+
+/obj/item/stack/tile/carpet/orange/fifty
+ amount = 50
+
+/obj/item/stack/tile/carpet/purple/fifty
+ amount = 50
+
+/obj/item/stack/tile/carpet/red/fifty
+ amount = 50
+
+/obj/item/stack/tile/carpet/royalblack/fifty
+ amount = 50
+
+/obj/item/stack/tile/carpet/royalblue/fifty
+ amount = 50
/obj/item/stack/tile/fakespace
name = "astral carpet"
diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm
index b5d7282b07..a79eb299da 100644
--- a/code/game/objects/items/storage/backpack.dm
+++ b/code/game/objects/items/storage/backpack.dm
@@ -23,7 +23,7 @@
/obj/item/storage/backpack/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 21
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_items = 21
@@ -34,7 +34,7 @@
/obj/item/storage/backpack/old/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 12
/obj/item/storage/backpack/holding
@@ -46,6 +46,7 @@
item_flags = NO_MAT_REDEMPTION
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 50)
component_type = /datum/component/storage/concrete/bluespace/bag_of_holding
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/holding/satchel
name = "satchel of holding"
@@ -53,10 +54,11 @@
icon_state = "holdingsat"
item_state = "holdingsat"
species_exception = list(/datum/species/angel)
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/holding/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.allow_big_nesting = TRUE
STR.max_w_class = WEIGHT_CLASS_GIGANTIC
STR.max_combined_w_class = 35
@@ -81,10 +83,11 @@
icon_state = "giftbag0"
item_state = "giftbag"
w_class = WEIGHT_CLASS_BULKY
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/santabag/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 60
@@ -133,6 +136,8 @@
desc = "It's a special backpack made exclusively for Nanotrasen officers."
icon_state = "captainpack"
item_state = "captainpack"
+ resistance_flags = FIRE_PROOF
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/industrial
name = "industrial backpack"
@@ -140,6 +145,7 @@
icon_state = "engiepack"
item_state = "engiepack"
resistance_flags = FIRE_PROOF
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/botany
name = "botany backpack"
@@ -194,6 +200,8 @@
desc = "A tough satchel with extra pockets."
icon_state = "satchel-eng"
item_state = "engiepack"
+ resistance_flags = FIRE_PROOF
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/satchel/med
name = "medical satchel"
@@ -252,7 +260,7 @@
/obj/item/storage/backpack/satchel/bone/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 20
STR.max_items = 15
@@ -261,6 +269,8 @@
desc = "An exclusive satchel for Nanotrasen officers."
icon_state = "satchel-cap"
item_state = "captainpack"
+ resistance_flags = FIRE_PROOF
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/satchel/flat
name = "smuggler's satchel"
@@ -276,7 +286,7 @@
/obj/item/storage/backpack/satchel/flat/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 6
STR.cant_hold = typecacheof(list(/obj/item/storage/backpack/satchel/flat)) //muh recursive backpacks
@@ -328,7 +338,7 @@
/obj/item/storage/backpack/duffelbag/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 30
/obj/item/storage/backpack/duffelbag/captain
@@ -385,6 +395,8 @@
desc = "A large duffel bag for holding extra tools and supplies."
icon_state = "duffel-eng"
item_state = "duffel-eng"
+ resistance_flags = FIRE_PROOF
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/duffelbag/durathread
name = "durathread duffel bag"
@@ -400,6 +412,7 @@
icon_state = "duffel-drone"
item_state = "duffel-drone"
resistance_flags = FIRE_PROOF
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/duffelbag/drone/PopulateContents()
new /obj/item/screwdriver(src)
@@ -427,10 +440,11 @@
icon_state = "duffel-syndie"
item_state = "duffel-syndieammo"
slowdown = 0
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/backpack/duffelbag/syndie/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.silent = TRUE
/obj/item/storage/backpack/duffelbag/syndie/hitman
@@ -479,12 +493,9 @@
desc = "A large duffel bag for holding surgical tools. Bears the logo of an advanced med-tech firm."
/obj/item/storage/backpack/duffelbag/syndie/surgery_adv/PopulateContents()
- new /obj/item/hemostat/adv(src)
- new /obj/item/circular_saw/adv(src)
- new /obj/item/scalpel/adv(src)
- new /obj/item/retractor/adv(src)
- new /obj/item/cautery/adv(src)
- new /obj/item/surgicaldrill/adv(src)
+ new /obj/item/scalpel/advanced(src)
+ new /obj/item/retractor/advanced(src)
+ new /obj/item/surgicaldrill/advanced(src)
new /obj/item/surgical_drapes(src)
new /obj/item/storage/firstaid/tactical(src)
new /obj/item/clothing/suit/straight_jacket(src)
@@ -583,7 +594,7 @@
// For ClownOps.
/obj/item/storage/backpack/duffelbag/clown/syndie/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
slowdown = 0
STR.silent = TRUE
diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm
index e4debeff49..eafa79798e 100644
--- a/code/game/objects/items/storage/bags.dm
+++ b/code/game/objects/items/storage/bags.dm
@@ -21,7 +21,7 @@
/obj/item/storage/bag/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.allow_quick_gather = TRUE
STR.allow_quick_empty = TRUE
STR.display_numerical_stacking = TRUE
@@ -44,11 +44,13 @@
/obj/item/storage/bag/trash/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_combined_w_class = 30
STR.max_items = 30
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear))
+ STR.limited_random_access = TRUE
+ STR.limited_random_access_stack_position = 3
/obj/item/storage/bag/trash/suicide_act(mob/user)
user.visible_message("[user] puts [src] over [user.p_their()] head and starts chomping at the insides! Disgusting! ")
@@ -81,12 +83,14 @@
desc = "The latest and greatest in custodial convenience, a trashbag that is capable of holding vast quantities of garbage."
icon_state = "bluetrashbag"
item_flags = NO_MAT_REDEMPTION
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/bag/trash/bluespace/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 60
STR.max_items = 60
+ STR.limited_random_access_stack_position = 5
/obj/item/storage/bag/trash/bluespace/cyborg
insertable = FALSE
@@ -104,11 +108,12 @@
w_class = WEIGHT_CLASS_NORMAL
component_type = /datum/component/storage/concrete/stack
var/spam_protection = FALSE //If this is TRUE, the holder won't receive any messages when they fail to pick up ore through crossing it
- var/datum/component/mobhook
+ var/mob/listeningTo
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/bag/ore/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.allow_quick_empty = TRUE
STR.can_hold = typecacheof(list(/obj/item/stack/ore))
STR.max_w_class = WEIGHT_CLASS_HUGE
@@ -116,15 +121,17 @@
/obj/item/storage/bag/ore/equipped(mob/user)
. = ..()
- if (mobhook && mobhook.parent != user)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/Pickup_ores)))
+ if(listeningTo == user)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/Pickup_ores)
+ listeningTo = user
/obj/item/storage/bag/ore/dropped()
. = ..()
- if (mobhook)
- QDEL_NULL(mobhook)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
/obj/item/storage/bag/ore/proc/Pickup_ores(mob/living/user)
var/show_message = FALSE
@@ -134,7 +141,7 @@
return
if (istype(user.pulling, /obj/structure/ore_box))
box = user.pulling
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
if(STR)
for(var/A in tile)
if (!is_type_in_typecache(A, STR.can_hold))
@@ -164,7 +171,7 @@
/obj/item/storage/bag/ore/cyborg/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.allow_quick_empty = TRUE
STR.can_hold = typecacheof(list(/obj/item/stack/ore))
STR.max_w_class = WEIGHT_CLASS_HUGE
@@ -176,7 +183,7 @@
/obj/item/storage/bag/ore/large/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.allow_quick_empty = TRUE
STR.can_hold = typecacheof(list(/obj/item/stack/ore))
STR.max_w_class = WEIGHT_CLASS_HUGE
@@ -189,7 +196,7 @@
/obj/item/storage/bag/ore/holding/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.max_items = INFINITY
STR.max_combined_w_class = INFINITY
STR.max_combined_stack_amount = INFINITY
@@ -207,7 +214,7 @@
/obj/item/storage/bag/plants/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 100
STR.max_items = 100
@@ -247,7 +254,7 @@
/obj/item/storage/bag/sheetsnatcher/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.allow_quick_empty = TRUE
STR.can_hold = typecacheof(list(/obj/item/stack/sheet))
STR.cant_hold = typecacheof(list(/obj/item/stack/sheet/mineral/sandstone, /obj/item/stack/sheet/mineral/wood))
@@ -264,7 +271,7 @@
/obj/item/storage/bag/sheetsnatcher/borg/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage/concrete/stack)
+ var/datum/component/storage/concrete/stack/STR = GetComponent(/datum/component/storage/concrete/stack)
STR.max_combined_stack_amount = 500
// -----------------------------
@@ -281,7 +288,7 @@
/obj/item/storage/bag/books/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 21
STR.max_items = 7
@@ -306,15 +313,14 @@
/obj/item/storage/bag/tray/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.insert_preposition = "on"
/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user)
. = ..()
// Drop all the things. All of them.
var/list/obj/item/oldContents = contents.Copy()
- GET_COMPONENT(STR, /datum/component/storage)
- STR.quick_empty()
+ SEND_SIGNAL(src, COMSIG_TRY_STORAGE_QUICK_EMPTY)
// Make each item scatter a bit
for(var/obj/item/I in oldContents)
spawn()
@@ -360,11 +366,11 @@
/obj/item/storage/bag/chemistry/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 200
STR.max_items = 50
STR.insert_preposition = "in"
- STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle))
+ STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/reagent_containers/glass/beaker, /obj/item/reagent_containers/glass/bottle, /obj/item/reagent_containers/syringe/dart))
/*
* Biowaste bag (mostly for xenobiologists)
@@ -380,7 +386,7 @@
/obj/item/storage/bag/bio/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 200
STR.max_items = 25
STR.insert_preposition = "in"
@@ -391,9 +397,10 @@
icon = 'icons/obj/chemical.dmi'
icon_state = "bspace_biobag"
desc = "A bag for the safe transportation and disposal of biowaste and other biological materials."
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/bag/bio/holding/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = INFINITY
STR.max_items = 100
diff --git a/code/game/objects/items/storage/belt.dm b/code/game/objects/items/storage/belt.dm
index 4495e9da14..713dbe4133 100755
--- a/code/game/objects/items/storage/belt.dm
+++ b/code/game/objects/items/storage/belt.dm
@@ -40,10 +40,11 @@
icon_state = "utilitybelt"
item_state = "utility"
content_overlays = TRUE
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //because this is easier than trying to have showers wash all contents.
/obj/item/storage/belt/utility/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
var/static/list/can_hold = typecacheof(list(
/obj/item/crowbar,
/obj/item/screwdriver,
@@ -126,7 +127,7 @@
/obj/item/storage/belt/medical/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.can_hold = typecacheof(list(
/obj/item/healthanalyzer,
@@ -184,12 +185,9 @@
content_overlays = FALSE
/obj/item/storage/belt/medical/surgery_belt_adv/PopulateContents()
- new /obj/item/hemostat/adv(src)
- new /obj/item/circular_saw/adv(src)
- new /obj/item/scalpel/adv(src)
- new /obj/item/retractor/adv(src)
- new /obj/item/cautery/adv(src)
- new /obj/item/surgicaldrill/adv(src)
+ new /obj/item/scalpel/advanced(src)
+ new /obj/item/retractor/advanced(src)
+ new /obj/item/surgicaldrill/advanced(src)
new /obj/item/surgical_drapes(src)
/obj/item/storage/belt/security
@@ -201,7 +199,7 @@
/obj/item/storage/belt/security/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 5
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.can_hold = typecacheof(list(
@@ -240,7 +238,7 @@
/obj/item/storage/belt/mining/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 20
@@ -299,7 +297,7 @@
/obj/item/storage/belt/mining/primitive/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 5
/obj/item/storage/belt/soulstone
@@ -310,7 +308,7 @@
/obj/item/storage/belt/soulstone/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(
/obj/item/soulstone
@@ -333,7 +331,7 @@
/obj/item/storage/belt/champion/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 1
STR.can_hold = list(
/obj/item/clothing/mask/luchador
@@ -344,10 +342,11 @@
desc = "A set of tactical webbing worn by Syndicate boarding parties."
icon_state = "militarywebbing"
item_state = "militarywebbing"
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/belt/military/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
/obj/item/storage/belt/military/snack
@@ -360,7 +359,7 @@
/obj/item/storage/belt/military/snack/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.can_hold = typecacheof(list(
@@ -428,7 +427,7 @@
/obj/item/storage/belt/military/assault/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
/obj/item/storage/belt/durathread
@@ -481,7 +480,7 @@
/obj/item/storage/belt/grenade/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 30
STR.display_numerical_stacking = TRUE
STR.max_combined_w_class = 60
@@ -530,10 +529,11 @@
desc = "A belt designed to hold various rods of power. A veritable fanny pack of exotic magic."
icon_state = "soulstonebelt"
item_state = "soulstonebelt"
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/storage/belt/wands/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(
/obj/item/gun/magic/wand
@@ -559,7 +559,7 @@
/obj/item/storage/belt/janitor/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.max_w_class = WEIGHT_CLASS_BULKY // Set to this so the light replacer can fit.
STR.can_hold = typecacheof(list(
@@ -586,7 +586,7 @@
/obj/item/storage/belt/bandolier/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 18
STR.display_numerical_stacking = TRUE
STR.can_hold = typecacheof(list(
@@ -599,10 +599,10 @@
icon_state = "bandolier-durathread"
item_state = "bandolier-durathread"
resistance_flags = FIRE_PROOF
-
+
/obj/item/storage/belt/bandolier/durathread/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 32
STR.display_numerical_stacking = TRUE
STR.can_hold = typecacheof(list(
@@ -617,9 +617,12 @@
/obj/item/storage/belt/medolier/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 15
STR.display_numerical_stacking = FALSE
+ STR.allow_quick_gather = TRUE
+ STR.allow_quick_empty = TRUE
+ STR.click_gather = TRUE
STR.can_hold = typecacheof(list(
/obj/item/reagent_containers/syringe/dart
))
@@ -628,6 +631,25 @@
for(var/i in 1 to 16)
new /obj/item/reagent_containers/syringe/dart/(src)
+/obj/item/storage/belt/medolier/afterattack(obj/target, mob/user , proximity)
+ if(!(istype(target, /obj/item/reagent_containers/glass/beaker)))
+ return
+ if(!proximity)
+ return
+ if(!target.reagents)
+ return
+
+ for(var/obj/item/reagent_containers/syringe/dart/D in contents)
+ if(round(target.reagents.total_volume, 1) <= 0)
+ to_chat(user, "You soak as many of the darts as you can with the contents from [target]. ")
+ return
+ if(D.mode == SYRINGE_INJECT)
+ continue
+
+ D.afterattack(target, user, proximity)
+
+ ..()
+
/obj/item/storage/belt/holster
name = "shoulder holster"
desc = "A holster to carry a handgun and ammo. WARNING: Badasses only."
@@ -637,7 +659,7 @@
/obj/item/storage/belt/holster/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 3
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.can_hold = typecacheof(list(
@@ -661,7 +683,7 @@
/obj/item/storage/belt/fannypack/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 3
STR.max_w_class = WEIGHT_CLASS_SMALL
@@ -728,7 +750,7 @@
/obj/item/storage/belt/sabre/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 1
STR.rustle_sound = FALSE
STR.max_w_class = WEIGHT_CLASS_BULKY
diff --git a/code/game/objects/items/storage/book.dm b/code/game/objects/items/storage/book.dm
index df7b203f91..c658eee3d5 100644
--- a/code/game/objects/items/storage/book.dm
+++ b/code/game/objects/items/storage/book.dm
@@ -11,7 +11,7 @@
/obj/item/storage/book/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 1
/obj/item/storage/book/attack_self(mob/user)
@@ -140,7 +140,7 @@ GLOBAL_LIST_INIT(bibleitemstates, list("bible", "koran", "scrapbook", "bible",
else if(iscarbon(M))
var/mob/living/carbon/C = M
if(!istype(C.head, /obj/item/clothing/head))
- C.adjustBrainLoss(10, 80)
+ C.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 80)
to_chat(C, "You feel dumber. ")
if(smack)
diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm
index 903c319644..e053ff2a5c 100644
--- a/code/game/objects/items/storage/boxes.dm
+++ b/code/game/objects/items/storage/boxes.dm
@@ -33,6 +33,7 @@
resistance_flags = FLAMMABLE
var/foldable = /obj/item/stack/sheet/cardboard
var/illustration = "writing"
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //exploits ahoy
/obj/item/storage/box/Initialize(mapload)
. = ..()
@@ -397,7 +398,7 @@
/obj/item/storage/box/donkpockets/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/donkpocket))
/obj/item/storage/box/donkpockets/PopulateContents()
@@ -412,7 +413,7 @@
/obj/item/storage/box/monkeycubes/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 7
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/monkeycube))
@@ -567,7 +568,7 @@
/obj/item/storage/box/snappops/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/toy/snappop))
STR.max_items = 8
@@ -585,7 +586,7 @@
/obj/item/storage/box/matches/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 10
STR.can_hold = typecacheof(list(/obj/item/match))
@@ -608,7 +609,7 @@
/obj/item/storage/box/lights/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 21
STR.can_hold = typecacheof(list(/obj/item/light/tube, /obj/item/light/bulb))
STR.max_combined_w_class = 21
@@ -854,7 +855,7 @@
if(SMILEY)
desc = "A paper sack with a crude smile etched onto the side."
return 0
- else if(W.is_sharp())
+ else if(W.get_sharpness())
if(!contents.len)
if(item_state == "paperbag_None")
user.show_message("You cut eyeholes into [src]. ", 1)
@@ -1143,7 +1144,7 @@
if(can_expire)
expiration_date = rand(expiration_date_min, expiration_date_max)
desc += "\nAn expiry date is listed on it. It reads: [expiration_date] "
- var/spess_current_year = GLOB.year_integer + 540
+ var/spess_current_year = GLOB.year_integer
if(expiration_date < spess_current_year)
var/gross_risk = min(round(spess_current_year - expiration_date * 0.1), 1)
var/toxic_risk = min(round(spess_current_year - expiration_date * 0.01), 1)
diff --git a/code/game/objects/items/storage/briefcase.dm b/code/game/objects/items/storage/briefcase.dm
index ed547bc17d..782ffd3add 100644
--- a/code/game/objects/items/storage/briefcase.dm
+++ b/code/game/objects/items/storage/briefcase.dm
@@ -17,7 +17,7 @@
/obj/item/storage/briefcase/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 21
@@ -48,7 +48,7 @@
/obj/item/storage/briefcase/lawyer/family/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 14
diff --git a/code/game/objects/items/storage/dakis.dm b/code/game/objects/items/storage/dakis.dm
index 08748bf37e..2703581a94 100644
--- a/code/game/objects/items/storage/dakis.dm
+++ b/code/game/objects/items/storage/dakis.dm
@@ -13,7 +13,7 @@
/obj/item/storage/daki/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_combined_w_class = 21
STR.max_items = 3
diff --git a/code/game/objects/items/storage/fancy.dm b/code/game/objects/items/storage/fancy.dm
index 95639918bb..44e122e4b9 100644
--- a/code/game/objects/items/storage/fancy.dm
+++ b/code/game/objects/items/storage/fancy.dm
@@ -25,7 +25,7 @@
var/fancy_open = FALSE
/obj/item/storage/fancy/PopulateContents()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
for(var/i = 1 to STR.max_items)
new spawn_type(src)
@@ -72,7 +72,7 @@
/obj/item/storage/fancy/donut_box/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/donut))
@@ -93,7 +93,7 @@
/obj/item/storage/fancy/egg_box/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 12
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/egg))
@@ -115,7 +115,7 @@
/obj/item/storage/fancy/candle_box/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 5
/obj/item/storage/fancy/candle_box/attack_self(mob_user)
@@ -138,7 +138,7 @@
/obj/item/storage/fancy/cigarettes/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(/obj/item/clothing/mask/cigarette, /obj/item/lighter))
@@ -276,7 +276,7 @@
/obj/item/storage/fancy/rollingpapers/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 10
STR.can_hold = typecacheof(list(/obj/item/rollingpaper))
@@ -300,7 +300,7 @@
/obj/item/storage/fancy/cigarettes/cigars/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 5
STR.can_hold = typecacheof(list(/obj/item/clothing/mask/cigarette/cigar))
@@ -309,9 +309,10 @@
if(fancy_open)
icon_state = "[initial(icon_state)]_open"
- var/cigar_position = 1 //generate sprites for cigars in the box
+ var/cigar_position = 0 //to keep track of the pixel_x offset of each new overlay.
for(var/obj/item/clothing/mask/cigarette/cigar/smokes in contents)
- var/mutable_appearance/cigar_overlay = mutable_appearance(icon, "[smokes.icon_off]_[cigar_position]")
+ var/mutable_appearance/cigar_overlay = mutable_appearance(icon, "[smokes.icon_off]")
+ cigar_overlay.pixel_x = 3 * cigar_position
add_overlay(cigar_overlay)
cigar_position++
@@ -347,6 +348,6 @@
/obj/item/storage/fancy/heart_box/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 8
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/tinychocolate))
diff --git a/code/game/objects/items/storage/firstaid.dm b/code/game/objects/items/storage/firstaid.dm
index 312ef35430..822a1d5011 100644
--- a/code/game/objects/items/storage/firstaid.dm
+++ b/code/game/objects/items/storage/firstaid.dm
@@ -170,7 +170,7 @@
/obj/item/storage/firstaid/tactical/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
/obj/item/storage/firstaid/tactical/PopulateContents()
@@ -200,7 +200,7 @@
/obj/item/storage/pill_bottle/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.allow_quick_gather = TRUE
STR.click_gather = TRUE
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/pill, /obj/item/dice))
@@ -337,7 +337,7 @@
/obj/item/storage/pill_bottle/penis_enlargement/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/reagent_containers/pill/penis_enlargement(src)
-
+
/obj/item/storage/pill_bottle/breast_enlargement
name = "breast enlargement pills"
desc = "Made by Fermichem - They have a woman with breasts larger than she is on them. The warming states not to take more than 10u at a time."
@@ -363,7 +363,7 @@
/obj/item/storage/belt/organbox/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 16
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 20
diff --git a/code/game/objects/items/storage/lockbox.dm b/code/game/objects/items/storage/lockbox.dm
index eeebc6f4c5..1607b19c2f 100644
--- a/code/game/objects/items/storage/lockbox.dm
+++ b/code/game/objects/items/storage/lockbox.dm
@@ -15,7 +15,7 @@
/obj/item/storage/lockbox/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 14
STR.max_items = 4
@@ -101,7 +101,7 @@
/obj/item/storage/lockbox/medal/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_items = 10
STR.max_combined_w_class = 20
diff --git a/code/game/objects/items/storage/secure.dm b/code/game/objects/items/storage/secure.dm
index 20dae54a71..8618e4c3ae 100644
--- a/code/game/objects/items/storage/secure.dm
+++ b/code/game/objects/items/storage/secure.dm
@@ -26,7 +26,7 @@
/obj/item/storage/secure/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_combined_w_class = 14
@@ -136,7 +136,7 @@
/obj/item/storage/secure/briefcase/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 21
STR.max_w_class = WEIGHT_CLASS_NORMAL
@@ -146,7 +146,7 @@
/obj/item/storage/secure/briefcase/syndie/PopulateContents()
..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
for(var/i = 0, i < STR.max_items - 2, i++)
new /obj/item/stack/spacecash/c1000(src)
@@ -170,7 +170,7 @@
/obj/item/storage/secure/safe/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.cant_hold = typecacheof(list(/obj/item/storage/secure/briefcase))
STR.max_w_class = 8 //??
diff --git a/code/game/objects/items/storage/toolbox.dm b/code/game/objects/items/storage/toolbox.dm
index 5b99bb85bf..251703f907 100644
--- a/code/game/objects/items/storage/toolbox.dm
+++ b/code/game/objects/items/storage/toolbox.dm
@@ -19,6 +19,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
var/latches = "single_latch"
var/has_latches = TRUE
var/can_rubberify = TRUE
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //very protecc too
/obj/item/storage/toolbox/Initialize(mapload)
. = ..()
@@ -34,6 +35,8 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/update_icon()
..()
cut_overlays()
+ if(blood_DNA && blood_DNA.len)
+ add_blood_overlay()
if(has_latches)
var/icon/I = icon('icons/obj/storage.dmi', latches)
add_overlay(I)
@@ -121,7 +124,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/syndicate/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.silent = TRUE
/obj/item/storage/toolbox/syndicate/PopulateContents()
@@ -162,7 +165,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/brass/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_combined_w_class = 28
STR.max_items = 28
@@ -217,7 +220,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/artistic/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 20
STR.max_items = 10
@@ -255,7 +258,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/gold_real/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_combined_w_class = 40
STR.max_items = 12
diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm
index cf5d685b4a..84ebc28afa 100644
--- a/code/game/objects/items/storage/uplink_kits.dm
+++ b/code/game/objects/items/storage/uplink_kits.dm
@@ -220,7 +220,7 @@
/obj/item/storage/box/syndie_kit/space/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.can_hold = typecacheof(list(/obj/item/clothing/suit/space/syndicate, /obj/item/clothing/head/helmet/space/syndicate))
@@ -244,7 +244,7 @@
/obj/item/storage/box/syndie_kit/chemical/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 14
/obj/item/storage/box/syndie_kit/chemical/PopulateContents()
diff --git a/code/game/objects/items/storage/wallets.dm b/code/game/objects/items/storage/wallets.dm
index cb5790e45f..7a6899ad15 100644
--- a/code/game/objects/items/storage/wallets.dm
+++ b/code/game/objects/items/storage/wallets.dm
@@ -11,7 +11,7 @@
/obj/item/storage/wallet/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 4
STR.cant_hold = typecacheof(list(/obj/item/screwdriver/power))
STR.can_hold = typecacheof(list(
diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm
index bfe630ba01..ee126971a7 100644
--- a/code/game/objects/items/stunbaton.dm
+++ b/code/game/objects/items/stunbaton.dm
@@ -1,4 +1,5 @@
#define STUNBATON_CHARGE_LENIENCY 0.3
+#define STUNBATON_DEPLETION_RATE 0.006
/obj/item/melee/baton
name = "stunbaton"
@@ -76,7 +77,7 @@
update_icon()
/obj/item/melee/baton/process()
- deductcharge(hitcost * 0.004, FALSE, FALSE)
+ deductcharge(round(hitcost * STUNBATON_DEPLETION_RATE), FALSE, FALSE)
/obj/item/melee/baton/update_icon()
if(status)
@@ -250,4 +251,5 @@
sparkler?.activate()
. = ..()
-#undef STUNBATON_CHARGE_LENIENCY
\ No newline at end of file
+#undef STUNBATON_CHARGE_LENIENCY
+#undef STUNBATON_DEPLETION_RATE
diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm
index b672eb01ca..f592055338 100644
--- a/code/game/objects/items/tanks/jetpack.dm
+++ b/code/game/objects/items/tanks/jetpack.dm
@@ -17,7 +17,7 @@
/obj/item/tank/jetpack/New()
..()
if(gas_type)
- air_contents.gases[gas_type] = (6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)
+ air_contents.gases[gas_type] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C))
ion_trail = new
ion_trail.set_up(src)
@@ -37,42 +37,50 @@
return
if(!on)
- turn_on()
+ turn_on(user)
to_chat(user, "You turn the jetpack on. ")
else
- turn_off()
+ turn_off(user)
to_chat(user, "You turn the jetpack off. ")
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
-/obj/item/tank/jetpack/proc/turn_on()
+/obj/item/tank/jetpack/proc/turn_on(mob/user)
on = TRUE
icon_state = "[initial(icon_state)]-on"
ion_trail.start()
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/move_react)
+ if(full_speed)
+ user.add_movespeed_modifier(MOVESPEED_ID_JETPACK, priority=100, multiplicative_slowdown=-2, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK)
-/obj/item/tank/jetpack/proc/turn_off()
+/obj/item/tank/jetpack/proc/turn_off(mob/user)
on = FALSE
stabilizers = FALSE
icon_state = initial(icon_state)
ion_trail.stop()
+ UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
+ user.remove_movespeed_modifier(MOVESPEED_ID_JETPACK)
+
+/obj/item/tank/jetpack/proc/move_react(mob/user)
+ allow_thrust(0.01, user)
/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user)
if(!on)
return
if((num < 0.005 || air_contents.total_moles() < num))
- turn_off()
+ turn_off(user)
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
- turn_off()
+ turn_off(user)
return
var/turf/T = get_turf(user)
T.assume_air(removed)
- return 1
+ return TRUE
/obj/item/tank/jetpack/suicide_act(mob/user)
if (istype(user, /mob/living/carbon/human/))
@@ -96,22 +104,22 @@
if(!on)
return
if((num < 0.005 || air_contents.total_moles() < num))
- turn_off()
+ turn_off(user)
return
if(rand(0,250) == 0)
to_chat(user, "You feel your jetpack's engines cut out. ")
- turn_off()
+ turn_off(user)
return
var/datum/gas_mixture/removed = air_contents.remove(num)
if(removed.total_moles() < 0.005)
- turn_off()
+ turn_off(user)
return
var/turf/T = get_turf(user)
T.assume_air(removed)
- return 1
+ return TRUE
/obj/item/tank/jetpack/void
name = "void jetpack (oxygen)"
@@ -178,6 +186,7 @@
full_speed = FALSE
var/datum/gas_mixture/temp_air_contents
var/obj/item/tank/internals/tank = null
+ var/mob/living/carbon/human/cur_user
/obj/item/tank/jetpack/suit/New()
..()
@@ -198,28 +207,30 @@
return
..()
-/obj/item/tank/jetpack/suit/turn_on()
- if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
+/obj/item/tank/jetpack/suit/turn_on(mob/user)
+ if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc) || loc.loc != user)
return
- var/mob/living/carbon/human/H = loc.loc
+ var/mob/living/carbon/human/H = user
tank = H.s_store
air_contents = tank.air_contents
START_PROCESSING(SSobj, src)
+ cur_user = user
..()
-/obj/item/tank/jetpack/suit/turn_off()
+/obj/item/tank/jetpack/suit/turn_off(mob/user)
tank = null
air_contents = temp_air_contents
STOP_PROCESSING(SSobj, src)
+ cur_user = null
..()
/obj/item/tank/jetpack/suit/process()
if(!istype(loc, /obj/item/clothing/suit/space/hardsuit) || !ishuman(loc.loc))
- turn_off()
+ turn_off(cur_user)
return
var/mob/living/carbon/human/H = loc.loc
if(!tank || tank != H.s_store)
- turn_off()
+ turn_off(cur_user)
return
..()
diff --git a/code/game/objects/items/tanks/watertank.dm b/code/game/objects/items/tanks/watertank.dm
index 8f2b85098d..f3be8cefc8 100644
--- a/code/game/objects/items/tanks/watertank.dm
+++ b/code/game/objects/items/tanks/watertank.dm
@@ -24,7 +24,7 @@
/obj/item/watertank/ui_action_click(mob/user)
toggle_mister(user)
-/obj/item/watertank/item_action_slot_check(slot, mob/user)
+/obj/item/watertank/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == user.getBackSlot())
return 1
@@ -341,7 +341,7 @@
/obj/item/reagent_containers/chemtank/ui_action_click()
toggle_injection()
-/obj/item/reagent_containers/chemtank/item_action_slot_check(slot, mob/user)
+/obj/item/reagent_containers/chemtank/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_BACK)
return 1
diff --git a/code/game/objects/items/teleportation.dm b/code/game/objects/items/teleportation.dm
index 1ccc88d892..e16b0dd690 100644
--- a/code/game/objects/items/teleportation.dm
+++ b/code/game/objects/items/teleportation.dm
@@ -75,15 +75,14 @@
temp += "Implant Signals: "
for (var/obj/item/implant/tracking/W in GLOB.tracked_implants)
- if (!W.imp_in || !isliving(W.loc))
+ if (!isliving(W.imp_in))
continue
- else
- var/mob/living/M = W.loc
- if (M.stat == DEAD)
- if (M.timeofdeath + 6000 < world.time)
- continue
+ var/mob/living/M = W.imp_in
+ if (M.stat == DEAD)
+ if (M.timeofdeath + 6000 < world.time)
+ continue
- var/turf/tr = get_turf(W)
+ var/turf/tr = get_turf(M)
if (tr.z == sr.z && tr)
var/direct = max(abs(tr.x - sr.x), abs(tr.y - sr.y))
if (direct < 20)
@@ -188,8 +187,13 @@
user.show_message("\The [src] is recharging! ")
return
var/atom/T = L[t1]
+ var/implantcheckmate = FALSE
+ if(isliving(T))
+ var/mob/living/M = T
+ if(!locate(/obj/item/implant/tracking) in M.implants) //The user was too slow and let the target mob's tracking implant expire or get removed.
+ implantcheckmate = TRUE
var/area/A = get_area(T)
- if(A.noteleport)
+ if(A.noteleport || implantcheckmate)
to_chat(user, "\The [src] is malfunctioning. ")
return
current_location = get_turf(user) //Recheck.
diff --git a/code/game/objects/items/teleprod.dm b/code/game/objects/items/teleprod.dm
index 40392c19c3..f427bf6c4c 100644
--- a/code/game/objects/items/teleprod.dm
+++ b/code/game/objects/items/teleprod.dm
@@ -6,11 +6,11 @@
item_state = "teleprod"
slot_flags = null
-/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/carbon/M, mob/living/carbon/user)//handles making things teleport when hit
+/obj/item/melee/baton/cattleprod/teleprod/baton_stun(mob/living/L, mob/living/carbon/user)//handles making things teleport when hit
. = ..()
- if(!. || !istype(M) || M.anchored)
+ if(!. || L.anchored)
return
- do_teleport(M, get_turf(M), 15, channel = TELEPORT_CHANNEL_BLUESPACE)
+ do_teleport(L, get_turf(L), 15, channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/item/melee/baton/cattleprod/teleprod/clowning_around(mob/living/user)
user.visible_message("[user] accidentally hits [user.p_them()]self with [src]! ", \
diff --git a/code/game/objects/items/theft_tools.dm b/code/game/objects/items/theft_tools.dm
index 0c74f610df..d52c280f1b 100644
--- a/code/game/objects/items/theft_tools.dm
+++ b/code/game/objects/items/theft_tools.dm
@@ -49,6 +49,10 @@
lefthand_file = 'icons/mob/inhands/misc/sheets_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/sheets_righthand.dmi'
var/obj/item/nuke_core/core
+ var/nt =FALSE //For the lid
+
+/obj/item/nuke_core_container/nt
+ nt = TRUE
/obj/item/nuke_core_container/Destroy()
QDEL_NULL(core)
@@ -67,10 +71,13 @@
/obj/item/nuke_core_container/proc/seal()
if(istype(core))
STOP_PROCESSING(SSobj, core)
- icon_state = "core_container_sealed"
playsound(src, 'sound/items/deconstruct.ogg', 60, 1)
if(ismob(loc))
to_chat(loc, "[src] is permanently sealed, [core]'s radiation is contained. ")
+ if(nt != TRUE)
+ icon_state = "core_container_sealed"
+ else
+ icon_state = "core_container_sealed_nt"
/obj/item/nuke_core_container/attackby(obj/item/nuke_core/core, mob/user)
if(istype(core))
@@ -92,6 +99,11 @@
toolspeed = 0.5
random_color = FALSE
+/obj/item/screwdriver/nuke/nt
+ desc = "A screwdriver with an ultra thin diamon tip."
+ toolspeed = 0.25
+ icon_state = "screwdriver_nt"
+
/obj/item/paper/guides/antag/nuke_instructions
info = "How to break into a Nanotrasen self-destruct terminal and remove its plutonium core: \
\
@@ -103,6 +115,18 @@
??? \
"
+/obj/item/paper/guides/nt/nuke_instructions
+ info = "How to remove its plutonium core: \
+ \
+ Use a screwdriver with a very thin tip (provided) to unscrew the terminal's front panel \
+ Dislodge and remove the front panel with a crowbar \
+ Cut the inner metal plate with a welding tool \
+ Pry off the inner plate with a crowbar to expose the radioactive core \
+ Use the core container to remove the plutonium core; the container will take some time to seal \
+ Send core back to CC \
+ "
+
+
// STEALING SUPERMATTER
/obj/item/paper/guides/antag/supermatter_sliver
@@ -232,7 +256,7 @@
. = ..()
if(!sliver)
return
- if(ismovableatom(O) && O != sliver)
+ if(proximity && ismovableatom(O) && O != sliver)
Consume(O, user)
/obj/item/hemostat/supermatter/throw_impact(atom/hit_atom) // no instakill supermatter javelins
diff --git a/code/game/objects/items/tools/weldingtool.dm b/code/game/objects/items/tools/weldingtool.dm
index fb38e4335e..b04d96dc80 100644
--- a/code/game/objects/items/tools/weldingtool.dm
+++ b/code/game/objects/items/tools/weldingtool.dm
@@ -223,7 +223,7 @@
..()
to_chat(user, "It contains [get_fuel()] unit\s of fuel out of [max_fuel].")
-/obj/item/weldingtool/is_hot()
+/obj/item/weldingtool/get_temperature()
return welding * heat
//Returns whether or not the welding tool is currently on.
diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm
index 46fabea8b0..de5a53fd9c 100644
--- a/code/game/objects/items/toys.dm
+++ b/code/game/objects/items/toys.dm
@@ -79,7 +79,7 @@
to_chat(user, "You fill the balloon with the contents of [I]. ")
I.reagents.trans_to(src, 10)
update_icon()
- else if(I.is_sharp())
+ else if(I.get_sharpness())
balloon_burst()
else
return ..()
@@ -276,6 +276,106 @@
/obj/item/toy/sword/getweight()
return (active ? total_mass_on : total_mass) || w_class *1.25
+/obj/item/toy/sword/cx
+ name = "\improper DX Non-Euplastic LightSword"
+ desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up."
+ icon = 'icons/obj/items_and_weapons.dmi'
+ icon_state = "cxsword_hilt"
+ item_state = "cxsword"
+ active = FALSE
+ w_class = WEIGHT_CLASS_SMALL
+ attack_verb = list("poked", "jabbed", "hit")
+ light_color = "#37FFF7"
+ var/light_brightness = 3
+ actions_types = list()
+
+/obj/item/toy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
+ altafterattack(A, user, TRUE, params)
+ return TRUE
+
+/obj/item/toy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
+ if(istype(user))
+ user.visible_message("[user] points the tip of [src] at [target]. ", "You point the tip of [src] at [target]. ")
+ return TRUE
+
+/obj/item/toy/sword/cx/attack_self(mob/user)
+ active = !( active )
+
+ if (active)
+ to_chat(user, "You activate the holographic blade with a press of a button. ")
+ playsound(user, 'sound/weapons/nebon.ogg', 50, 1)
+ w_class = WEIGHT_CLASS_BULKY
+ attack_verb = list("slashed", "stabbed", "ravaged")
+ set_light(light_brightness)
+ update_icon()
+
+ else
+ to_chat(user, "You deactivate the holographic blade with a press of a button. ")
+ playsound(user, 'sound/weapons/neboff.ogg', 50, 1)
+ w_class = WEIGHT_CLASS_SMALL
+ attack_verb = list("poked", "jabbed", "hit")
+ set_light(0)
+ update_icon()
+
+ add_fingerprint(user)
+
+/obj/item/toy/sword/cx/update_icon()
+ var/mutable_appearance/blade_overlay = mutable_appearance(icon, "cxsword_blade")
+ var/mutable_appearance/gem_overlay = mutable_appearance(icon, "cxsword_gem")
+
+ if(light_color)
+ blade_overlay.color = light_color
+ gem_overlay.color = light_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(gem_overlay)
+
+ if(active)
+ add_overlay(blade_overlay)
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+
+/obj/item/toy/sword/cx/AltClick(mob/living/user)
+ if(!in_range(src, user)) //Basic checks to prevent abuse
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now! ")
+ return
+
+ if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
+ if(energy_color_input)
+ light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ update_light()
+
+/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(active)
+ if(isinhands)
+ var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
+ blade_inhand.color = light_color
+ . += blade_inhand
+
+/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params)
+ if(istype(W, /obj/item/toy/sword/cx))
+ if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
+ to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]! ")
+ return
+ else
+ to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool. ")
+ new /obj/item/twohanded/dualsaber/hypereutactic/toy(user.loc)
+ qdel(W)
+ qdel(src)
+ else
+ return ..()
+
+/obj/item/toy/sword/cx/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to recolor it. ")
+
/*
* Foam armblade
*/
@@ -337,6 +437,30 @@
/obj/item/twohanded/dualsaber/toy/IsReflect()//Stops Toy Dualsabers from reflecting energy projectiles
return FALSE
+/obj/item/twohanded/dualsaber/hypereutactic/toy
+ name = "\improper DX Hyper-Euplastic LightSword"
+ desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up."
+ force = 0
+ throwforce = 0
+ throw_speed = 3
+ throw_range = 5
+ force_unwielded = 0
+ force_wielded = 0
+ attack_verb = list("attacked", "struck", "hit")
+ total_mass_on = TOTAL_MASS_TOY_SWORD
+ slowdown_wielded = 0
+
+/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
+ return FALSE
+
+/obj/item/twohanded/dualsaber/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles
+ return FALSE
+
+/obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow
+ name = "\improper Hyper-Euclidean Reciprocating Trigonometric Zweihander"
+ desc = "A custom-built toy with fancy rainbow lights built-in."
+ hacked = TRUE
+
/obj/item/toy/katana
name = "replica katana"
desc = "Woefully underpowered in D20."
diff --git a/code/game/objects/items/twohanded.dm b/code/game/objects/items/twohanded.dm
index 82bf2c6b5f..14f924a27e 100644
--- a/code/game/objects/items/twohanded.dm
+++ b/code/game/objects/items/twohanded.dm
@@ -6,6 +6,7 @@
* Spears
* CHAINSAWS
* Bone Axe and Spear
+ * And more
*/
/*##################################################################
@@ -35,7 +36,7 @@
if(!wielded || !user)
return
wielded = 0
- if(force_unwielded)
+ if(!isnull(force_unwielded))
force = force_unwielded
var/sf = findtext(name," (Wielded)")
if(sf)
@@ -304,7 +305,7 @@
var/obj/item/bodypart/head/myhead = user.get_bodypart(BODY_ZONE_HEAD)//stole from chainsaw code
var/obj/item/organ/brain/B = user.getorganslot(ORGAN_SLOT_BRAIN)
- B.vital = FALSE//this cant possibly be a good idea
+ B.organ_flags &= ~ORGAN_VITAL //this cant possibly be a good idea
var/randdir
for(var/i in 1 to 24)//like a headless chicken!
if(user.is_holding(src))
@@ -346,7 +347,8 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
- SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+
+ clean_blood()
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
if(user.has_dna())
@@ -463,6 +465,116 @@
else
return ..()
+/////////////////////////////////////////////////////
+// HYPEREUTACTIC Blades /////////////////////////
+/////////////////////////////////////////////////////
+
+/obj/item/twohanded/dualsaber/hypereutactic
+ icon = 'icons/obj/1x2.dmi'
+ icon_state = "hypereutactic"
+ lefthand_file = 'icons/mob/inhands/64x64_lefthand.dmi'
+ righthand_file = 'icons/mob/inhands/64x64_righthand.dmi'
+ item_state = "hypereutactic"
+ inhand_x_dimension = 64
+ inhand_y_dimension = 64
+ name = "hypereutactic blade"
+ desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter."
+ force = 7
+ force_unwielded = 7
+ force_wielded = 40
+ wieldsound = 'sound/weapons/nebon.ogg'
+ unwieldsound = 'sound/weapons/neboff.ogg'
+ hitsound_on = 'sound/weapons/nebhit.ogg'
+ slowdown_wielded = 1
+ armour_penetration = 60
+ light_color = "#37FFF7"
+ rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00")
+ attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded")
+ spinnable = FALSE
+ total_mass_on = 4
+
+/obj/item/twohanded/dualsaber/hypereutactic/chaplain
+ name = "\improper divine lightblade"
+ desc = "A giant blade of bright and holy light, said to cut down the wicked with ease."
+ force = 5
+ force_unwielded = 5
+ force_wielded = 20
+ block_chance = 50
+ armour_penetration = 0
+ var/chaplain_spawnable = TRUE
+ obj_flags = UNIQUE_RENAME
+
+/obj/item/twohanded/dualsaber/hypereutactic/chaplain/Initialize()
+ . = ..()
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
+
+/obj/item/twohanded/dualsaber/hypereutactic/chaplain/IsReflect()
+ return FALSE
+
+/obj/item/twohanded/dualsaber/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
+ altafterattack(A, user, TRUE, params)
+ return TRUE
+
+/obj/item/twohanded/dualsaber/hypereutactic/altafterattack(atom/target, mob/living/user, proximity_flag, click_parameters) //does right click memes
+ if(istype(user))
+ user.visible_message("[user] points the tip of [src] at [target]. ", "You point the tip of [src] at [target]. ")
+ return TRUE
+
+/obj/item/twohanded/dualsaber/hypereutactic/update_icon()
+ var/mutable_appearance/blade_overlay = mutable_appearance(icon, "hypereutactic_blade")
+ var/mutable_appearance/gem_overlay = mutable_appearance(icon, "hypereutactic_gem")
+
+ if(light_color)
+ blade_overlay.color = light_color
+ gem_overlay.color = light_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(gem_overlay)
+
+ if(wielded)
+ add_overlay(blade_overlay)
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+
+ clean_blood()
+
+/obj/item/twohanded/dualsaber/hypereutactic/AltClick(mob/living/user)
+ if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
+ return
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now! ")
+ return
+ if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
+ if(!energy_color_input || !user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
+ return
+ light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ update_icon()
+ update_light()
+
+/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(isinhands)
+ var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
+ gem_inhand.color = light_color
+ . += gem_inhand
+ if(wielded)
+ var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade")
+ blade_inhand.color = light_color
+ . += blade_inhand
+
+/obj/item/twohanded/dualsaber/hypereutactic/examine(mob/user)
+ ..()
+ if(!hacked)
+ to_chat(user, "Alt-click to recolor it. ")
+
+/obj/item/twohanded/dualsaber/hypereutactic/rainbow_process()
+ . = ..()
+ update_icon()
+ update_light()
+
//spears
/obj/item/twohanded/spear
icon_state = "spearglass0"
@@ -599,6 +711,8 @@
sharpness = IS_SHARP
actions_types = list(/datum/action/item_action/startchainsaw)
var/on = FALSE
+ tool_behaviour = TOOL_SAW
+ toolspeed = 0.5
/obj/item/twohanded/required/chainsaw/Initialize()
. = ..()
@@ -622,7 +736,7 @@
force = on ? force_on : initial(force)
throwforce = on ? force_on : initial(force)
icon_state = "chainsaw_[on ? "on" : "off"]"
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = on
if(on)
@@ -845,18 +959,20 @@
righthand_file = 'icons/mob/inhands/items_righthand.dmi'
slot_flags = ITEM_SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
- var/datum/component/mobhook
+ var/mob/listeningTo
var/zoom_out_amt = 6
var/zoom_amt = 10
+/obj/item/twohanded/binoculars/Destroy()
+ listeningTo = null
+ return ..()
+
/obj/item/twohanded/binoculars/wield(mob/user)
. = ..()
if(!wielded)
return
- if(QDELETED(mobhook))
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/unwield)))
- else
- user.TakeComponent(mobhook)
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/unwield)
+ listeningTo = user
user.visible_message("[user] holds [src] up to [user.p_their()] eyes.","You hold [src] up to your eyes.")
item_state = "binoculars_wielded"
user.regenerate_icons()
@@ -880,7 +996,8 @@
/obj/item/twohanded/binoculars/unwield(mob/user)
. = ..()
- mobhook.RemoveComponent()
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
user.visible_message("[user] lowers [src].","You lower [src].")
item_state = "binoculars"
user.regenerate_icons()
@@ -889,4 +1006,4 @@
var/client/C = user.client
C.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
- user.client.pixel_y = 0
+ user.client.pixel_y = 0
\ No newline at end of file
diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm
index 4cb6fc74c0..fec17cfa69 100644
--- a/code/game/objects/items/weaponry.dm
+++ b/code/game/objects/items/weaponry.dm
@@ -436,6 +436,8 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
attack_verb = list("sawed", "torn", "cut", "chopped", "diced")
hitsound = 'sound/weapons/chainsawhit.ogg'
total_mass = TOTAL_MASS_HAND_REPLACEMENT
+ tool_behaviour = TOOL_SAW
+ toolspeed = 1
/obj/item/mounted_chainsaw/Initialize()
. = ..()
@@ -526,7 +528,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
/obj/item/melee/baseball_bat/chaplain/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/melee/baseball_bat/homerun
name = "home run bat"
diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm
index 5f21862c17..7526807eeb 100644
--- a/code/game/objects/structures.dm
+++ b/code/game/objects/structures.dm
@@ -8,6 +8,7 @@
var/climbable = FALSE
var/mob/living/structureclimber
var/broken = 0 //similar to machinery's stat BROKEN
+ layer = BELOW_OBJ_LAYER
/obj/structure/Initialize()
if (!armor)
diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm
index 2093ae5660..053512a256 100644
--- a/code/game/objects/structures/barsigns.dm
+++ b/code/game/objects/structures/barsigns.dm
@@ -1,4 +1,4 @@
-/obj/structure/sign/barsign // All Signs are 64 by 32 pixels, they take two tiles
+/obj/structure/sign/barsign // All Signs are 64 by 64 pixels, though most of them are made to fit 64 x 32 and only take the two lowermost tiles.
name = "Bar Sign"
desc = "A bar sign with no writing on it."
icon = 'icons/obj/barsigns.dmi'
diff --git a/code/game/objects/structures/beds_chairs/chair.dm b/code/game/objects/structures/beds_chairs/chair.dm
index dde9bce1bc..cec97d5d8b 100644
--- a/code/game/objects/structures/beds_chairs/chair.dm
+++ b/code/game/objects/structures/beds_chairs/chair.dm
@@ -495,7 +495,25 @@
icon_state = "sofamiddle"
icon = 'icons/obj/sofa.dmi'
buildstackamount = 1
- item_chair = null
+ var/mutable_appearance/armrest
+
+/obj/structure/chair/sofa/Initialize()
+ armrest = mutable_appearance(icon, "[icon_state]_armrest")
+ return ..()
+
+/obj/structure/chair/sofa/post_buckle_mob(mob/living/M)
+ . = ..()
+ update_armrest()
+
+/obj/structure/chair/sofa/proc/update_armrest()
+ if(has_buckled_mobs())
+ add_overlay(armrest)
+ else
+ cut_overlay(armrest)
+
+/obj/structure/chair/sofa/post_unbuckle_mob()
+ . = ..()
+ update_armrest()
/obj/structure/chair/sofa/left
icon_state = "sofaend_left"
@@ -504,4 +522,7 @@
icon_state = "sofaend_right"
/obj/structure/chair/sofa/corner
- icon_state = "sofacorner"
\ No newline at end of file
+ icon_state = "sofacorner"
+
+/obj/structure/chair/sofa/corner/handle_layer() //only the armrest/back of this chair should cover the mob.
+ return
\ No newline at end of file
diff --git a/code/game/objects/structures/bedsheet_bin.dm b/code/game/objects/structures/bedsheet_bin.dm
index b493f84240..1e1fee0bfe 100644
--- a/code/game/objects/structures/bedsheet_bin.dm
+++ b/code/game/objects/structures/bedsheet_bin.dm
@@ -41,7 +41,7 @@ LINEN BINS
return
/obj/item/bedsheet/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/wirecutters) || I.is_sharp())
+ if(istype(I, /obj/item/wirecutters) || I.get_sharpness())
var/obj/item/stack/sheet/cloth/C = new (get_turf(src), 3)
transfer_fingerprints_to(C)
C.add_fingerprint(user)
@@ -288,17 +288,19 @@ LINEN BINS
resistance_flags = FLAMMABLE
max_integrity = 70
var/amount = 10
+ var/list/sheet_types = list(/obj/item/bedsheet)
+ var/static/allowed_sheets = list(/obj/item/bedsheet, /obj/item/reagent_containers/rag/towel)
var/list/sheets = list()
var/obj/item/hidden = null
/obj/structure/bedsheetbin/examine(mob/user)
..()
if(amount < 1)
- to_chat(user, "There are no bed sheets in the bin.")
+ to_chat(user, "There are no sheets in the bin.")
else if(amount == 1)
- to_chat(user, "There is one bed sheet in the bin.")
+ to_chat(user, "There is one sheet in the bin.")
else
- to_chat(user, "There are [amount] bed sheets in the bin.")
+ to_chat(user, "There are [amount] sheets in the bin.")
/obj/structure/bedsheetbin/update_icon()
@@ -317,8 +319,9 @@ LINEN BINS
..()
/obj/structure/bedsheetbin/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/bedsheet))
+ if(is_type_in_list(I, allowed_sheets))
if(!user.transferItemToLoc(I, src))
+ to_chat(user, "\The [I] is stuck to your hand, you cannot place it into the bin! ")
return
sheets.Add(I)
amount++
@@ -339,18 +342,19 @@ LINEN BINS
. = ..()
if(.)
return
- if(user.lying)
+ if(user.incapacitated())
return
if(amount >= 1)
amount--
- var/obj/item/bedsheet/B
+ var/obj/item/B
if(sheets.len > 0)
B = sheets[sheets.len]
sheets.Remove(B)
else
- B = new /obj/item/bedsheet(loc)
+ var/chosen = pick(sheet_types)
+ B = new chosen
B.forceMove(drop_location())
user.put_in_hands(B)
@@ -362,19 +366,20 @@ LINEN BINS
to_chat(user, "[hidden] falls out of [B]! ")
hidden = null
-
add_fingerprint(user)
+
/obj/structure/bedsheetbin/attack_tk(mob/user)
if(amount >= 1)
amount--
- var/obj/item/bedsheet/B
+ var/obj/item/B
if(sheets.len > 0)
B = sheets[sheets.len]
sheets.Remove(B)
else
- B = new /obj/item/bedsheet(loc)
+ var/chosen = pick(sheet_types)
+ B = new chosen
B.forceMove(drop_location())
to_chat(user, "You telekinetically remove [B] from [src]. ")
@@ -384,5 +389,11 @@ LINEN BINS
hidden.forceMove(drop_location())
hidden = null
+/obj/structure/bedsheetbin/towel
+ desc = "It looks rather cosy. This one is designed to hold towels."
+ sheet_types = list(/obj/item/reagent_containers/rag/towel)
- add_fingerprint(user)
+/obj/structure/bedsheetbin/color
+ sheet_types = list(/obj/item/bedsheet, /obj/item/bedsheet/blue, /obj/item/bedsheet/green, /obj/item/bedsheet/orange, \
+ /obj/item/bedsheet/purple, /obj/item/bedsheet/red, /obj/item/bedsheet/yellow, /obj/item/bedsheet/brown, \
+ /obj/item/bedsheet/black)
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm
index edcb4a6181..172120861b 100644
--- a/code/game/objects/structures/crates_lockers/closets.dm
+++ b/code/game/objects/structures/crates_lockers/closets.dm
@@ -4,7 +4,6 @@
icon = 'icons/obj/closet.dmi'
icon_state = "generic"
density = TRUE
- layer = BELOW_OBJ_LAYER
var/icon_door = null
var/icon_door_override = FALSE //override to have open overlay use icon different to its base's
var/secure = FALSE //secure locker or not, also used if overriding a non-secure locker with a secure door overlay to add fancy lights
@@ -615,3 +614,6 @@
user.resting = FALSE
togglelock(user)
T1.visible_message("[user] dives into [src]! ")
+
+/obj/structure/closet/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
+ return ..() && opened
diff --git a/code/game/objects/structures/crates_lockers/closets/genpop.dm b/code/game/objects/structures/crates_lockers/closets/genpop.dm
new file mode 100644
index 0000000000..80b64aaedc
--- /dev/null
+++ b/code/game/objects/structures/crates_lockers/closets/genpop.dm
@@ -0,0 +1,117 @@
+/obj/structure/closet/secure_closet/genpop
+ desc = "It's a secure locker for inmates's personal belongings."
+ var/default_desc = "It's a secure locker for the storage inmates's personal belongings during their time in prison."
+ name = "prisoner closet"
+ var/default_name = "prisoner closet"
+ req_access = list(ACCESS_BRIG)
+ var/obj/item/card/id/prisoner/registered_id = null
+ icon_state = "prisoner"
+ locked = FALSE
+ anchored = TRUE
+ opened = TRUE
+ density = FALSE
+
+/obj/structure/closet/secure_closet/genpop/attackby(obj/item/W, mob/user, params)
+ if(!broken && locked && W == registered_id) //Prisoner opening
+ handle_prisoner_id(user)
+ return
+
+ return ..()
+
+/obj/structure/closet/secure_closet/genpop/proc/handle_prisoner_id(mob/user)
+ var/obj/item/card/id/prisoner/prisoner_id = null
+ for(prisoner_id in user.held_items)
+ if(prisoner_id != registered_id)
+ prisoner_id = null
+ else
+ break
+
+ if(!prisoner_id)
+ to_chat(user, "Access Denied. ")
+ return FALSE
+
+ qdel(registered_id)
+ registered_id = null
+ locked = FALSE
+ open(user)
+ desc = "It's a secure locker for prisoner effects."
+ to_chat(user, "You insert your prisoner id into \the [src] and it springs open! ")
+
+ return TRUE
+
+/obj/structure/closet/secure_closet/genpop/proc/handle_edit_sentence(mob/user)
+ var/prisoner_name = input(user, "Please input the name of the prisoner.", "Prisoner Name", registered_id.registered_name) as text|null
+ if(prisoner_name == null | !user.Adjacent(src))
+ return FALSE
+ var/sentence_length = input(user, "Please input the length of their sentence in minutes (0 for perma).", "Sentence Length", registered_id.sentence) as num|null
+ if(sentence_length == null | !user.Adjacent(src))
+ return FALSE
+ var/crimes = input(user, "Please input their crimes.", "Crimes", registered_id.crime) as text|null
+ if(crimes == null | !user.Adjacent(src))
+ return FALSE
+
+ registered_id.registered_name = prisoner_name
+ var/filteredsentlength = text2num(sentence_length)
+ registered_id.sentence = filteredsentlength ? (filteredsentlength MINUTES) + world.time : 0
+ registered_id.crime = crimes
+ registered_id.update_label(prisoner_name, registered_id.assignment)
+ if(registered_id.sentence)
+ START_PROCESSING(SSobj, registered_id)
+ else
+ STOP_PROCESSING(SSobj, registered_id)
+
+ name = "[default_name] ([prisoner_name])"
+ desc = "[default_desc] It contains the personal effects of [prisoner_name]."
+
+ return TRUE
+
+/obj/structure/closet/secure_closet/genpop/togglelock(mob/living/user)
+ if(!allowed(user))
+ return ..()
+
+ if(!broken && locked && registered_id != null)
+ var/name = registered_id.registered_name
+ var/result = alert(user, "This locker currently contains [name]'s personal belongings ","Locker In Use","Reset","Amend ID", "Open")
+ if(!user.Adjacent(src))
+ return
+ if(result == "Reset")
+ name = default_name
+ desc = default_desc
+ registered_id = null
+ if(result == "Open" | result == "Reset")
+ locked = FALSE
+ open(user)
+ if(result == "Amend ID")
+ handle_edit_sentence(user)
+ else
+ return ..()
+
+/obj/structure/closet/secure_closet/genpop/close(mob/living/user)
+ if(registered_id != null)
+ locked = TRUE
+ return ..()
+
+/obj/structure/closet/secure_closet/genpop/attack_hand(mob/user)
+ if(user.lying && get_dist(src, user) > 0)
+ return
+
+ if(!broken && registered_id != null && registered_id in user.held_items)
+ handle_prisoner_id(user)
+ return
+
+ if(!broken && opened && !locked && allowed(user) && !registered_id) //Genpop setup
+
+ registered_id = new /obj/item/card/id/prisoner/(src.contents)
+ if(handle_edit_sentence(user))
+ close(user)
+ locked = TRUE
+ update_icon()
+ registered_id.forceMove(src.loc)
+ new /obj/item/clothing/under/rank/prisoner(src.loc)
+ else
+ qdel(registered_id)
+ registered_id = null
+
+ return
+
+ ..()
\ No newline at end of file
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
index a7adafdad4..f173ac0662 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/engineering.dm
@@ -10,7 +10,7 @@
new /obj/item/clothing/under/rank/chief_engineer(src)
new /obj/item/clothing/under/rank/chief_engineer/skirt(src)
new /obj/item/clothing/head/hardhat/white(src)
- new /obj/item/clothing/head/welding(src)
+ new /obj/item/clothing/head/hardhat/weldhat/white(src)
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/clothing/shoes/sneakers/brown(src)
new /obj/item/tank/jetpack/suit(src)
diff --git a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm
index 6e841bcd93..9dab3679fa 100644
--- a/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm
+++ b/code/game/objects/structures/crates_lockers/closets/secure/freezer.dm
@@ -2,6 +2,24 @@
icon_state = "freezer"
var/jones = FALSE
+/obj/structure/closet/secure_closet/freezer/Destroy()
+ recursive_organ_check(src)
+ ..()
+
+/obj/structure/closet/secure_closet/freezer/Initialize()
+ ..()
+ recursive_organ_check(src)
+
+/obj/structure/closet/secure_closet/freezer/open(mob/living/user)
+ if(opened || !can_open(user)) //dupe check just so we don't let the organs decay when someone fails to open the locker
+ return FALSE
+ recursive_organ_check(src)
+ return ..()
+
+/obj/structure/closet/secure_closet/freezer/close(mob/living/user)
+ if(..()) //if we actually closed the locker
+ recursive_organ_check(src)
+
/obj/structure/closet/secure_closet/freezer/ex_act()
if(!jones)
jones = TRUE
diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm
index 6caa7d834b..23703c7891 100644
--- a/code/game/objects/structures/crates_lockers/crates.dm
+++ b/code/game/objects/structures/crates_lockers/crates.dm
@@ -99,6 +99,25 @@
name = "freezer"
icon_state = "freezer"
+//Snowflake organ freezer code
+//Order is important, since we check source, we need to do the check whenever we have all the organs in the crate
+
+/obj/structure/closet/crate/freezer/open()
+ recursive_organ_check(src)
+ ..()
+
+/obj/structure/closet/crate/freezer/close()
+ ..()
+ recursive_organ_check(src)
+
+/obj/structure/closet/crate/freezer/Destroy()
+ recursive_organ_check(src)
+ ..()
+
+/obj/structure/closet/crate/freezer/Initialize()
+ . = ..()
+ recursive_organ_check(src)
+
/obj/structure/closet/crate/freezer/blood
name = "blood freezer"
desc = "A freezer containing packs of blood."
diff --git a/code/game/objects/structures/false_walls.dm b/code/game/objects/structures/false_walls.dm
index d52ec81a05..d7e2d5564a 100644
--- a/code/game/objects/structures/false_walls.dm
+++ b/code/game/objects/structures/false_walls.dm
@@ -236,7 +236,7 @@
canSmoothWith = list(/obj/structure/falsewall/plasma, /turf/closed/wall/mineral/plasma)
/obj/structure/falsewall/plasma/attackby(obj/item/W, mob/user, params)
- if(W.is_hot() > 300)
+ if(W.get_temperature() > 300)
var/turf/T = get_turf(src)
message_admins("Plasma falsewall ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma falsewall ignited by [key_name(user)] in [AREACOORD(T)]")
diff --git a/code/game/objects/structures/flora.dm b/code/game/objects/structures/flora.dm
index 7c73a1fd8c..12529fb9e0 100644
--- a/code/game/objects/structures/flora.dm
+++ b/code/game/objects/structures/flora.dm
@@ -300,18 +300,9 @@
throw_speed = 2
throw_range = 4
-
-/obj/item/twohanded/required/kirbyplants/equipped(mob/living/user)
- var/image/I = image(icon = 'icons/obj/flora/plants.dmi' , icon_state = src.icon_state, loc = user)
- I.copy_overlays(src)
- I.override = 1
- add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/everyone, "sneaking_mission", I)
- I.layer = ABOVE_MOB_LAYER
- ..()
-
-/obj/item/twohanded/required/kirbyplants/dropped(mob/living/user)
- ..()
- user.remove_alt_appearance("sneaking_mission")
+/obj/item/twohanded/required/kirbyplants/Initialize()
+ . = ..()
+ AddComponent(/datum/component/tactical)
/obj/item/twohanded/required/kirbyplants/random
icon = 'icons/obj/flora/_flora.dmi'
diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm
index 12827a0aba..b820e93c7b 100644
--- a/code/game/objects/structures/ghost_role_spawners.dm
+++ b/code/game/objects/structures/ghost_role_spawners.dm
@@ -45,7 +45,7 @@
death = FALSE
anchored = FALSE
density = FALSE
- flavour_text = "You are an ash walker. Your tribe worships the Necropolis . The wastes are sacred ground, its monsters a blessed bounty. \
+ flavour_text = "You are an ash walker. Your tribe worships the Necropolis . The wastes are sacred ground, its monsters a blessed bounty. You would never leave its beautiful expanse. \
You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest. "
assignedrole = "Ash Walker"
@@ -561,7 +561,7 @@
icon = 'icons/obj/machines/sleeper.dmi'
icon_state = "sleeper"
mob_name = "a space pirate"
- mob_species = /datum/species/skeleton/pirate
+ mob_species = /datum/species/skeleton/space
outfit = /datum/outfit/pirate/space
roundstart = FALSE
death = FALSE
diff --git a/code/game/objects/structures/girders.dm b/code/game/objects/structures/girders.dm
index cd87075258..31bf9318ce 100644
--- a/code/game/objects/structures/girders.dm
+++ b/code/game/objects/structures/girders.dm
@@ -4,7 +4,6 @@
desc = "A large structural assembly made out of metal; It requires a layer of metal before it can be considered a wall."
anchored = TRUE
density = TRUE
- layer = BELOW_OBJ_LAYER
var/state = GIRDER_NORMAL
var/girderpasschance = 20 // percentage chance that a projectile passes through the girder.
var/can_displace = TRUE //If the girder can be moved around by wrenching it
diff --git a/code/game/objects/structures/mineral_doors.dm b/code/game/objects/structures/mineral_doors.dm
index 13ca421daa..efb12ae34a 100644
--- a/code/game/objects/structures/mineral_doors.dm
+++ b/code/game/objects/structures/mineral_doors.dm
@@ -6,6 +6,7 @@
density = TRUE
anchored = TRUE
opacity = TRUE
+ layer = CLOSED_DOOR_LAYER
icon = 'icons/obj/doors/mineral_doors.dmi'
icon_state = "metal"
@@ -90,6 +91,7 @@
flick("[initial_state]opening",src)
sleep(10)
density = FALSE
+ layer = OPEN_DOOR_LAYER
state = 1
air_update_turf(1)
update_icon()
@@ -111,6 +113,7 @@
density = TRUE
set_opacity(TRUE)
state = 0
+ layer = initial(layer)
air_update_turf(1)
update_icon()
isSwitchingStates = 0
@@ -190,7 +193,7 @@
return
/obj/structure/mineral_door/transparent/plasma/attackby(obj/item/W, mob/user, params)
- if(W.is_hot())
+ if(W.get_temperature())
var/turf/T = get_turf(src)
message_admins("Plasma mineral door ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma mineral door ignited by [key_name(user)] in [AREACOORD(T)]")
diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm
index 09e5510d62..e7be30520e 100644
--- a/code/game/objects/structures/morgue.dm
+++ b/code/game/objects/structures/morgue.dm
@@ -31,6 +31,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
/obj/structure/bodycontainer/Initialize()
. = ..()
GLOB.bodycontainers += src
+ recursive_organ_check(src)
/obj/structure/bodycontainer/Destroy()
GLOB.bodycontainers -= src
@@ -101,6 +102,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
/obj/structure/bodycontainer/deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/metal (loc, 5)
+ recursive_organ_check(src)
qdel(src)
/obj/structure/bodycontainer/container_resist(mob/living/user)
@@ -120,6 +122,7 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
open()
/obj/structure/bodycontainer/proc/open()
+ recursive_organ_check(src)
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
playsound(src, 'sound/effects/roll.ogg', 5, 1)
var/turf/T = get_step(src, dir)
@@ -130,10 +133,13 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
/obj/structure/bodycontainer/proc/close()
playsound(src, 'sound/effects/roll.ogg', 5, 1)
- playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
+ playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
for(var/atom/movable/AM in connected.loc)
if(!AM.anchored || AM == connected)
+ if(ismob(AM) && !isliving(AM))
+ continue
AM.forceMove(src)
+ recursive_organ_check(src)
update_icon()
/obj/structure/bodycontainer/get_remote_view_fullscreens(mob/user)
@@ -301,7 +307,7 @@ GLOBAL_LIST_EMPTY(crematoriums)
/obj/structure/tray
icon = 'icons/obj/stationobjs.dmi'
density = TRUE
- layer = BELOW_OBJ_LAYER
+ layer = TRAY_LAYER
var/obj/structure/bodycontainer/connected = null
anchored = TRUE
pass_flags = LETPASSTHROW
diff --git a/code/game/objects/structures/reflector.dm b/code/game/objects/structures/reflector.dm
index 889cdab388..419502e2b0 100644
--- a/code/game/objects/structures/reflector.dm
+++ b/code/game/objects/structures/reflector.dm
@@ -5,7 +5,6 @@
desc = "A base for reflector assemblies."
anchored = FALSE
density = FALSE
- layer = BELOW_OBJ_LAYER
var/deflector_icon_state
var/image/deflector_overlay
var/finished = FALSE
diff --git a/code/game/objects/structures/statues.dm b/code/game/objects/structures/statues.dm
index dd28168ccc..5e6b35ba4f 100644
--- a/code/game/objects/structures/statues.dm
+++ b/code/game/objects/structures/statues.dm
@@ -127,11 +127,11 @@
..()
/obj/structure/statue/plasma/attackby(obj/item/W, mob/user, params)
- if(W.is_hot() > 300 && !QDELETED(src))//If the temperature of the object is over 300, then ignite
+ if(W.get_temperature() > 300 && !QDELETED(src))//If the temperature of the object is over 300, then ignite
var/turf/T = get_turf(src)
message_admins("Plasma statue ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(T)]")
log_game("Plasma statue ignited by [key_name(user)] in [AREACOORD(T)]")
- ignite(W.is_hot())
+ ignite(W.get_temperature())
else
return ..()
diff --git a/code/game/objects/structures/table_frames.dm b/code/game/objects/structures/table_frames.dm
index 226d279288..f62bed878b 100644
--- a/code/game/objects/structures/table_frames.dm
+++ b/code/game/objects/structures/table_frames.dm
@@ -22,92 +22,22 @@
var/framestackamount = 2
/obj/structure/table_frame/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/wrench))
+ if(I.tool_behaviour == TOOL_WRENCH)
to_chat(user, "You start disassembling [src]... ")
I.play_tool_sound(src)
if(I.use_tool(src, user, 30))
- playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
+ playsound(src.loc, 'sound/items/deconstruct.ogg', 50, TRUE)
deconstruct(TRUE)
- else if(istype(I, /obj/item/stack/sheet/plasteel))
- var/obj/item/stack/sheet/plasteel/P = I
- if(P.get_amount() < 1)
- to_chat(user, "You need one plasteel sheet to do this! ")
+ return
+
+ var/obj/item/stack/material = I
+ if (istype(I, /obj/item/stack) && material?.tableVariant)
+ if(material.get_amount() < 1)
+ to_chat(user, "You need one [material.name] sheet to do this! ")
return
- to_chat(user, "You start adding [P] to [src]... ")
- if(do_after(user, 50, target = src) && P.use(1))
- make_new_table(/obj/structure/table/reinforced)
- else if(istype(I, /obj/item/stack/sheet/metal))
- var/obj/item/stack/sheet/metal/M = I
- if(M.get_amount() < 1)
- to_chat(user, "You need one metal sheet to do this! ")
- return
- to_chat(user, "You start adding [M] to [src]... ")
- if(do_after(user, 20, target = src) && M.use(1))
- make_new_table(/obj/structure/table)
- else if(istype(I, /obj/item/stack/sheet/glass))
- var/obj/item/stack/sheet/glass/G = I
- if(G.get_amount() < 1)
- to_chat(user, "You need one glass sheet to do this! ")
- return
- to_chat(user, "You start adding [G] to [src]... ")
- if(do_after(user, 20, target = src) && G.use(1))
- make_new_table(/obj/structure/table/glass)
- else if(istype(I, /obj/item/stack/sheet/mineral/silver))
- var/obj/item/stack/sheet/mineral/silver/S = I
- if(S.get_amount() < 1)
- to_chat(user, "You need one silver sheet to do this! ")
- return
- to_chat(user, "You start adding [S] to [src]... ")
- if(do_after(user, 20, target = src) && S.use(1))
- make_new_table(/obj/structure/table/optable)
- else if(istype(I, /obj/item/stack/tile/carpet/black))
- var/obj/item/stack/tile/carpet/black/C = I
- if(C.get_amount() < 1)
- to_chat(user, "You need one black carpet sheet to do this! ")
- return
- to_chat(user, "You start adding [C] to [src]... ")
- if(do_after(user, 20, target = src) && C.use(1))
- make_new_table(/obj/structure/table/wood/fancy/black)
- else if(istype(I, /obj/item/stack/tile/carpet/blackred))
- var/obj/item/stack/tile/carpet/blackred/C = I
- if(C.get_amount() < 1)
- to_chat(user, "You need one red carpet sheet to do this! ")
- return
- to_chat(user, "You start adding [C] to [src]... ")
- if(do_after(user, 20, target = src) && C.use(1))
- make_new_table(/obj/structure/table/wood/fancy/blackred)
- else if(istype(I, /obj/item/stack/tile/carpet/monochrome))
- var/obj/item/stack/tile/carpet/monochrome/C = I
- if(C.get_amount() < 1)
- to_chat(user, "You need one monochrome carpet sheet to do this! ")
- return
- to_chat(user, "You start adding [C] to [src]... ")
- if(do_after(user, 20, target = src) && C.use(1))
- make_new_table(/obj/structure/table/wood/fancy/monochrome)
- else if(istype(I, /obj/item/stack/tile/carpet))
- var/obj/item/stack/tile/carpet/C = I
- if(C.get_amount() < 1)
- to_chat(user, "You need one carpet sheet to do this! ")
- return
- to_chat(user, "You start adding [C] to [src]... ")
- if(do_after(user, 20, target = src) && C.use(1))
- make_new_table(/obj/structure/table/wood/fancy)
- else if(istype(I, /obj/item/stack/tile/bronze))
- var/obj/item/stack/tile/bronze/B = I
- if(B.get_amount() < 1)
- to_chat(user, "You need one bronze sheet to do this! ")
- return
- to_chat(user, "You start adding [B] to [src]... ")
- if(do_after(user, 20, target = src) && B.use(1))
- make_new_table(/obj/structure/table/bronze)
- else if(istype(I, /obj/item/stack/sheet/plasmaglass))
- var/obj/item/stack/sheet/plasmaglass/G = I
- if(G.get_amount() < 1)
- to_chat(user, "You need one plasmaglass sheet to do this! ")
- return
- to_chat(user, "You start adding [G] to [src]... ")
- if(do_after(user, 20, target = src) && G.use(1))
- make_new_table(/obj/structure/table/plasmaglass)
+ to_chat(user, "You start adding [material] to [src]... ")
+ if(do_after(user, 20, target = src) && material.use(1))
+ make_new_table(material.tableVariant)
else
return ..()
@@ -143,23 +73,21 @@
resistance_flags = FLAMMABLE
/obj/structure/table_frame/wood/attackby(obj/item/I, mob/user, params)
- if(istype(I, /obj/item/stack/sheet/mineral/wood))
- var/obj/item/stack/sheet/mineral/wood/W = I
- if(W.get_amount() < 1)
- to_chat(user, "You need one wood sheet to do this! ")
- return
- to_chat(user, "You start adding [W] to [src]... ")
- if(do_after(user, 20, target = src) && W.use(1))
- make_new_table(/obj/structure/table/wood)
- return
- else if(istype(I, /obj/item/stack/tile/carpet))
- var/obj/item/stack/tile/carpet/C = I
- if(C.get_amount() < 1)
- to_chat(user, "You need one carpet sheet to do this! ")
- return
- to_chat(user, "You start adding [C] to [src]... ")
- if(do_after(user, 20, target = src) && C.use(1))
- make_new_table(/obj/structure/table/wood/poker)
+ if (istype(I, /obj/item/stack))
+ var/obj/item/stack/material = I
+ var/toConstruct // stores the table variant
+ if(istype(I, /obj/item/stack/sheet/mineral/wood))
+ toConstruct = /obj/structure/table/wood
+ else if(istype(I, /obj/item/stack/tile/carpet))
+ toConstruct = /obj/structure/table/wood/poker
+
+ if (toConstruct)
+ if(material.get_amount() < 1)
+ to_chat(user, "You need one [material.name] sheet to do this! ")
+ return
+ to_chat(user, "You start adding [material] to [src]... ")
+ if(do_after(user, 20, target = src) && material.use(1))
+ make_new_table(toConstruct)
else
return ..()
diff --git a/code/game/objects/structures/tables_racks.dm b/code/game/objects/structures/tables_racks.dm
index cd9b595f0a..b12a26cd00 100644
--- a/code/game/objects/structures/tables_racks.dm
+++ b/code/game/objects/structures/tables_racks.dm
@@ -21,6 +21,7 @@
anchored = TRUE
layer = TABLE_LAYER
climbable = TRUE
+ obj_flags = CAN_BE_HIT|SHOVABLE_ONTO
pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.")
var/frame = /obj/structure/table_frame
var/framestack = /obj/item/stack/rods
@@ -136,6 +137,15 @@
var/mob/living/carbon/human/H = pushed_mob
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "table", /datum/mood_event/table)
+/obj/structure/table/shove_act(mob/living/target, mob/living/user)
+ if(!target.resting)
+ target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
+ user.visible_message("[user.name] shoves [target.name] onto \the [src]! ",
+ "You shove [target.name] onto \the [src]! ", null, COMBAT_MESSAGE_RANGE)
+ target.forceMove(src.loc)
+ log_combat(user, target, "shoved", "onto [src] (table)")
+ return TRUE
+
/obj/structure/table/attackby(obj/item/I, mob/user, params)
if(!(flags_1 & NODECONSTRUCT_1))
if(istype(I, /obj/item/screwdriver) && deconstruction_ready)
@@ -348,44 +358,83 @@
frame = /obj/structure/table_frame
framestack = /obj/item/stack/rods
buildstack = /obj/item/stack/tile/carpet
- canSmoothWith = list(/obj/structure/table/wood/fancy, /obj/structure/table/wood/fancy/black, /obj/structure/table/wood/fancy/blackred, /obj/structure/table/wood/fancy/monochrome)
+ canSmoothWith = list(/obj/structure/table/wood/fancy,
+ /obj/structure/table/wood/fancy/black,
+ /obj/structure/table/wood/fancy/blackred,
+ /obj/structure/table/wood/fancy/monochrome,
+ /obj/structure/table/wood/fancy/blue,
+ /obj/structure/table/wood/fancy/cyan,
+ /obj/structure/table/wood/fancy/green,
+ /obj/structure/table/wood/fancy/orange,
+ /obj/structure/table/wood/fancy/purple,
+ /obj/structure/table/wood/fancy/red,
+ /obj/structure/table/wood/fancy/royalblack,
+ /obj/structure/table/wood/fancy/royalblue)
+ var/smooth_icon = 'icons/obj/smooth_structures/fancy_table.dmi' // see Initialize()
-/obj/structure/table/wood/fancy/New()
- // New() is used so that the /black subtype can override `icon` easily and
- // the correct value will be used by the smoothing subsystem.
+/obj/structure/table/wood/fancy/Initialize()
. = ..()
// Needs to be set dynamically because table smooth sprites are 32x34,
// which the editor treats as a two-tile-tall object. The sprites are that
// size so that the north/south corners look nice - examine the detail on
// the sprites in the editor to see why.
- icon = 'icons/obj/smooth_structures/fancy_table.dmi'
+ icon = smooth_icon
/obj/structure/table/wood/fancy/black
icon_state = "fancy_table_black"
buildstack = /obj/item/stack/tile/carpet/black
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_black.dmi'
/obj/structure/table/wood/fancy/blackred
- icon = 'icons/obj/structures.dmi'
- icon_state = "fancy_table_blackred"
- buildstack = /obj/item/stack/tile/carpet/blackred
-
-/obj/structure/table/wood/fancy/blackred/New()
- . = ..()
- icon = 'icons/obj/smooth_structures/fancy_table_blackred.dmi'
+ icon_state = "fancy_table_blackred"
+ buildstack = /obj/item/stack/tile/carpet/blackred
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_blackred.dmi'
/obj/structure/table/wood/fancy/monochrome
- icon = 'icons/obj/structures.dmi'
- icon_state = "fancy_table_monochrome"
- buildstack = /obj/item/stack/tile/carpet/monochrome
+ icon_state = "fancy_table_monochrome"
+ buildstack = /obj/item/stack/tile/carpet/monochrome
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_monochrome.dmi'
-/obj/structure/table/wood/fancy/monochrome/New()
- . = ..()
- icon = 'icons/obj/smooth_structures/fancy_table_monochrome.dmi'
+/obj/structure/table/wood/fancy/blue
+ icon_state = "fancy_table_blue"
+ buildstack = /obj/item/stack/tile/carpet/blue
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_blue.dmi'
+
+/obj/structure/table/wood/fancy/cyan
+ icon_state = "fancy_table_cyan"
+ buildstack = /obj/item/stack/tile/carpet/cyan
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_cyan.dmi'
+
+/obj/structure/table/wood/fancy/green
+ icon_state = "fancy_table_green"
+ buildstack = /obj/item/stack/tile/carpet/green
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_green.dmi'
+
+/obj/structure/table/wood/fancy/orange
+ icon_state = "fancy_table_orange"
+ buildstack = /obj/item/stack/tile/carpet/orange
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_orange.dmi'
+
+/obj/structure/table/wood/fancy/purple
+ icon_state = "fancy_table_purple"
+ buildstack = /obj/item/stack/tile/carpet/purple
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_purple.dmi'
+
+/obj/structure/table/wood/fancy/red
+ icon_state = "fancy_table_red"
+ buildstack = /obj/item/stack/tile/carpet/red
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_red.dmi'
+
+/obj/structure/table/wood/fancy/royalblack
+ icon_state = "fancy_table_royalblack"
+ buildstack = /obj/item/stack/tile/carpet/royalblack
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_royalblack.dmi'
+
+/obj/structure/table/wood/fancy/royalblue
+ icon_state = "fancy_table_royalblue"
+ buildstack = /obj/item/stack/tile/carpet/royalblue
+ smooth_icon = 'icons/obj/smooth_structures/fancy_table_royalblue.dmi'
-/obj/structure/table/wood/fancy/black/New()
- . = ..()
- // Ditto above.
- icon = 'icons/obj/smooth_structures/fancy_table_black.dmi'
/*
* Reinforced tables
*/
diff --git a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
index ee46538be1..392c802ed8 100644
--- a/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
+++ b/code/game/objects/structures/transit_tubes/transit_tube_pod.dm
@@ -4,7 +4,6 @@
animate_movement = FORWARD_STEPS
anchored = TRUE
density = TRUE
- layer = BELOW_OBJ_LAYER
var/moving = 0
var/datum/gas_mixture/air_contents = new()
diff --git a/code/game/objects/structures/traps.dm b/code/game/objects/structures/traps.dm
index ffc2c344f9..176779abd7 100644
--- a/code/game/objects/structures/traps.dm
+++ b/code/game/objects/structures/traps.dm
@@ -65,6 +65,8 @@
var/mob/M = AM
if(M.mind in immune_minds)
return
+ if(M.anti_magic_check())
+ flare()
if(charges <= 0)
return
flare()
diff --git a/code/game/objects/structures/watercloset.dm b/code/game/objects/structures/watercloset.dm
index 46db567b10..76c8f7f11f 100644
--- a/code/game/objects/structures/watercloset.dm
+++ b/code/game/objects/structures/watercloset.dm
@@ -318,6 +318,7 @@
/obj/machinery/shower/proc/wash_obj(obj/O)
. = SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ . = O.clean_blood()
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
if(isitem(O))
var/obj/item/I = O
@@ -328,8 +329,9 @@
/obj/machinery/shower/proc/wash_turf()
if(isturf(loc))
var/turf/tile = loc
- SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
tile.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
+ tile.clean_blood()
+ SEND_SIGNAL(tile, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
for(var/obj/effect/E in tile)
if(is_cleanable(E))
qdel(E)
@@ -381,7 +383,8 @@
else if(H.w_uniform && wash_obj(H.w_uniform))
H.update_inv_w_uniform()
if(washgloves)
- SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ H.clean_blood()
+ SEND_SIGNAL(H, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
if(H.shoes && washshoes && wash_obj(H.shoes))
H.update_inv_shoes()
if(H.wear_mask && washmask && wash_obj(H.wear_mask))
@@ -398,9 +401,11 @@
else
if(M.wear_mask && wash_obj(M.wear_mask))
M.update_inv_wear_mask(0)
- SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ M.clean_blood()
+ SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
else
- SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ L.clean_blood()
+ SEND_SIGNAL(L, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
/obj/machinery/shower/proc/contamination_cleanse(atom/movable/thing)
var/datum/component/radioactive/healthy_green_glow = thing.GetComponent(/datum/component/radioactive)
@@ -498,7 +503,8 @@
H.regenerate_icons()
user.drowsyness = max(user.drowsyness - rand(2,3), 0) //Washing your face wakes you up if you're falling asleep
else
- SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(user, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ user.clean_blood()
/obj/structure/sink/attackby(obj/item/O, mob/living/user, params)
if(busy)
@@ -554,7 +560,8 @@
busy = FALSE
return 1
busy = FALSE
- SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ O.clean_blood()
O.acid_level = 0
create_reagents(5)
reagents.add_reagent(dispensedreagent, 5)
@@ -675,4 +682,4 @@
else
playsound(loc, 'sound/weapons/tap.ogg', 50, 1)
if(BURN)
- playsound(loc, 'sound/items/welder.ogg', 80, 1)
+ playsound(loc, 'sound/items/welder.ogg', 80, 1)
\ No newline at end of file
diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm
index 9fc055c2ba..794776cfa5 100644
--- a/code/game/objects/structures/window.dm
+++ b/code/game/objects/structures/window.dm
@@ -731,8 +731,8 @@
/obj/structure/window/paperframe/attackby(obj/item/W, mob/user)
- if(W.is_hot())
- fire_act(W.is_hot())
+ if(W.get_temperature())
+ fire_act(W.get_temperature())
return
if(user.a_intent == INTENT_HARM)
return ..()
diff --git a/code/game/sound.dm b/code/game/sound.dm
index 5503c6103d..e7562476a8 100644
--- a/code/game/sound.dm
+++ b/code/game/sound.dm
@@ -182,6 +182,8 @@
soundin = pick('sound/voice/beepsky/god.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/secureday.ogg', 'sound/voice/beepsky/radio.ogg', 'sound/voice/beepsky/insult.ogg', 'sound/voice/beepsky/creep.ogg')
if("honkbot_e")
soundin = pick('sound/items/bikehorn.ogg', 'sound/items/AirHorn2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/items/AirHorn.ogg', 'sound/effects/reee.ogg', 'sound/items/WEEOO1.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/beepsky/creep.ogg','sound/magic/Fireball.ogg' ,'sound/effects/pray.ogg', 'sound/voice/hiss1.ogg','sound/machines/buzz-sigh.ogg', 'sound/machines/ping.ogg', 'sound/weapons/flashbang.ogg', 'sound/weapons/bladeslice.ogg')
+ if("goose")
+ soundin = pick('sound/creatures/goose1.ogg', 'sound/creatures/goose2.ogg', 'sound/creatures/goose3.ogg', 'sound/creatures/goose4.ogg')
//START OF CIT CHANGES - adds random vore sounds
if ("struggle_sound")
soundin = pick( 'sound/vore/pred/struggle_01.ogg','sound/vore/pred/struggle_02.ogg','sound/vore/pred/struggle_03.ogg',
diff --git a/code/game/turfs/change_turf.dm b/code/game/turfs/change_turf.dm
index e441ccd6cc..f1c5080c8f 100644
--- a/code/game/turfs/change_turf.dm
+++ b/code/game/turfs/change_turf.dm
@@ -41,7 +41,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
/turf/open/copyTurf(turf/T, copy_air = FALSE)
. = ..()
if (isopenturf(T))
- GET_COMPONENT(slip, /datum/component/wet_floor)
+ var/datum/component/wet_floor/slip = GetComponent(/datum/component/wet_floor)
if(slip)
var/datum/component/wet_floor/WF = T.AddComponent(/datum/component/wet_floor)
WF.InheritComponent(slip)
diff --git a/code/game/turfs/open.dm b/code/game/turfs/open.dm
index f6d234b346..bd24e0ff93 100644
--- a/code/game/turfs/open.dm
+++ b/code/game/turfs/open.dm
@@ -251,6 +251,7 @@
M.apply_water()
SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ clean_blood()
for(var/obj/effect/O in src)
if(is_cleanable(O))
qdel(O)
diff --git a/code/game/turfs/simulated/chasm.dm b/code/game/turfs/simulated/chasm.dm
index 677fba2990..0a7b507488 100644
--- a/code/game/turfs/simulated/chasm.dm
+++ b/code/game/turfs/simulated/chasm.dm
@@ -15,11 +15,11 @@
AddComponent(/datum/component/chasm, SSmapping.get_turf_below(src))
/turf/open/chasm/proc/set_target(turf/target)
- GET_COMPONENT(chasm_component, /datum/component/chasm)
+ var/datum/component/chasm/chasm_component = GetComponent(/datum/component/chasm)
chasm_component.target_turf = target
/turf/open/chasm/proc/drop(atom/movable/AM)
- GET_COMPONENT(chasm_component, /datum/component/chasm)
+ var/datum/component/chasm/chasm_component = GetComponent(/datum/component/chasm)
chasm_component.drop(AM)
/turf/open/chasm/MakeSlippery(wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent)
diff --git a/code/game/turfs/simulated/floor/fancy_floor.dm b/code/game/turfs/simulated/floor/fancy_floor.dm
index 7b45aa1fbb..ed6e279088 100644
--- a/code/game/turfs/simulated/floor/fancy_floor.dm
+++ b/code/game/turfs/simulated/floor/fancy_floor.dm
@@ -209,6 +209,46 @@
icon_state = "tile-carpet-monochrome"
canSmoothWith = list(/turf/open/floor/carpet/black, /turf/open/floor/carpet/blackred, /turf/open/floor/carpet/monochrome)
+/turf/open/floor/carpet/blue
+ icon = 'icons/turf/floors/carpet_blue.dmi'
+ floor_tile = /obj/item/stack/tile/carpet/blue
+ canSmoothWith = list(/turf/open/floor/carpet/blue)
+
+/turf/open/floor/carpet/cyan
+ icon = 'icons/turf/floors/carpet_cyan.dmi'
+ floor_tile = /obj/item/stack/tile/carpet/cyan
+ canSmoothWith = list(/turf/open/floor/carpet/cyan)
+
+/turf/open/floor/carpet/green
+ icon = 'icons/turf/floors/carpet_green.dmi'
+ floor_tile = /obj/item/stack/tile/carpet/green
+ canSmoothWith = list(/turf/open/floor/carpet/green)
+
+/turf/open/floor/carpet/orange
+ icon = 'icons/turf/floors/carpet_orange.dmi'
+ floor_tile = /obj/item/stack/tile/carpet/orange
+ canSmoothWith = list(/turf/open/floor/carpet/orange)
+
+/turf/open/floor/carpet/purple
+ icon = 'icons/turf/floors/carpet_purple.dmi'
+ floor_tile = /obj/item/stack/tile/carpet/purple
+ canSmoothWith = list(/turf/open/floor/carpet/purple)
+
+/turf/open/floor/carpet/red
+ icon = 'icons/turf/floors/carpet_red.dmi'
+ floor_tile = /obj/item/stack/tile/carpet/red
+ canSmoothWith = list(/turf/open/floor/carpet/red)
+
+/turf/open/floor/carpet/royalblack
+ icon = 'icons/turf/floors/carpet_royalblack.dmi'
+ floor_tile = /obj/item/stack/tile/carpet/royalblack
+ canSmoothWith = list(/turf/open/floor/carpet/royalblack)
+
+/turf/open/floor/carpet/royalblue
+ icon = 'icons/turf/floors/carpet_royalblue.dmi'
+ floor_tile = /obj/item/stack/tile/carpet/royalblue
+ canSmoothWith = list(/turf/open/floor/carpet/royalblue)
+
/turf/open/floor/carpet/narsie_act(force, ignore_mobs, probability = 20)
. = (prob(probability) || force)
for(var/I in src)
diff --git a/code/game/turfs/simulated/floor/mineral_floor.dm b/code/game/turfs/simulated/floor/mineral_floor.dm
index a77417e4e4..b71fb51123 100644
--- a/code/game/turfs/simulated/floor/mineral_floor.dm
+++ b/code/game/turfs/simulated/floor/mineral_floor.dm
@@ -43,10 +43,10 @@
PlasmaBurn(exposed_temperature)
/turf/open/floor/mineral/plasma/attackby(obj/item/W, mob/user, params)
- if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
+ if(W.get_temperature() > 300)//If the temperature of the object is over 300, then ignite
message_admins("Plasma flooring was ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(src)]")
log_game("Plasma flooring was ignited by [key_name(user)] in [AREACOORD(src)]")
- ignite(W.is_hot())
+ ignite(W.get_temperature())
return
..()
diff --git a/code/game/turfs/simulated/wall/mineral_walls.dm b/code/game/turfs/simulated/wall/mineral_walls.dm
index dbffd1010b..9962f72d4a 100644
--- a/code/game/turfs/simulated/wall/mineral_walls.dm
+++ b/code/game/turfs/simulated/wall/mineral_walls.dm
@@ -94,10 +94,10 @@
canSmoothWith = list(/turf/closed/wall/mineral/plasma, /obj/structure/falsewall/plasma)
/turf/closed/wall/mineral/plasma/attackby(obj/item/W, mob/user, params)
- if(W.is_hot() > 300)//If the temperature of the object is over 300, then ignite
+ if(W.get_temperature() > 300)//If the temperature of the object is over 300, then ignite
message_admins("Plasma wall ignited by [ADMIN_LOOKUPFLW(user)] in [ADMIN_VERBOSEJMP(src)]")
log_game("Plasma wall ignited by [key_name(user)] in [AREACOORD(src)]")
- ignite(W.is_hot())
+ ignite(W.get_temperature())
return
..()
diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm
index 7110ff4405..ebf6f6626c 100755
--- a/code/game/turfs/turf.dm
+++ b/code/game/turfs/turf.dm
@@ -382,6 +382,19 @@
if(ismob(A) || .)
A.ratvar_act()
+//called on /datum/species/proc/altdisarm()
+/turf/shove_act(mob/living/target, mob/living/user, pre_act = FALSE)
+ var/list/possibilities
+ for(var/obj/O in contents)
+ if(CHECK_BITFIELD(O.obj_flags, SHOVABLE_ONTO))
+ LAZYADD(possibilities, O)
+ else if(!O.CanPass(target, src))
+ return FALSE
+ if(possibilities)
+ var/obj/O = pick(possibilities)
+ return O.shove_act(target, user)
+ return FALSE
+
/turf/proc/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
underlay_appearance.icon = icon
underlay_appearance.icon_state = icon_state
@@ -452,16 +465,21 @@
/turf/AllowDrop()
return TRUE
-/turf/proc/add_vomit_floor(mob/living/carbon/M, toxvomit = NONE)
+/turf/proc/add_vomit_floor(mob/living/M, toxvomit = NONE)
+
var/obj/effect/decal/cleanable/vomit/V = new /obj/effect/decal/cleanable/vomit(src, M.get_static_viruses())
- // If the vomit combined, apply toxicity and reagents to the old vomit
+ //if the vomit combined, apply toxicity and reagents to the old vomit
if (QDELETED(V))
V = locate() in src
// Make toxins and blazaam vomit look different
if(toxvomit == VOMIT_PURPLE)
V.icon_state = "vomitpurp_[pick(1,4)]"
- else if(toxvomit == VOMIT_TOXIC)
+ else if (toxvomit == VOMIT_TOXIC)
V.icon_state = "vomittox_[pick(1,4)]"
+ if (iscarbon(M))
+ var/mob/living/carbon/C = M
+ if(C.reagents)
+ clear_reagents_to_vomit_pool(C,V)
/proc/clear_reagents_to_vomit_pool(mob/living/carbon/M, obj/effect/decal/cleanable/vomit/V)
M.reagents.trans_to(V, M.reagents.total_volume / 10)
@@ -474,4 +492,4 @@
//Whatever happens after high temperature fire dies out or thermite reaction works.
//Should return new turf
/turf/proc/Melt()
- return ScrapeAway()
\ No newline at end of file
+ return ScrapeAway()
diff --git a/code/game/world.dm b/code/game/world.dm
index e9c8433006..25b8c4d9f3 100644
--- a/code/game/world.dm
+++ b/code/game/world.dm
@@ -100,6 +100,7 @@ GLOBAL_VAR(restart_counter)
GLOB.picture_log_directory = "data/picture_logs/[override_dir]"
GLOB.world_game_log = "[GLOB.log_directory]/game.log"
+ GLOB.world_virus_log = "[GLOB.log_directory]/virus.log"
GLOB.world_attack_log = "[GLOB.log_directory]/attack.log"
GLOB.world_pda_log = "[GLOB.log_directory]/pda.log"
GLOB.world_telecomms_log = "[GLOB.log_directory]/telecomms.log"
diff --git a/code/modules/NTNet/services/_service.dm b/code/modules/NTNet/services/_service.dm
index 8611c2d25d..3622dc3881 100644
--- a/code/modules/NTNet/services/_service.dm
+++ b/code/modules/NTNet/services/_service.dm
@@ -17,7 +17,7 @@
/datum/ntnet_service/proc/connect(datum/ntnet/net)
if(!istype(net))
return FALSE
- GET_COMPONENT(interface, /datum/component/ntnet_interface)
+ var/datum/component/ntnet_interface/interface = GetComponent(/datum/component/ntnet_interface)
if(!interface.register_connection(net))
return FALSE
if(!net.register_service(src))
@@ -29,7 +29,7 @@
/datum/ntnet_service/proc/disconnect(datum/ntnet/net, force = FALSE)
if(!istype(net) || (!net.unregister_service(src) && !force))
return FALSE
- GET_COMPONENT(interface, /datum/component/ntnet_interface)
+ var/datum/component/ntnet_interface/interface = GetComponent(/datum/component/ntnet_interface)
interface.unregister_connection(net)
networks_by_id -= net.network_id
return TRUE
diff --git a/code/modules/VR/vr_human.dm b/code/modules/VR/vr_human.dm
deleted file mode 100644
index 53a4bbe540..0000000000
--- a/code/modules/VR/vr_human.dm
+++ /dev/null
@@ -1,61 +0,0 @@
-/mob/living/carbon/human/virtual_reality
- var/datum/mind/real_mind // where is my mind t. pixies
- var/obj/machinery/vr_sleeper/vr_sleeper
- var/datum/action/quit_vr/quit_action
-
-/mob/living/carbon/human/virtual_reality/Initialize()
- . = ..()
- quit_action = new()
- quit_action.Grant(src)
-
-/mob/living/carbon/human/virtual_reality/death()
- revert_to_reality()
- ..()
-
-/mob/living/carbon/human/virtual_reality/Destroy()
- revert_to_reality()
- return ..()
-
-/mob/living/carbon/human/virtual_reality/Life()
- . = ..()
- if(real_mind)
- var/mob/living/real_me = real_mind.current
- if (real_me && real_me.stat == CONSCIOUS)
- return
- revert_to_reality(FALSE)
-
-/mob/living/carbon/human/virtual_reality/ghostize()
- stack_trace("Ghostize was called on a virtual reality mob")
-
-/mob/living/carbon/human/virtual_reality/ghost()
- set category = "OOC"
- set name = "Ghost"
- set desc = "Relinquish your life and enter the land of the dead."
- revert_to_reality(FALSE)
-
-/mob/living/carbon/human/virtual_reality/proc/revert_to_reality(deathchecks = TRUE)
- if(real_mind && mind)
- real_mind.current.audiovisual_redirect = null
- real_mind.current.ckey = ckey
- real_mind.current.stop_sound_channel(CHANNEL_HEARTBEAT)
- if(deathchecks && vr_sleeper)
- if(vr_sleeper.you_die_in_the_game_you_die_for_real)
- to_chat(real_mind, "You feel everything fading away... ")
- real_mind.current.death(0)
- if(deathchecks && vr_sleeper)
- vr_sleeper.vr_human = null
- vr_sleeper = null
- real_mind = null
-
-/datum/action/quit_vr
- name = "Quit Virtual Reality"
- icon_icon = 'icons/mob/actions/actions_vr.dmi'
- button_icon_state = "logout"
-
-/datum/action/quit_vr/Trigger()
- if(..())
- if(istype(owner, /mob/living/carbon/human/virtual_reality))
- var/mob/living/carbon/human/virtual_reality/VR = owner
- VR.revert_to_reality(FALSE)
- else
- Remove(owner)
diff --git a/code/modules/VR/vr_mob.dm b/code/modules/VR/vr_mob.dm
new file mode 100644
index 0000000000..5c0cea9f60
--- /dev/null
+++ b/code/modules/VR/vr_mob.dm
@@ -0,0 +1,44 @@
+/mob/proc/build_virtual_character(mob/M)
+ mind_initialize()
+ if(!M)
+ return FALSE
+ name = M.name
+ real_name = M.real_name
+ mind.name = M.real_name
+ return TRUE
+
+/mob/living/carbon/build_virtual_character(mob/M)
+ . = ..()
+ if(!.)
+ return
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.dna?.transfer_identity(src)
+
+/mob/living/carbon/human/build_virtual_character(mob/M, datum/outfit/outfit)
+ . = ..()
+ if(!.)
+ return
+ var/mob/living/carbon/human/H
+ if(ishuman(M))
+ H = M
+ socks = H ? H.socks : random_socks()
+ socks_color = H ? H.socks_color : random_color()
+ undershirt = H ? H.undershirt : random_undershirt(M.gender)
+ shirt_color = H ? H.shirt_color : random_color()
+ underwear = H ? H.underwear : random_underwear(M.gender)
+ undie_color = H ? H.undie_color : random_color()
+ give_genitals(TRUE)
+ if(outfit)
+ var/datum/outfit/O = new outfit()
+ O.equip(src)
+
+/datum/action/quit_vr
+ name = "Quit Virtual Reality"
+ icon_icon = 'icons/mob/actions/actions_vr.dmi'
+ button_icon_state = "logout"
+
+/datum/action/quit_vr/Trigger() //this merely a trigger for /datum/component/virtual_reality
+ . = ..()
+ if(!.)
+ Remove(owner)
diff --git a/code/modules/VR/vr_sleeper.dm b/code/modules/VR/vr_sleeper.dm
index 89e9c33ecc..72cbdc1409 100644
--- a/code/modules/VR/vr_sleeper.dm
+++ b/code/modules/VR/vr_sleeper.dm
@@ -1,5 +1,3 @@
-
-
//Glorified teleporter that puts you in a new human body.
// it's """VR"""
/obj/machinery/vr_sleeper
@@ -12,9 +10,10 @@
circuit = /obj/item/circuitboard/machine/vr_sleeper
var/you_die_in_the_game_you_die_for_real = FALSE
var/datum/effect_system/spark_spread/sparks
- var/mob/living/carbon/human/virtual_reality/vr_human
+ var/mob/living/vr_mob
+ var/virtual_mob_type = /mob/living/carbon/human
var/vr_category = "default" //Specific category of spawn points to pick from
- var/allow_creating_vr_humans = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games
+ var/allow_creating_vr_mobs = TRUE //So you can have vr_sleepers that always spawn you as a specific person or 1 life/chance vr games
var/only_current_user_can_interact = FALSE
/obj/machinery/vr_sleeper/Initialize()
@@ -44,7 +43,7 @@
/obj/machinery/vr_sleeper/Destroy()
open_machine()
- cleanup_vr_human()
+ cleanup_vr_mob()
QDEL_NULL(sparks)
return ..()
@@ -58,8 +57,9 @@
/obj/machinery/vr_sleeper/emag_act(mob/user)
. = ..()
- if(you_die_in_the_game_you_die_for_real)
+ if(!(obj_flags & EMAGGED))
return
+ obj_flags |= EMAGGED
you_die_in_the_game_you_die_for_real = TRUE
sparks.start()
addtimer(CALLBACK(src, .proc/emagNotify), 150)
@@ -69,12 +69,11 @@
icon_state = "[initial(icon_state)][state_open ? "-open" : ""]"
/obj/machinery/vr_sleeper/open_machine()
- if(!state_open)
- if(vr_human)
- vr_human.revert_to_reality(FALSE)
- if(occupant)
- SStgui.close_user_uis(occupant, src)
- ..()
+ if(state_open)
+ return
+ if(occupant)
+ SStgui.close_user_uis(occupant, src)
+ return ..()
/obj/machinery/vr_sleeper/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
@@ -94,22 +93,20 @@
if("vr_connect")
var/mob/living/carbon/human/human_occupant = occupant
if(human_occupant && human_occupant.mind && usr == occupant)
+
to_chat(occupant, "Transferring to virtual reality... ")
- if(vr_human && vr_human.stat == CONSCIOUS && !vr_human.real_mind)
- SStgui.close_user_uis(occupant, src)
- human_occupant.audiovisual_redirect = vr_human
- vr_human.real_mind = human_occupant.mind
- vr_human.ckey = human_occupant.ckey
- to_chat(vr_human, "Transfer successful! You are now playing as [vr_human] in VR! ")
+ if(vr_mob && (!istype(vr_mob) || !vr_mob.InCritical()) && !vr_mob.GetComponent(/datum/component/virtual_reality))
+ vr_mob.AddComponent(/datum/component/virtual_reality, human_occupant, src, you_die_in_the_game_you_die_for_real)
+ to_chat(vr_mob, "Transfer successful! You are now playing as [vr_mob] in VR! ")
else
- if(allow_creating_vr_humans)
+ if(allow_creating_vr_mobs)
to_chat(occupant, "Virtual avatar not found, attempting to create one... ")
var/obj/effect/landmark/vr_spawn/V = get_vr_spawnpoint()
var/turf/T = get_turf(V)
if(T)
SStgui.close_user_uis(occupant, src)
- build_virtual_human(occupant, T, V.vr_outfit)
- to_chat(vr_human, "Transfer successful! You are now playing as [vr_human] in VR! ")
+ new_player(occupant, T, V.vr_outfit)
+ to_chat(vr_mob, "Transfer successful! You are now playing as [vr_mob] in VR! ")
else
to_chat(occupant, "Virtual world misconfigured, aborting transfer ")
else
@@ -117,8 +114,8 @@
. = TRUE
if("delete_avatar")
if(!occupant || usr == occupant)
- if(vr_human)
- cleanup_vr_human()
+ if(vr_mob)
+ cleanup_vr_mob()
else
to_chat(usr, "The VR Sleeper's safeties prevent you from doing that. ")
. = TRUE
@@ -131,19 +128,22 @@
/obj/machinery/vr_sleeper/ui_data(mob/user)
var/list/data = list()
- if(vr_human && !QDELETED(vr_human))
+ if(vr_mob && !QDELETED(vr_mob))
data["can_delete_avatar"] = TRUE
- var/status
- switch(vr_human.stat)
- if(CONSCIOUS)
- status = "Conscious"
- if(DEAD)
- status = "Dead"
- if(UNCONSCIOUS)
- status = "Unconscious"
- if(SOFT_CRIT)
- status = "Barely Conscious"
- data["vr_avatar"] = list("name" = vr_human.name, "status" = status, "health" = vr_human.health, "maxhealth" = vr_human.maxHealth)
+ data["vr_avatar"] = list("name" = vr_mob.name)
+ data["isliving"] = istype(vr_mob)
+ if(data["isliving"])
+ var/status
+ switch(vr_mob.stat)
+ if(CONSCIOUS)
+ status = "Conscious"
+ if(DEAD)
+ status = "Dead"
+ if(UNCONSCIOUS)
+ status = "Unconscious"
+ if(SOFT_CRIT)
+ status = "Barely Conscious"
+ data["vr_avatar"] += list("status" = status, "health" = vr_mob.health, "maxhealth" = vr_mob.maxHealth)
data["toggle_open"] = state_open
data["emagged"] = you_die_in_the_game_you_die_for_real
data["isoccupant"] = (user == occupant)
@@ -157,40 +157,25 @@
for(var/obj/effect/landmark/vr_spawn/V in GLOB.landmarks_list)
GLOB.vr_spawnpoints[V.vr_category] = V
-/obj/machinery/vr_sleeper/proc/build_virtual_human(mob/living/carbon/human/H, location, var/datum/outfit/outfit, transfer = TRUE)
- if(H)
- cleanup_vr_human()
- vr_human = new /mob/living/carbon/human/virtual_reality(location)
- vr_human.mind_initialize()
- vr_human.vr_sleeper = src
- vr_human.real_mind = H.mind
- H.dna.transfer_identity(vr_human)
- vr_human.name = H.name
- vr_human.real_name = H.real_name
- vr_human.socks = H.socks
- vr_human.socks_color = H.socks_color
- vr_human.undershirt = H.undershirt
- vr_human.shirt_color = H.shirt_color
- vr_human.underwear = H.underwear
- vr_human.undie_color = H.undie_color
- vr_human.updateappearance(TRUE, TRUE, TRUE)
- vr_human.give_genitals(TRUE) //CITADEL ADD
- if(outfit)
- var/datum/outfit/O = new outfit()
- O.equip(vr_human)
- if(transfer && H.mind)
- SStgui.close_user_uis(H, src)
- H.audiovisual_redirect = vr_human
- vr_human.ckey = H.ckey
+/obj/machinery/vr_sleeper/proc/new_player(mob/living/carbon/human/H, location, datum/outfit/outfit, transfer = TRUE)
+ if(!H)
+ return
+ cleanup_vr_mob()
+ vr_mob = new virtual_mob_type(location)
+ if(vr_mob.build_virtual_character(H, outfit))
+ var/mob/living/carbon/human/vr_H = vr_mob
+ vr_H.updateappearance(TRUE, TRUE, TRUE)
+ if(!transfer || !H.mind)
+ return
+ vr_mob.AddComponent(/datum/component/virtual_reality, H, src, you_die_in_the_game_you_die_for_real)
-/obj/machinery/vr_sleeper/proc/cleanup_vr_human()
- if(vr_human)
- vr_human.vr_sleeper = null // Prevents race condition where a new human could get created out of order and set to null.
- QDEL_NULL(vr_human)
+/obj/machinery/vr_sleeper/proc/cleanup_vr_mob()
+ if(vr_mob)
+ QDEL_NULL(vr_mob)
/obj/machinery/vr_sleeper/proc/emagNotify()
- if(vr_human)
- vr_human.Dizzy(10)
+ if(vr_mob)
+ vr_mob.Dizzy(10)
/obj/effect/landmark/vr_spawn //places you can spawn in VR, auto selected by the vr_sleeper during get_vr_spawnpoint()
var/vr_category = "default" //So we can have specific sleepers, eg: "Basketball VR Sleeper", etc.
@@ -222,6 +207,7 @@
color = "#00FF00"
invisibility = INVISIBILITY_ABSTRACT
var/area/vr_area
+ var/list/corpse_party
/obj/effect/vr_clean_master/Initialize()
. = ..()
@@ -234,7 +220,8 @@
qdel(casing)
for(var/obj/effect/decal/cleanable/C in vr_area)
qdel(C)
- for (var/mob/living/carbon/human/virtual_reality/H in vr_area)
- if (H.stat == DEAD && !H.vr_sleeper && !H.real_mind)
- qdel(H)
+ for (var/A in corpse_party)
+ var/mob/M = A
+ if(get_area(M) == vr_area && M.stat == DEAD)
+ qdel(M)
addtimer(CALLBACK(src, .proc/clean_up), 3 MINUTES)
diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm
index 555c35980d..7fafca69f0 100644
--- a/code/modules/admin/admin.dm
+++ b/code/modules/admin/admin.dm
@@ -682,7 +682,7 @@
log_admin("[key_name(usr)] delayed the round start.")
else
to_chat(world, "The game will start in [DisplayTimeText(newtime)]. ")
- SEND_SOUND(world, sound('sound/ai/attention.ogg'))
+ SEND_SOUND(world, sound(get_announcer_sound("attention")))
log_admin("[key_name(usr)] set the pre-game delay to [DisplayTimeText(newtime)].")
SSblackbox.record_feedback("tally", "admin_verb", 1, "Delay Game Start") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm
index ac1ae51f69..626fa7f66f 100644
--- a/code/modules/admin/admin_verbs.dm
+++ b/code/modules/admin/admin_verbs.dm
@@ -169,6 +169,7 @@ GLOBAL_LIST_INIT(admin_verbs_debug, world.AVerbsDebug())
/client/proc/cmd_display_overlay_log,
/client/proc/reload_configuration,
/datum/admins/proc/create_or_modify_area,
+ /client/proc/generate_wikichem_list //DO NOT PRESS UNLESS YOU WANT SUPERLAG
)
GLOBAL_PROTECT(admin_verbs_possess)
GLOBAL_LIST_INIT(admin_verbs_possess, list(/proc/possess, /proc/release))
diff --git a/code/modules/admin/create_mob.dm b/code/modules/admin/create_mob.dm
index 8b6f471e7d..eae59fcb93 100644
--- a/code/modules/admin/create_mob.dm
+++ b/code/modules/admin/create_mob.dm
@@ -25,6 +25,9 @@
H.facial_hair_color = H.hair_color
H.eye_color = random_eye_color()
H.dna.blood_type = random_blood_type()
+ H.saved_underwear = H.underwear
+ H.saved_undershirt = H.undershirt
+ H.saved_socks = H.socks
// Mutant randomizing, doesn't affect the mob appearance unless it's the specific mutant.
H.dna.features["mcolor"] = random_short_color()
@@ -35,8 +38,9 @@
H.dna.features["spines"] = pick(GLOB.spines_list)
H.dna.features["body_markings"] = pick(GLOB.body_markings_list)
H.dna.features["insect_wings"] = pick(GLOB.insect_wings_list)
+ H.dna.features["deco_wings"] = pick(GLOB.deco_wings_list)
H.dna.features["insect_fluff"] = pick(GLOB.insect_fluffs_list)
H.update_body()
H.update_hair()
- H.update_body_parts()
\ No newline at end of file
+ H.update_body_parts()
diff --git a/code/modules/admin/fun_balloon.dm b/code/modules/admin/fun_balloon.dm
index da811a1974..81050e6eae 100644
--- a/code/modules/admin/fun_balloon.dm
+++ b/code/modules/admin/fun_balloon.dm
@@ -61,7 +61,7 @@
to_chat(body, "Your mob has been taken over by a ghost!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(body)])")
body.ghostize(0)
- body.key = C.key
+ C.transfer_ckey(body)
new /obj/effect/temp_visual/gravpush(get_turf(body))
/obj/effect/fun_balloon/sentience/emergency_shuttle
diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm
index 7d74387c43..70ae133a31 100644
--- a/code/modules/admin/secrets.dm
+++ b/code/modules/admin/secrets.dm
@@ -400,7 +400,7 @@
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Chinese Cartoons"))
message_admins("[key_name_admin(usr)] made everything kawaii.")
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
- SEND_SOUND(H, sound('sound/ai/animes.ogg'))
+ SEND_SOUND(H, sound(get_announcer_sound("animes")))
if(H.dna.species.id == "human")
if(H.dna.features["tail_human"] == "None" || H.dna.features["ears"] == "None")
@@ -458,7 +458,7 @@
SSblackbox.record_feedback("nested tally", "admin_secrets_fun_used", 1, list("Mass Braindamage"))
for(var/mob/living/carbon/human/H in GLOB.player_list)
to_chat(H, "You suddenly feel stupid. ")
- H.adjustBrainLoss(60, 80)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 60, 80)
message_admins("[key_name_admin(usr)] made everybody retarded")
if("eagles")//SCRAW
@@ -469,7 +469,7 @@
if(is_station_level(W.z) && !istype(get_area(W), /area/bridge) && !istype(get_area(W), /area/crew_quarters) && !istype(get_area(W), /area/security/prison))
W.req_access = list()
message_admins("[key_name_admin(usr)] activated Egalitarian Station mode")
- priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, 'sound/ai/commandreport.ogg')
+ priority_announce("CentCom airlock control override activated. Please take this time to get acquainted with your coworkers.", null, "commandreport")
if("ak47s")
if(!check_rights(R_FUN))
@@ -744,7 +744,7 @@
var/mob/chosen = players[1]
if (chosen.client)
chosen.client.prefs.copy_to(spawnedMob)
- spawnedMob.key = chosen.key
+ chosen.transfer_ckey(spawnedMob)
players -= chosen
if (ishuman(spawnedMob) && ispath(humanoutfit, /datum/outfit))
var/mob/living/carbon/human/H = spawnedMob
diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm
index 91df9ef85c..b0b9190556 100644
--- a/code/modules/admin/topic.dm
+++ b/code/modules/admin/topic.dm
@@ -2042,7 +2042,7 @@
if(DEAD)
status = "Dead "
health_description = "Status = [status]"
- health_description += " Oxy: [L.getOxyLoss()] - Tox: [L.getToxLoss()] - Fire: [L.getFireLoss()] - Brute: [L.getBruteLoss()] - Clone: [L.getCloneLoss()] - Brain: [L.getBrainLoss()] - Stamina: [L.getStaminaLoss()]"
+ health_description += " Oxy: [L.getOxyLoss()] - Tox: [L.getToxLoss()] - Fire: [L.getFireLoss()] - Brute: [L.getBruteLoss()] - Clone: [L.getCloneLoss()] - Brain: [L.getOrganLoss(ORGAN_SLOT_BRAIN)] - Stamina: [L.getStaminaLoss()]"
else
health_description = "This mob type has no health to speak of."
diff --git a/code/modules/admin/verbs/adminhelp.dm b/code/modules/admin/verbs/adminhelp.dm
index 91fdc78d20..ce4b8f7e39 100644
--- a/code/modules/admin/verbs/adminhelp.dm
+++ b/code/modules/admin/verbs/adminhelp.dm
@@ -318,6 +318,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
RemoveActive()
state = AHELP_CLOSED
GLOB.ahelp_tickets.ListInsert(src)
+ to_chat(initiator, "Ticket closed by [usr?.client?.holder?.fakekey? usr.client.holder.fakekey : "an administrator"]. ")
AddInteraction("Closed by [key_name]. ")
if(!silent)
SSblackbox.record_feedback("tally", "ahelp_stats", 1, "closed")
@@ -336,7 +337,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
addtimer(CALLBACK(initiator, /client/proc/giveadminhelpverb), 50)
AddInteraction("Resolved by [key_name]. ")
- to_chat(initiator, "Your ticket has been resolved by an admin. The Adminhelp verb will be returned to you shortly. ")
+ to_chat(initiator, "Your ticket has been resolved by [usr?.client?.holder?.fakekey? usr.client.holder.fakekey : "an administrator"]. The Adminhelp verb will be returned to you shortly. ")
if(!silent)
SSblackbox.record_feedback("tally", "ahelp_stats", 1, "resolved")
var/msg = "Ticket [TicketHref("#[id]")] resolved by [key_name]"
@@ -353,7 +354,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
SEND_SOUND(initiator, sound('sound/effects/adminhelp.ogg'))
- to_chat(initiator, "- AdminHelp Rejected! - ")
+ to_chat(initiator, "- AdminHelp Rejected by [usr?.client?.holder?.fakekey? usr.client.holder.fakekey : "an administrator"]! - ")
to_chat(initiator, "Your admin help was rejected. The adminhelp verb has been returned to you so that you may try again. ")
to_chat(initiator, "Please try to be calm, clear, and descriptive in admin helps, do not assume the admin has seen any related events, and clearly state the names of anybody you are reporting.")
@@ -369,7 +370,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if(state != AHELP_ACTIVE)
return
- var/msg = "- AdminHelp marked as IC issue! - "
+ var/msg = "- AdminHelp marked as IC issue by [usr?.client?.holder?.fakekey? usr.client.holder.fakekey : "an administrator"]! - "
msg += "Losing is part of the game! "
msg += "It is also possible that your ahelp is unable to be answered properly, due to events occurring in the round. "
if(initiator)
@@ -413,9 +414,9 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
dat += "CLOSED"
else
dat += "UNKNOWN"
- dat += " [GLOB.TAB][TicketHref("Refresh", ref_src)][GLOB.TAB][TicketHref("Re-Title", ref_src, "retitle")]"
+ dat += "[FOURSPACES][TicketHref("Refresh", ref_src)][FOURSPACES][TicketHref("Re-Title", ref_src, "retitle")]"
if(state != AHELP_ACTIVE)
- dat += "[GLOB.TAB][TicketHref("Reopen", ref_src, "reopen")]"
+ dat += "[FOURSPACES][TicketHref("Reopen", ref_src, "reopen")]"
dat += " Opened at: [GAMETIMESTAMP("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - opened_at)] ago)"
if(closed_at)
dat += " Closed at: [GAMETIMESTAMP("hh:mm:ss", closed_at)] (Approx [DisplayTimeText(world.time - closed_at)] ago)"
@@ -423,7 +424,7 @@ GLOBAL_DATUM_INIT(ahelp_tickets, /datum/admin_help_tickets, new)
if(initiator)
dat += "Actions: [FullMonty(ref_src)] "
else
- dat += "DISCONNECTED [GLOB.TAB][ClosureLinks(ref_src)] "
+ dat += "DISCONNECTED [FOURSPACES][ClosureLinks(ref_src)] "
dat += "Log: "
for(var/I in _interactions)
dat += "[I] "
diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm
index e15613c43d..53fdb315b5 100644
--- a/code/modules/admin/verbs/debug.dm
+++ b/code/modules/admin/verbs/debug.dm
@@ -306,7 +306,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
var/mob/living/silicon/pai/pai = new(card)
pai.name = input(choice, "Enter your pAI name:", "pAI Name", "Personal AI") as text
pai.real_name = pai.name
- pai.key = choice.key
+ choice.transfer_ckey(pai)
card.setPersonality(pai)
for(var/datum/paiCandidate/candidate in SSpai.candidates)
if(candidate.key == choice.key)
diff --git a/code/modules/admin/verbs/modifyvariables.dm b/code/modules/admin/verbs/modifyvariables.dm
index 5b74ae7c5b..e70ea1c1b3 100644
--- a/code/modules/admin/verbs/modifyvariables.dm
+++ b/code/modules/admin/verbs/modifyvariables.dm
@@ -534,7 +534,7 @@ GLOBAL_PROTECT(VVpixelmovement)
if (prompt != "Continue")
return FALSE
return TRUE
-
+
/client/proc/modify_variables(atom/O, param_var_name = null, autodetect_class = 0)
if(!check_rights(R_VAREDIT))
@@ -545,7 +545,7 @@ GLOBAL_PROTECT(VVpixelmovement)
var/var_value
if(param_var_name)
- if(!param_var_name in O.vars)
+ if(!(param_var_name in O.vars))
to_chat(src, "A variable with this name ([param_var_name]) doesn't exist in this datum ([O])")
return
variable = param_var_name
diff --git a/code/modules/admin/verbs/one_click_antag.dm b/code/modules/admin/verbs/one_click_antag.dm
index d9732818bd..09a8f692d8 100644
--- a/code/modules/admin/verbs/one_click_antag.dm
+++ b/code/modules/admin/verbs/one_click_antag.dm
@@ -412,7 +412,7 @@
//Spawn the body
var/mob/living/carbon/human/ERTOperative = new ertemplate.mobtype(spawnloc)
chosen_candidate.client.prefs.copy_to(ERTOperative)
- ERTOperative.key = chosen_candidate.key
+ chosen_candidate.transfer_ckey(ERTOperative)
if(ertemplate.enforce_human || ERTOperative.dna.species.dangerous_existence) // Don't want any exploding plasmemes
ERTOperative.set_species(/datum/species/human)
diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm
index a725399b0f..d7dd8db08d 100644
--- a/code/modules/admin/verbs/randomverbs.dm
+++ b/code/modules/admin/verbs/randomverbs.dm
@@ -384,7 +384,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
//Now to give them their mind back.
G_found.mind.transfer_to(new_xeno) //be careful when doing stuff like this! I've already checked the mind isn't in use
- new_xeno.key = G_found.key
+ G_found.transfer_ckey(new_xeno, FALSE)
to_chat(new_xeno, "You have been fully respawned. Enjoy the game.")
var/msg = "[key_name_admin(usr)] has respawned [new_xeno.key] as a filthy xeno. "
message_admins(msg)
@@ -397,7 +397,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/mob/living/carbon/monkey/new_monkey = new
SSjob.SendToLateJoin(new_monkey)
G_found.mind.transfer_to(new_monkey) //be careful when doing stuff like this! I've already checked the mind isn't in use
- new_monkey.key = G_found.key
+ G_found.transfer_ckey(new_monkey, FALSE)
to_chat(new_monkey, "You have been fully respawned. Enjoy the game.")
var/msg = "[key_name_admin(usr)] has respawned [new_monkey.key] as a filthy xeno. "
message_admins(msg)
@@ -437,7 +437,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!new_character.mind.assigned_role)
new_character.mind.assigned_role = "Assistant"//If they somehow got a null assigned role.
- new_character.key = G_found.key
+ G_found.transfer_ckey(new_character, FALSE)
/*
The code below functions with the assumption that the mob is already a traitor if they have a special role.
@@ -560,7 +560,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
var/announce_command_report = TRUE
switch(confirm)
if("Yes")
- priority_announce(input, null, 'sound/ai/commandreport.ogg')
+ priority_announce(input, null, "commandreport")
announce_command_report = FALSE
if("Cancel")
return
@@ -1264,7 +1264,7 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits
target.electrocution_animation(40)
to_chat(target, "The gods have punished you for your sins! ")
if(ADMIN_PUNISHMENT_BRAINDAMAGE)
- target.adjustBrainLoss(199, 199)
+ target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 199, 199)
if(ADMIN_PUNISHMENT_GIB)
target.gib(FALSE)
if(ADMIN_PUNISHMENT_BSA)
diff --git a/code/modules/antagonists/_common/antag_datum.dm b/code/modules/antagonists/_common/antag_datum.dm
index aa91af1dd8..1894d8c7ae 100644
--- a/code/modules/antagonists/_common/antag_datum.dm
+++ b/code/modules/antagonists/_common/antag_datum.dm
@@ -15,7 +15,7 @@ GLOBAL_LIST_EMPTY(antagonists)
var/antag_memory = ""//These will be removed with antag datum
var/antag_moodlet //typepath of moodlet that the mob will gain with their status
var/can_hijack = HIJACK_NEUTRAL //If these antags are alone on shuttle hijack happens.
-
+
//Antag panel properties
var/show_in_antagpanel = TRUE //This will hide adding this antag type in antag panel, use only for internal subtypes that shouldn't be added directly but still show if possessed by mind
var/antagpanel_category = "Uncategorized" //Antagpanel will display these together, REQUIRED
@@ -87,7 +87,7 @@ GLOBAL_LIST_EMPTY(antagonists)
to_chat(owner, "Your mob has been taken over by a ghost! Appeal your job ban if you want to avoid this in the future!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(owner.current)]) to replace a jobbaned player.")
owner.current.ghostize(0)
- owner.current.key = C.key
+ C.transfer_ckey(owner.current, FALSE)
/datum/antagonist/proc/on_removal()
remove_innate_effects()
@@ -96,7 +96,6 @@ GLOBAL_LIST_EMPTY(antagonists)
LAZYREMOVE(owner.antag_datums, src)
if(!silent && owner.current)
farewell()
- owner.objectives -= objectives
var/datum/team/team = get_team()
if(team)
team.remove_member(owner)
@@ -132,14 +131,14 @@ GLOBAL_LIST_EMPTY(antagonists)
report += printplayer(owner)
var/objectives_complete = TRUE
- if(owner.objectives.len)
- report += printobjectives(owner)
- for(var/datum/objective/objective in owner.objectives)
+ if(objectives.len)
+ report += printobjectives(objectives)
+ for(var/datum/objective/objective in objectives)
if(!objective.check_completion())
objectives_complete = FALSE
break
- if(owner.objectives.len == 0 || objectives_complete)
+ if(objectives.len == 0 || objectives_complete)
report += "The [name] was successful! "
else
report += "The [name] has failed! "
@@ -216,25 +215,6 @@ GLOBAL_LIST_EMPTY(antagonists)
return
antag_memory = new_memo
-//This datum will autofill the name with special_role
-//Used as placeholder for minor antagonists, please create proper datums for these
-/datum/antagonist/auto_custom
- show_in_antagpanel = FALSE
- antagpanel_category = "Other"
- show_name_in_check_antagonists = TRUE
-
-/datum/antagonist/auto_custom/on_gain()
- ..()
- name = owner.special_role
- //Add all objectives not already owned by other datums to this one.
- var/list/already_registered_objectives = list()
- for(var/datum/antagonist/A in owner.antag_datums)
- if(A == src)
- continue
- else
- already_registered_objectives |= A.objectives
- objectives = owner.objectives - already_registered_objectives
-
//This one is created by admin tools for custom objectives
/datum/antagonist/custom
antagpanel_category = "Custom"
diff --git a/code/modules/antagonists/abductor/abductor.dm b/code/modules/antagonists/abductor/abductor.dm
index 0fca957ffe..e8d30e8dbe 100644
--- a/code/modules/antagonists/abductor/abductor.dm
+++ b/code/modules/antagonists/abductor/abductor.dm
@@ -26,7 +26,7 @@
sub_role = "Scientist"
outfit = /datum/outfit/abductor/scientist
landmark_type = /obj/effect/landmark/abductor/scientist
- greet_text = "Use your stealth technology and equipment to incapacitate humans for your scientist to retrieve."
+ greet_text = "Use your experimental console and surgical equipment to monitor your agent and experiment upon abducted humans."
show_in_antagpanel = TRUE
/datum/antagonist/abductor/create_team(datum/team/abductor_team/new_team)
@@ -40,17 +40,18 @@
return team
/datum/antagonist/abductor/on_gain()
- owner.special_role = "[name] [sub_role]"
- owner.assigned_role = "[name] [sub_role]"
- owner.objectives += team.objectives
+ owner.special_role = "[name]"
+ owner.assigned_role = "[name]"
+ objectives += team.objectives
finalize_abductor()
+ ADD_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
return ..()
/datum/antagonist/abductor/on_removal()
- owner.objectives -= team.objectives
if(owner.current)
to_chat(owner.current,"You are no longer the [owner.special_role]! ")
owner.special_role = null
+ REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_TRAINING, ABDUCTOR_ANTAGONIST)
return ..()
/datum/antagonist/abductor/greet()
@@ -64,6 +65,7 @@
//Equip
var/mob/living/carbon/human/H = owner.current
H.set_species(/datum/species/abductor)
+
H.real_name = "[team.name] [sub_role]"
H.equipOutfit(outfit)
@@ -75,11 +77,15 @@
update_abductor_icons_added(owner,"abductor")
-/datum/antagonist/abductor/scientist/finalize_abductor()
- ..()
- var/mob/living/carbon/human/H = owner.current
- var/datum/species/abductor/A = H.dna.species
- A.scientist = TRUE
+/datum/antagonist/abductor/scientist/on_gain()
+ ADD_TRAIT(owner, TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST)
+ ADD_TRAIT(owner, TRAIT_SURGEON, ABDUCTOR_ANTAGONIST)
+ . = ..()
+
+/datum/antagonist/abductor/scientist/on_removal()
+ REMOVE_TRAIT(owner, TRAIT_ABDUCTOR_SCIENTIST_TRAINING, ABDUCTOR_ANTAGONIST)
+ REMOVE_TRAIT(owner, TRAIT_SURGEON, ABDUCTOR_ANTAGONIST)
+ . = ..()
/datum/antagonist/abductor/admin_add(datum/mind/new_owner,mob/admin)
var/list/current_teams = list()
@@ -93,8 +99,8 @@
else
return
new_owner.add_antag_datum(src)
- log_admin("[key_name(usr)] made [key_name(new_owner.current)] [name] on [choice]!")
- message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner.current)] [name] on [choice] !")
+ log_admin("[key_name(usr)] made [key_name(new_owner)] [name] on [choice]!")
+ message_admins("[key_name_admin(usr)] made [key_name_admin(new_owner)] [name] on [choice] !")
/datum/antagonist/abductor/get_admin_commands()
. = ..()
@@ -147,7 +153,7 @@
result += ""
for(var/datum/mind/abductor_mind in members)
result += printplayer(abductor_mind)
- result += printobjectives(abductor_mind)
+ result += printobjectives(objectives)
return "[result.Join(" ")]
"
@@ -172,7 +178,6 @@
var/objtype = (prob(75) ? /datum/objective/abductee/random : pick(subtypesof(/datum/objective/abductee/) - /datum/objective/abductee/random))
var/datum/objective/abductee/O = new objtype()
objectives += O
- owner.objectives += objectives
/datum/antagonist/abductee/apply_innate_effects(mob/living/mob_override)
update_abductor_icons_added(mob_override ? mob_override.mind : owner,"abductee")
@@ -214,4 +219,4 @@
/datum/antagonist/proc/update_abductor_icons_removed(datum/mind/alien_mind)
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_ABDUCTOR]
hud.leave_hud(alien_mind.current)
- set_antag_hud(alien_mind.current, null)
\ No newline at end of file
+ set_antag_hud(alien_mind.current, null)
diff --git a/code/modules/antagonists/abductor/equipment/abduction_gear.dm b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
index 1573204d88..c1088cbb3d 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_gear.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_gear.dm
@@ -55,7 +55,7 @@
var/datum/action/A = X
A.UpdateButtonIcon()
-/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user)
+/obj/item/clothing/suit/armor/abductor/vest/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_WEAR_SUIT) //we only give the mob the ability to activate the vest if he's actually wearing it.
return 1
@@ -132,22 +132,26 @@
/obj/item/abductor
icon = 'icons/obj/abductor.dmi'
-/obj/item/abductor/proc/AbductorCheck(user)
- if(isabductor(user))
+/obj/item/abductor/proc/AbductorCheck(mob/user)
+ if(HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING))
+ return TRUE
+ if (istype(user) && user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
return TRUE
to_chat(user, "You can't figure how this works! ")
return FALSE
-/obj/item/abductor/proc/ScientistCheck(user)
- if(!AbductorCheck(user))
- return FALSE
+/obj/item/abductor/proc/ScientistCheck(mob/user)
+ var/training = HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
+ var/sci_training = HAS_TRAIT(user, TRAIT_ABDUCTOR_SCIENTIST_TRAINING) || (user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_SCIENTIST_TRAINING))
- var/mob/living/carbon/human/H = user
- var/datum/species/abductor/S = H.dna.species
- if(S.scientist)
- return TRUE
- to_chat(user, "You're not trained to use this! ")
- return FALSE
+ if(training && !sci_training)
+ to_chat(user, "You're not trained to use this! ")
+ . = FALSE
+ else if(!training && !sci_training)
+ to_chat(user, "You can't figure how this works! ")
+ . = FALSE
+ else
+ . = TRUE
/obj/item/abductor/gizmo
name = "science tool"
@@ -341,8 +345,8 @@
if(QDELETED(G))
return
- if(istype(C.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
- to_chat(user, "Your target seems to have some sort of protective headgear on, blocking the message from being sent! ")
+ if(C.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "Your target seems to have some sort of tinfoil protection on, blocking the message from being sent! ")
return
G.mind_control(command, user)
@@ -520,10 +524,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
/obj/item/abductor_baton/proc/SleepAttack(mob/living/L,mob/living/user)
if(L.incapacitated(TRUE, TRUE))
- if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
- to_chat(user, "The specimen's protective headgear is interfering with the sleep inducement! ")
- L.visible_message("[user] tried to induced sleep in [L] with [src], but [L.p_their()] headgear protected [L.p_them()]! ", \
- "You feel a strange wave of heavy drowsiness wash over you, but your headgear deflects most of it! ")
+ if(L.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "The specimen's tinfoil protection is interfering with the sleep inducement! ")
+ L.visible_message("[user] tried to induced sleep in [L] with [src], but [L.p_their()] tinfoil protected [L.p_them()]! ", \
+ "You feel a strange wave of heavy drowsiness wash over you, but your tinfoil protection deflects most of it! ")
L.drowsyness += 2
return
L.visible_message("[user] has induced sleep in [L] with [src]! ", \
@@ -532,10 +536,10 @@ Congratulations! You are now trained for invasive xenobiology research!"}
L.Sleeping(1200)
log_combat(user, L, "put to sleep")
else
- if(istype(L.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
- to_chat(user, "The specimen's protective headgear is completely blocking our sleep inducement methods! ")
- L.visible_message("[user] tried to induce sleep in [L] with [src], but [L.p_their()] headgear completely protected [L.p_them()]! ", \
- "Any sense of drowsiness is quickly diminished as your headgear deflects the effects! ")
+ if(L.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "The specimen's tinfoil protection is completely blocking our sleep inducement methods! ")
+ L.visible_message("[user] tried to induce sleep in [L] with [src], but [L.p_their()] tinfoil completely protected [L.p_them()]! ", \
+ "Any sense of drowsiness is quickly diminished as your tinfoil protection deflects the effects! ")
return
L.drowsyness += 1
to_chat(user, "Sleep inducement works fully only on stunned specimens! ")
@@ -683,7 +687,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
desc = "Abduct with style - spiky style. Prevents digital tracking."
icon_state = "alienhelmet"
item_state = "alienhelmet"
- blockTracking = 1
+ blockTracking = TRUE
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR
// Operating Table / Beds / Lockers
diff --git a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm
index a69c8fdeff..7e03bbf57a 100644
--- a/code/modules/antagonists/abductor/equipment/abduction_outfits.dm
+++ b/code/modules/antagonists/abductor/equipment/abduction_outfits.dm
@@ -52,5 +52,5 @@
/datum/outfit/abductor/scientist/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
..()
if(!visualsOnly)
- var/obj/item/implant/abductor/beamplant = new /obj/item/implant/abductor(H)
+ var/obj/item/implant/abductor/beamplant = new
beamplant.implant(H)
diff --git a/code/modules/antagonists/abductor/equipment/gland.dm b/code/modules/antagonists/abductor/equipment/gland.dm
index 72edb18020..a35cbbf0e4 100644
--- a/code/modules/antagonists/abductor/equipment/gland.dm
+++ b/code/modules/antagonists/abductor/equipment/gland.dm
@@ -5,6 +5,7 @@
icon_state = "gland"
status = ORGAN_ROBOTIC
beating = TRUE
+ var/true_name = "baseline placebo referencer"
var/cooldown_low = 300
var/cooldown_high = 300
var/next_activation = 0
@@ -16,6 +17,11 @@
var/mind_control_duration = 1800
var/active_mind_control = FALSE
+/obj/item/organ/heart/gland/examine(mob/user)
+ . = ..()
+ if((user.mind && HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)) || isobserver(user))
+ to_chat(user, "It is \a [true_name]. ")
+
/obj/item/organ/heart/gland/proc/ownerCheck()
if(ishuman(owner))
return TRUE
@@ -42,19 +48,19 @@
/obj/item/organ/heart/gland/proc/mind_control(command, mob/living/user)
if(!ownerCheck() || !mind_control_uses || active_mind_control)
- return
+ return FALSE
mind_control_uses--
to_chat(owner, "You suddenly feel an irresistible compulsion to follow an order... ")
to_chat(owner, "[command] ")
active_mind_control = TRUE
- log_admin("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
+ message_admins("[key_name(user)] sent an abductor mind control message to [key_name(owner)]: [command]")
update_gland_hud()
addtimer(CALLBACK(src, .proc/clear_mind_control), mind_control_duration)
/obj/item/organ/heart/gland/proc/clear_mind_control()
if(!ownerCheck() || !active_mind_control)
- return
+ return FALSE
to_chat(owner, "You feel the compulsion fade, and you completely forget about your previous orders. ")
active_mind_control = FALSE
@@ -95,6 +101,7 @@
return
/obj/item/organ/heart/gland/heals
+ true_name = "coherency harmonizer"
cooldown_low = 200
cooldown_high = 400
uses = -1
@@ -109,6 +116,7 @@
owner.adjustOxyLoss(-20)
/obj/item/organ/heart/gland/slime
+ true_name = "gastric animation galvanizer"
cooldown_low = 600
cooldown_high = 1200
uses = -1
@@ -130,6 +138,7 @@
Slime.Leader = owner
/obj/item/organ/heart/gland/mindshock
+ true_name = "neural crosstalk uninhibitor"
cooldown_low = 400
cooldown_high = 700
uses = -1
@@ -151,11 +160,12 @@
if(2)
to_chat(H, "You hear an annoying buzz in your head. ")
H.confused += 15
- H.adjustBrainLoss(10, 160)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10, 160)
if(3)
H.hallucination += 60
/obj/item/organ/heart/gland/pop
+ true_name = "anthropmorphic translocator"
cooldown_low = 900
cooldown_high = 1800
uses = -1
@@ -171,6 +181,7 @@
owner.set_species(species)
/obj/item/organ/heart/gland/ventcrawling
+ true_name = "pliant cartilage enabler"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
@@ -183,6 +194,7 @@
owner.ventcrawler = VENTCRAWLER_ALWAYS
/obj/item/organ/heart/gland/viral
+ true_name = "contamination incubator"
cooldown_low = 1800
cooldown_high = 2400
uses = 1
@@ -217,6 +229,7 @@
return A
/obj/item/organ/heart/gland/trauma
+ true_name = "white matter randomiser"
cooldown_low = 800
cooldown_high = 1200
uses = 5
@@ -235,6 +248,7 @@
owner.gain_trauma_type(BRAIN_TRAUMA_MILD, rand(TRAUMA_RESILIENCE_BASIC, TRAUMA_RESILIENCE_LOBOTOMY))
/obj/item/organ/heart/gland/spiderman
+ true_name = "araneae cloister accelerator"
cooldown_low = 450
cooldown_high = 900
uses = -1
@@ -249,6 +263,7 @@
S.directive = "Protect your nest inside [owner.real_name]."
/obj/item/organ/heart/gland/egg
+ true_name = "roe/enzymatic synthesizer"
cooldown_low = 300
cooldown_high = 400
uses = -1
@@ -264,6 +279,7 @@
new /obj/item/reagent_containers/food/snacks/egg/gland(T)
/obj/item/organ/heart/gland/electric
+ true_name = "electron accumulator/discharger"
cooldown_low = 800
cooldown_high = 1200
uses = -1
@@ -289,6 +305,7 @@
playsound(get_turf(owner), 'sound/magic/lightningshock.ogg', 50, 1)
/obj/item/organ/heart/gland/chem
+ true_name = "intrinsic pharma-provider"
cooldown_low = 50
cooldown_high = 50
uses = -1
@@ -315,6 +332,7 @@
..()
/obj/item/organ/heart/gland/plasma
+ true_name = "effluvium sanguine-synonym emitter"
cooldown_low = 1200
cooldown_high = 1800
uses = -1
diff --git a/code/modules/antagonists/abductor/machinery/camera.dm b/code/modules/antagonists/abductor/machinery/camera.dm
index 41cfa6a954..00e48cb1c7 100644
--- a/code/modules/antagonists/abductor/machinery/camera.dm
+++ b/code/modules/antagonists/abductor/machinery/camera.dm
@@ -55,8 +55,7 @@
actions += set_droppoint_action
/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H)
- var/datum/species/abductor/S = H.dna.species
- return S.scientist
+ return HAS_TRAIT(H, TRAIT_ABDUCTOR_SCIENTIST_TRAINING)
/datum/action/innate/teleport_in
name = "Send To"
diff --git a/code/modules/antagonists/abductor/machinery/console.dm b/code/modules/antagonists/abductor/machinery/console.dm
index 46d69ba9bb..bcf02bda01 100644
--- a/code/modules/antagonists/abductor/machinery/console.dm
+++ b/code/modules/antagonists/abductor/machinery/console.dm
@@ -28,7 +28,7 @@
. = ..()
if(.)
return
- if(!isabductor(user))
+ if(!HAS_TRAIT(user, TRAIT_ABDUCTOR_TRAINING) && !HAS_TRAIT(user.mind, TRAIT_ABDUCTOR_TRAINING))
to_chat(user, "You start mashing alien buttons at random! ")
if(do_after(user,100, target = src))
TeleporterSend()
@@ -178,8 +178,8 @@
c.console = src
/obj/machinery/abductor/console/proc/AddSnapshot(mob/living/carbon/human/target)
- if(istype(target.get_item_by_slot(SLOT_HEAD), /obj/item/clothing/head/foilhat))
- say("Subject wearing specialized protective headgear, unable to get a proper scan!")
+ if(target.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ say("Subject wearing specialized protective tinfoil gear, unable to get a proper scan!")
return
var/datum/icon_snapshot/entry = new
entry.name = target.name
diff --git a/code/modules/antagonists/abductor/machinery/pad.dm b/code/modules/antagonists/abductor/machinery/pad.dm
index 1cb95fbf05..ab636f7d0e 100644
--- a/code/modules/antagonists/abductor/machinery/pad.dm
+++ b/code/modules/antagonists/abductor/machinery/pad.dm
@@ -53,4 +53,4 @@
. = ..()
var/datum/effect_system/spark_spread/S = new
S.set_up(10,0,loc)
- S.start()
\ No newline at end of file
+ S.start()
diff --git a/code/modules/antagonists/blob/blob.dm b/code/modules/antagonists/blob/blob.dm
index 964bc99311..3d6db983dc 100644
--- a/code/modules/antagonists/blob/blob.dm
+++ b/code/modules/antagonists/blob/blob.dm
@@ -30,7 +30,6 @@
var/datum/objective/blob_takeover/main = new
main.owner = owner
objectives += main
- owner.objectives |= objectives
/datum/antagonist/blob/apply_innate_effects(mob/living/mob_override)
if(!isovermind(owner.current))
diff --git a/code/modules/antagonists/blob/blob/blobs/core.dm b/code/modules/antagonists/blob/blob/blobs/core.dm
index 81792ca4f6..58f79e1c73 100644
--- a/code/modules/antagonists/blob/blob/blobs/core.dm
+++ b/code/modules/antagonists/blob/blob/blobs/core.dm
@@ -27,7 +27,7 @@
. = ..()
/obj/structure/blob/core/proc/generate_announcement()
- priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
+ priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak5")
/obj/structure/blob/core/scannerreport()
return "Directs the blob's expansion, gradually expands, and sustains nearby blob spores and blobbernauts."
diff --git a/code/modules/antagonists/blob/blob/powers.dm b/code/modules/antagonists/blob/blob/powers.dm
index 9e915ee0fa..e49d186362 100644
--- a/code/modules/antagonists/blob/blob/powers.dm
+++ b/code/modules/antagonists/blob/blob/powers.dm
@@ -172,7 +172,7 @@
blobber.adjustHealth(blobber.maxHealth * 0.5)
blob_mobs += blobber
var/mob/dead/observer/C = pick(candidates)
- blobber.key = C.key
+ C.transfer_ckey(blobber)
SEND_SOUND(blobber, sound('sound/effects/blobattack.ogg'))
SEND_SOUND(blobber, sound('sound/effects/attackblob.ogg'))
to_chat(blobber, "You are a blobbernaut! ")
diff --git a/code/modules/antagonists/blood_contract/blood_contract.dm b/code/modules/antagonists/blood_contract/blood_contract.dm
new file mode 100644
index 0000000000..4e7238647e
--- /dev/null
+++ b/code/modules/antagonists/blood_contract/blood_contract.dm
@@ -0,0 +1,33 @@
+
+/datum/antagonist/blood_contract
+ name = "Blood Contract Target"
+ show_in_roundend = FALSE
+ show_in_antagpanel = FALSE
+
+/datum/antagonist/blood_contract/on_gain()
+ . = ..()
+ give_objective()
+ start_the_hunt()
+
+/datum/antagonist/blood_contract/proc/give_objective()
+ var/datum/objective/survive/survive = new
+ survive.owner = owner
+ objectives += survive
+
+/datum/antagonist/blood_contract/greet()
+ . = ..()
+ to_chat(owner, "You've been marked for death! Don't let the demons get you! KILL THEM ALL! ")
+
+/datum/antagonist/blood_contract/proc/start_the_hunt()
+ var/mob/living/carbon/human/H = owner.current
+ if(!istype(H))
+ return
+ H.add_atom_colour("#FF0000", ADMIN_COLOUR_PRIORITY)
+ var/obj/effect/mine/pickup/bloodbath/B = new(H)
+ INVOKE_ASYNC(B, /obj/effect/mine/pickup/bloodbath/.proc/mineEffect, H) //could use moving out from the mine
+
+ for(var/mob/living/carbon/human/P in GLOB.player_list)
+ if(P == H)
+ continue
+ to_chat(P, "You have an overwhelming desire to kill [H]. [H.p_theyve(TRUE)] been marked red! Whoever [H.p_they()] [H.p_were()], friend or foe, go kill [H.p_them()]! ")
+ P.put_in_hands(new /obj/item/kitchen/knife/butcher(P), TRUE)
diff --git a/code/modules/antagonists/brainwashing/brainwashing.dm b/code/modules/antagonists/brainwashing/brainwashing.dm
index f1cff2bff4..491ee9d2e5 100644
--- a/code/modules/antagonists/brainwashing/brainwashing.dm
+++ b/code/modules/antagonists/brainwashing/brainwashing.dm
@@ -9,7 +9,6 @@
for(var/O in directives)
var/datum/objective/brainwashing/objective = new(O)
B.objectives += objective
- M.objectives += objective
B.greet()
else
B = new()
@@ -32,10 +31,6 @@
antagpanel_category = "Other"
show_name_in_check_antagonists = TRUE
-/datum/antagonist/brainwashed/on_gain()
- owner.objectives |= objectives
- . = ..()
-
/datum/antagonist/brainwashed/greet()
to_chat(owner, "Your mind reels as it begins focusing on a single purpose... ")
to_chat(owner, "Follow the Directives, at any cost! ")
diff --git a/code/modules/antagonists/brother/brother.dm b/code/modules/antagonists/brother/brother.dm
index f63e81acbf..7c589bb3ab 100644
--- a/code/modules/antagonists/brother/brother.dm
+++ b/code/modules/antagonists/brother/brother.dm
@@ -20,7 +20,6 @@
/datum/antagonist/brother/on_gain()
SSticker.mode.brothers += owner
objectives += team.objectives
- owner.objectives += objectives
owner.special_role = special_role
finalize_brother()
return ..()
diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm
index 252e2b5cbe..0d68660d9d 100644
--- a/code/modules/antagonists/changeling/changeling.dm
+++ b/code/modules/antagonists/changeling/changeling.dm
@@ -83,7 +83,7 @@
if(istype(C))
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
if(B && (B.decoy_override != initial(B.decoy_override)))
- B.vital = TRUE
+ B.organ_flags |= ORGAN_VITAL
B.decoy_override = FALSE
remove_changeling_powers()
. = ..()
@@ -340,7 +340,7 @@
if(istype(C))
var/obj/item/organ/brain/B = C.getorganslot(ORGAN_SLOT_BRAIN)
if(B)
- B.vital = FALSE
+ B.organ_flags &= ~ORGAN_VITAL
B.decoy_override = TRUE
update_changeling_icons_added()
return
@@ -459,8 +459,6 @@
objectives += identity_theft
escape_objective_possible = FALSE
- owner.objectives |= objectives
-
/datum/antagonist/changeling/proc/update_changeling_icons_added()
var/datum/atom_hud/antag/hud = GLOB.huds[ANTAG_HUD_CHANGELING]
hud.join_hud(owner.current)
diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm
index c428c56d45..92a4f28308 100644
--- a/code/modules/antagonists/changeling/powers/mutations.dm
+++ b/code/modules/antagonists/changeling/powers/mutations.dm
@@ -334,7 +334,7 @@
/obj/item/projectile/tentacle/proc/tentacle_stab(mob/living/carbon/human/H, mob/living/carbon/C)
if(H.Adjacent(C))
for(var/obj/item/I in H.held_items)
- if(I.is_sharp())
+ if(I.get_sharpness())
C.visible_message("[H] impales [C] with [H.p_their()] [I.name]! ", "[H] impales you with [H.p_their()] [I.name]! ")
C.apply_damage(I.force, BRUTE, BODY_ZONE_CHEST)
H.do_item_attack_animation(C, used_item = I)
diff --git a/code/modules/antagonists/changeling/powers/regenerate.dm b/code/modules/antagonists/changeling/powers/regenerate.dm
index a1f8e1ef9b..1b27fa9694 100644
--- a/code/modules/antagonists/changeling/powers/regenerate.dm
+++ b/code/modules/antagonists/changeling/powers/regenerate.dm
@@ -35,7 +35,7 @@
B = new C.dna.species.mutant_brain()
else
B = new()
- B.vital = FALSE
+ B.organ_flags &= ~ORGAN_VITAL
B.decoy_override = TRUE
B.Insert(C)
if(ishuman(user))
diff --git a/code/modules/antagonists/changeling/powers/strained_muscles.dm b/code/modules/antagonists/changeling/powers/strained_muscles.dm
index 081b1181dc..1f25e06324 100644
--- a/code/modules/antagonists/changeling/powers/strained_muscles.dm
+++ b/code/modules/antagonists/changeling/powers/strained_muscles.dm
@@ -21,7 +21,7 @@
to_chat(user, "Our muscles tense and strengthen. ")
changeling.chem_recharge_slowdown += 0.5
else
- REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
+ user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
to_chat(user, "Our muscles relax. ")
changeling.chem_recharge_slowdown -= 0.5
if(stacks >= 20)
@@ -36,12 +36,12 @@
/obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user)
var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling)
while(active)
- ADD_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
+ user.add_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
if(user.stat != CONSCIOUS || user.staminaloss >= 90)
active = !active
to_chat(user, "Our muscles relax without the energy to strengthen them. ")
user.Knockdown(40)
- REMOVE_TRAIT(user, TRAIT_GOTTAGOFAST, "changeling_muscles")
+ user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES)
changeling.chem_recharge_slowdown -= 0.5
break
diff --git a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
index 97d7f0c128..8000be87e6 100644
--- a/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
+++ b/code/modules/antagonists/clockcult/clock_effects/clock_sigils.dm
@@ -349,7 +349,7 @@
to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form! ")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.")
L.ghostize(0)
- L.key = C.key
+ C.transfer_ckey(L, FALSE)
var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src))
animate(V, alpha = 0, transform = matrix()*2, time = 8)
playsound(L, 'sound/magic/staff_healing.ogg', 50, 1)
@@ -366,6 +366,8 @@
break
if(!GLOB.ratvar_awakens)
+ if(GLOB.clockwork_vitality <= 0)
+ break
GLOB.clockwork_vitality -= vitality_used
sleep(2)
diff --git a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
index 3ad6684725..07b4366194 100644
--- a/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clock_weapons/ratvarian_spear.dm
@@ -35,7 +35,7 @@
/obj/item/clockwork/weapon/ratvarian_spear/attack(mob/living/target, mob/living/carbon/human/user)
. = ..()
- if(!QDELETED(target) && target.stat != DEAD && !target.anti_magic_check() && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
+ if(!QDELETED(target) && target.stat != DEAD && !target.anti_magic_check(chargecost = 0) && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
var/bonus_damage = bonus_burn //normally a total of 20 damage, 30 with ratvar
if(issilicon(target))
target.visible_message("[target] shudders violently at [src]'s touch! ", "ERROR: Temperature rising! ")
diff --git a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
index 0ac96c47f9..88cf420420 100644
--- a/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
+++ b/code/modules/antagonists/clockcult/clock_items/clockwork_armor.dm
@@ -50,7 +50,7 @@
to_chat(user, "The helmet tries to drive a spike through your head as you scramble to remove it! ")
user.emote("scream")
user.apply_damage(30, BRUTE, BODY_ZONE_HEAD)
- user.adjustBrainLoss(30)
+ user.adjustOrganLoss(ORGAN_SLOT_BRAIN, 30)
addtimer(CALLBACK(user, /mob/living.proc/dropItemToGround, src, TRUE), 1) //equipped happens before putting stuff on(but not before picking items up), 1). thus, we need to wait for it to be on before forcing it off.
/obj/item/clothing/head/helmet/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
diff --git a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm
index 12af249bee..2be0fdde11 100644
--- a/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm
+++ b/code/modules/antagonists/clockcult/clock_items/construct_chassis.dm
@@ -55,7 +55,7 @@
pre_spawn()
visible_message(creation_message)
var/mob/living/construct = new construct_type(get_turf(src))
- construct.key = user.key
+ user.transfer_ckey(construct, FALSE)
post_spawn(construct)
qdel(user)
qdel(src)
diff --git a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
index f44f67e9cb..644d9eedd5 100644
--- a/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
+++ b/code/modules/antagonists/clockcult/clock_items/judicial_visor.dm
@@ -27,7 +27,7 @@
qdel(blaster)
return ..()
-/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user)
+/obj/item/clothing/glasses/judicial_visor/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot != SLOT_GLASSES)
return 0
return ..()
@@ -190,8 +190,8 @@
for(var/mob/living/L in range(1, src))
if(is_servant_of_ratvar(L))
continue
- if(L.anti_magic_check())
- var/atom/I = L.anti_magic_check()
+ var/atom/I = L.anti_magic_check()
+ if(I)
if(isitem(I))
L.visible_message("Strange energy flows into [L]'s [I.name]! ", \
"Your [I.name] shields you from [src]! ")
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
index da499065d7..3d467350ff 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_applications.dm
@@ -119,3 +119,33 @@
var/datum/clockwork_scripture/create_object/construct/clockwork_marauder/CM = new()
CM.recent_marauders--
qdel(CM)
+
+//Summon Neovgre: Summon a very powerful combat mech that explodes when destroyed for massive damage.
+/datum/clockwork_scripture/create_object/summon_arbiter
+ descname = "Powerful Assault Mech"
+ name = "Summon Neovgre, the Anima Bulwark"
+ desc = "Calls forth the mighty Anima Bulwark, a weapon of unmatched power,\
+ mech with superior defensive and offensive capabilities. It will \
+ steadily regenerate HP and triple its regeneration speed while standing \
+ on a clockwork tile. It will automatically draw power from nearby sigils of \
+ transmission should the need arise. Its Arbiter laser cannon can decimate foes \
+ from a range and is capable of smashing through any barrier presented to it. \
+ Be warned, choosing to pilot Neovgre is a lifetime commitment, once you are \
+ in you cannot leave and when it is destroyed it will explode catastrophically with you inside."
+ invocations = list("By the strength of the alloy...!!", "...call forth the Arbiter!!")
+ channel_time = 200 // This is a strong fucking weapon, 20 seconds channel time is getting off light I tell ya.
+ power_cost = 75000 //75 KW
+ usage_tip = "Neovgre is a powerful mech that will crush your enemies!"
+ invokers_required = 5
+ multiple_invokers_used = TRUE
+ object_path = /obj/mecha/combat/neovgre
+ tier = SCRIPTURE_APPLICATION
+ primary_component = BELLIGERENT_EYE
+ sort_priority = 2
+ creator_message = "Neovgre, the Anima Bulwark towers over you... your enemies reckoning has come. "
+
+/datum/clockwork_scripture/create_object/summon_arbiter/check_special_requirements()
+ if(GLOB.neovgre_exists)
+ to_chat(invoker, "\"You've already got one...\" ")
+ return FALSE
+ return ..()
diff --git a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
index 6d6b1fa9d0..82c1291433 100644
--- a/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
+++ b/code/modules/antagonists/clockcult/clock_scriptures/scripture_drivers.dm
@@ -216,6 +216,9 @@
if(is_reebe(invoker.z))
to_chat(invoker, "You're already at Reebe. ")
return
+ if(!isturf(invoker.loc))
+ to_chat(invoker, "You must be visible to return! ")
+ return
return TRUE
/datum/clockwork_scripture/abscond/recital()
diff --git a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm
index 05f3ca5917..c01c7f0f57 100644
--- a/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/eminence_spire.dm
@@ -64,7 +64,7 @@
message_admins("Admin [key_name_admin(user)] directly became the Eminence of the cult! ")
log_admin("Admin [key_name(user)] made themselves the Eminence.")
var/mob/camera/eminence/eminence = new(get_turf(src))
- eminence.key = user.key
+ user.transfer_ckey(eminence, FALSE)
hierophant_message("Ratvar has directly assigned the Eminence! ")
for(var/mob/M in servants_and_ghosts())
M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE)
@@ -138,7 +138,7 @@
playsound(src, 'sound/machines/clockcult/ark_damage.ogg', 50, FALSE)
var/mob/camera/eminence/eminence = new(get_turf(src))
eminence_nominee = pick(candidates)
- eminence.key = eminence_nominee.key
+ eminence_nominee.transfer_ckey(eminence)
hierophant_message("A ghost has ascended into the Eminence! ")
for(var/mob/M in servants_and_ghosts())
M.playsound_local(M, 'sound/machines/clockcult/eminence_selected.ogg', 50, FALSE)
diff --git a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
index 7654c0203b..3a461b7745 100644
--- a/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/heralds_beacon.dm
@@ -78,7 +78,7 @@
return
voters += user.key
else
- if(!user.key in voters)
+ if(!(user.key in voters))
return
voters -= user.key
var/votes_left = votes_needed - voters.len
diff --git a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
index df0083e845..7afd9e7dbc 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ocular_warden.dm
@@ -60,7 +60,7 @@
else
if(isliving(target))
var/mob/living/L = target
- if(!L.anti_magic_check())
+ if(!L.anti_magic_check(chargecost = 0))
if(isrevenant(L))
var/mob/living/simple_animal/revenant/R = L
if(R.revealed)
diff --git a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
index 9341a7ee6a..c17885315f 100644
--- a/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/ratvar_the_clockwork_justicar.dm
@@ -45,7 +45,7 @@
return FALSE
var/mob/living/simple_animal/drone/cogscarab/ratvar/R = new/mob/living/simple_animal/drone/cogscarab/ratvar(get_turf(src))
R.visible_message("[R] forms, and its eyes blink open, glowing bright red! ")
- R.key = O.key
+ O.transfer_ckey(R, FALSE)
/obj/structure/destructible/clockwork/massive/ratvar/Bump(atom/A)
var/turf/T = get_turf(A)
diff --git a/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm b/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm
index 10c68b606f..1158b02a4c 100644
--- a/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/taunting_trail.dm
@@ -53,7 +53,7 @@
/obj/structure/destructible/clockwork/taunting_trail/proc/affect_mob(mob/living/L)
if(istype(L) && !is_servant_of_ratvar(L))
- if(!L.anti_magic_check())
+ if(!L.anti_magic_check(chargecost = 0))
L.confused = min(L.confused + 15, 50)
L.dizziness = min(L.dizziness + 15, 50)
if(L.confused >= 25)
diff --git a/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm b/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
index 8d65574987..6aede1592e 100644
--- a/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/traps/steam_vent.dm
@@ -7,7 +7,6 @@
break_message = "The vent snaps and collapses! "
max_integrity = 100
density = FALSE
- layer = BELOW_OBJ_LAYER
/obj/structure/destructible/clockwork/trap/steam_vent/activate()
opacity = !opacity
diff --git a/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm b/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
index fb8397eed7..32b1b61dd1 100644
--- a/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
+++ b/code/modules/antagonists/clockcult/clock_structures/wall_gear.dm
@@ -5,7 +5,6 @@
unanchored_icon = "wall_gear"
climbable = TRUE
max_integrity = 100
- layer = BELOW_OBJ_LAYER
construction_value = 3
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
break_message = "The gear breaks apart into shards of alloy! "
diff --git a/code/modules/antagonists/cult/cult.dm b/code/modules/antagonists/cult/cult.dm
index 47cf2abf3f..9989058d43 100644
--- a/code/modules/antagonists/cult/cult.dm
+++ b/code/modules/antagonists/cult/cult.dm
@@ -35,7 +35,6 @@
/datum/antagonist/cult/proc/add_objectives()
objectives |= cult_team.objectives
- owner.objectives |= objectives
/datum/antagonist/cult/Destroy()
QDEL_NULL(communion)
diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm
index 10759afcd0..06ea2cbe0a 100644
--- a/code/modules/antagonists/cult/cult_items.dm
+++ b/code/modules/antagonists/cult/cult_items.dm
@@ -275,7 +275,7 @@
desc = "A torn, dust-caked hood. Strange letters line the inside."
flags_inv = HIDEFACE|HIDEHAIR|HIDEEARS
flags_cover = HEADCOVERSEYES
- armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10)
+ armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 65, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10)
cold_protection = HEAD
min_cold_protection_temperature = HELMET_MIN_TEMP_PROTECT
heat_protection = HEAD
@@ -288,7 +288,7 @@
item_state = "cultrobes"
body_parts_covered = CHEST|GROIN|LEGS|ARMS
allowed = list(/obj/item/tome, /obj/item/melee/cultblade)
- armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 25, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10)
+ armor = list("melee" = 40, "bullet" = 30, "laser" = 40,"energy" = 20, "bomb" = 65, "bio" = 10, "rad" = 0, "fire" = 10, "acid" = 10)
flags_inv = HIDEJUMPSUIT
cold_protection = CHEST|GROIN|LEGS|ARMS
min_cold_protection_temperature = ARMOR_MIN_TEMP_PROTECT
diff --git a/code/modules/antagonists/cult/cult_structures.dm b/code/modules/antagonists/cult/cult_structures.dm
index f56c6f7fb5..0dd6b08c4d 100644
--- a/code/modules/antagonists/cult/cult_structures.dm
+++ b/code/modules/antagonists/cult/cult_structures.dm
@@ -86,7 +86,7 @@
var/static/image/radial_whetstone = image(icon = 'icons/obj/kitchen.dmi', icon_state = "cult_sharpener")
var/static/image/radial_shell = image(icon = 'icons/obj/wizard.dmi', icon_state = "construct-cult")
- var/static/image/radial_unholy_water = image(icon = 'icons/obj/chemical.dmi', icon_state = "holyflask")
+ var/static/image/radial_unholy_water = image(icon = 'icons/obj/drinks.dmi', icon_state = "holyflask")
/obj/structure/destructible/cult/talisman/Initialize()
. = ..()
diff --git a/code/modules/antagonists/cult/ritual.dm b/code/modules/antagonists/cult/ritual.dm
index 69941f582d..b9e4da8677 100644
--- a/code/modules/antagonists/cult/ritual.dm
+++ b/code/modules/antagonists/cult/ritual.dm
@@ -107,7 +107,7 @@ This file contains the cult dagger and rune list code
if(!(A in summon_objective.summon_spots)) // Check again to make sure they didn't move
to_chat(user, "The Geometer can only be summoned where the veil is weak - in [english_list(summon_objective.summon_spots)]! ")
return
- priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/ai/spanomalies.ogg')
+ priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", "spanomalies")
for(var/B in spiral_range_turfs(1, user, 1))
var/obj/structure/emergency_shield/sanguine/N = new(B)
shields += N
diff --git a/code/modules/antagonists/cult/runes.dm b/code/modules/antagonists/cult/runes.dm
index bfc4955f68..f0fc59834c 100644
--- a/code/modules/antagonists/cult/runes.dm
+++ b/code/modules/antagonists/cult/runes.dm
@@ -237,7 +237,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(M, "You need at least two invokers to convert [convertee]! ")
log_game("Offer rune failed - tried conversion with one invoker")
return 0
- if(convertee.anti_magic_check(TRUE, TRUE, FALSE, 0)) //Not chargecost because it can be spammed
+ if(convertee.anti_magic_check(TRUE, TRUE, chargecost = 0)) //Not major because it can be spammed
for(var/M in invokers)
to_chat(M, "Something is shielding [convertee]'s mind! ")
log_game("Offer rune failed - convertee had anti-magic")
@@ -575,7 +575,7 @@ structure_check() searches for nearby cultist structures required for the invoca
to_chat(mob_to_revive.mind, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form.")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(mob_to_revive)]) to replace an AFK player.")
mob_to_revive.ghostize(0)
- mob_to_revive.key = C.key
+ C.transfer_ckey(mob_to_revive, FALSE)
else
fail_invoke()
return
@@ -767,7 +767,7 @@ structure_check() searches for nearby cultist structures required for the invoca
set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
- var/atom/I = L.anti_magic_check()
+ var/atom/I = L.anti_magic_check(chargecost = 0)
if(I)
if(isitem(I))
to_chat(L, "[I] suddenly burns hotly before returning to normal! ")
@@ -797,7 +797,7 @@ structure_check() searches for nearby cultist structures required for the invoca
set_light(6, 1, color)
for(var/mob/living/L in viewers(T))
if(!iscultist(L) && L.blood_volume)
- if(L.anti_magic_check())
+ if(L.anti_magic_check(chargecost = 0))
continue
L.take_overall_damage(tick_damage*multiplier, tick_damage*multiplier)
if(is_servant_of_ratvar(L))
@@ -870,7 +870,7 @@ structure_check() searches for nearby cultist structures required for the invoca
visible_message("A cloud of red mist forms above [src], and from within steps... a [new_human.gender == FEMALE ? "wo":""]man. ")
to_chat(user, "Your blood begins flowing into [src]. You must remain in place and conscious to maintain the forms of those summoned. This will hurt you slowly but surely... ")
var/obj/structure/emergency_shield/invoker/N = new(T)
- new_human.key = ghost_to_spawn.key
+ ghost_to_spawn.transfer_ckey(new_human, FALSE)
SSticker.mode.add_cultist(new_human.mind, 0)
to_chat(new_human, "You are a servant of the Geometer. You have been made semi-corporeal by the cult of Nar'Sie, and you are to serve them at all costs. ")
diff --git a/code/modules/antagonists/devil/devil.dm b/code/modules/antagonists/devil/devil.dm
index 3f2bd003a3..2e38734b6f 100644
--- a/code/modules/antagonists/devil/devil.dm
+++ b/code/modules/antagonists/devil/devil.dm
@@ -539,17 +539,17 @@ GLOBAL_LIST_INIT(devil_suffix, list(" the Red", " the Soulless", " the Master",
var/list/parts = list()
parts += "The devil's true name is: [truename]"
parts += "The devil's bans were:"
- parts += "[GLOB.TAB][GLOB.lawlorify[LORE][ban]]"
- parts += "[GLOB.TAB][GLOB.lawlorify[LORE][bane]]"
- parts += "[GLOB.TAB][GLOB.lawlorify[LORE][obligation]]"
- parts += "[GLOB.TAB][GLOB.lawlorify[LORE][banish]]"
+ parts += "[FOURSPACES][GLOB.lawlorify[LORE][ban]]"
+ parts += "[FOURSPACES][GLOB.lawlorify[LORE][bane]]"
+ parts += "[FOURSPACES][GLOB.lawlorify[LORE][obligation]]"
+ parts += "[FOURSPACES][GLOB.lawlorify[LORE][banish]]"
return parts.Join(" ")
/datum/antagonist/devil/roundend_report()
var/list/parts = list()
parts += printplayer(owner)
parts += printdevilinfo()
- parts += printobjectives(owner)
+ parts += printobjectives(objectives)
return parts.Join(" ")
//A simple super light weight datum for the codex gigas.
diff --git a/code/modules/antagonists/devil/imp/imp.dm b/code/modules/antagonists/devil/imp/imp.dm
index da51a5d698..fa5263059a 100644
--- a/code/modules/antagonists/devil/imp/imp.dm
+++ b/code/modules/antagonists/devil/imp/imp.dm
@@ -57,3 +57,18 @@
visible_message("[src] screams in agony as it sublimates into a sulfurous smoke. ")
ghostize()
qdel(src)
+
+/datum/antagonist/imp
+ name = "Imp"
+ antagpanel_category = "Devil"
+ show_in_roundend = FALSE
+
+/datum/antagonist/imp/on_gain()
+ . = ..()
+ give_objectives()
+
+/datum/antagonist/imp/proc/give_objectives()
+ var/datum/objective/newobjective = new
+ newobjective.explanation_text = "Try to get a promotion to a higher devilic rank."
+ newobjective.owner = owner
+ objectives += newobjective
\ No newline at end of file
diff --git a/code/modules/antagonists/devil/true_devil/_true_devil.dm b/code/modules/antagonists/devil/true_devil/_true_devil.dm
index 1df81a797b..df761ac183 100644
--- a/code/modules/antagonists/devil/true_devil/_true_devil.dm
+++ b/code/modules/antagonists/devil/true_devil/_true_devil.dm
@@ -146,14 +146,9 @@
/mob/living/carbon/true_devil/attack_ghost(mob/dead/observer/user as mob)
if(ascended || user.mind.soulOwner == src.mind)
var/mob/living/simple_animal/imp/S = new(get_turf(loc))
- S.key = user.key
- S.mind.assigned_role = "Imp"
- S.mind.special_role = "Imp"
- var/datum/objective/newobjective = new
- newobjective.explanation_text = "Try to get a promotion to a higher devilic rank."
- S.mind.objectives += newobjective
- to_chat(S, S.playstyle_string)
- to_chat(S, "Objective #[1] : [newobjective.explanation_text]")
+ user.transfer_ckey(S, FALSE)
+ var/datum/antagonist/imp/A = new()
+ S.mind.add_antag_datum(A)
else
return ..()
diff --git a/code/modules/antagonists/disease/disease_abilities.dm b/code/modules/antagonists/disease/disease_abilities.dm
index 07cd3030b1..dc2249006c 100644
--- a/code/modules/antagonists/disease/disease_abilities.dm
+++ b/code/modules/antagonists/disease/disease_abilities.dm
@@ -5,25 +5,48 @@ is currently following.
*/
GLOBAL_LIST_INIT(disease_ability_singletons, list(
- new /datum/disease_ability/action/cough(),
- new /datum/disease_ability/action/sneeze(),
- new /datum/disease_ability/action/infect(),
- new /datum/disease_ability/symptom/cough(),
- new /datum/disease_ability/symptom/sneeze(),\
- new /datum/disease_ability/symptom/hallucigen(),
- new /datum/disease_ability/symptom/choking(),
- new /datum/disease_ability/symptom/confusion(),
- new /datum/disease_ability/symptom/youth(),
- new /datum/disease_ability/symptom/vomit(),
- new /datum/disease_ability/symptom/voice_change(),
- new /datum/disease_ability/symptom/visionloss(),
- new /datum/disease_ability/symptom/viraladaptation(),
- new /datum/disease_ability/symptom/vitiligo(),
- new /datum/disease_ability/symptom/sensory_restoration(),
- new /datum/disease_ability/symptom/itching(),
- new /datum/disease_ability/symptom/weight_loss(),
- new /datum/disease_ability/symptom/metabolism_heal(),
- new /datum/disease_ability/symptom/coma_heal()
+ new /datum/disease_ability/action/cough,
+ new /datum/disease_ability/action/sneeze,
+ new /datum/disease_ability/action/infect,
+ new /datum/disease_ability/symptom/mild/cough,
+ new /datum/disease_ability/symptom/mild/sneeze,
+ new /datum/disease_ability/symptom/medium/shedding,
+ new /datum/disease_ability/symptom/medium/beard,
+ new /datum/disease_ability/symptom/medium/hallucigen,
+ new /datum/disease_ability/symptom/medium/choking,
+ new /datum/disease_ability/symptom/medium/confusion,
+ new /datum/disease_ability/symptom/medium/vomit,
+ new /datum/disease_ability/symptom/medium/voice_change,
+ new /datum/disease_ability/symptom/medium/visionloss,
+ new /datum/disease_ability/symptom/medium/deafness,
+ new /datum/disease_ability/symptom/powerful/narcolepsy,
+ new /datum/disease_ability/symptom/medium/fever,
+ new /datum/disease_ability/symptom/medium/shivering,
+ new /datum/disease_ability/symptom/medium/headache,
+ new /datum/disease_ability/symptom/medium/nano_boost,
+ new /datum/disease_ability/symptom/medium/nano_destroy,
+ new /datum/disease_ability/symptom/medium/viraladaptation,
+ new /datum/disease_ability/symptom/medium/viralevolution,
+ new /datum/disease_ability/symptom/medium/vitiligo,
+ new /datum/disease_ability/symptom/medium/revitiligo,
+ new /datum/disease_ability/symptom/medium/itching,
+ new /datum/disease_ability/symptom/medium/heal/weight_loss,
+ new /datum/disease_ability/symptom/medium/heal/sensory_restoration,
+ new /datum/disease_ability/symptom/medium/heal/mind_restoration,
+ new /datum/disease_ability/symptom/powerful/fire,
+ new /datum/disease_ability/symptom/powerful/flesh_eating,
+// new /datum/disease_ability/symptom/powerful/genetic_mutation,
+ new /datum/disease_ability/symptom/powerful/inorganic_adaptation,
+ new /datum/disease_ability/symptom/powerful/heal/starlight,
+ new /datum/disease_ability/symptom/powerful/heal/oxygen,
+ new /datum/disease_ability/symptom/powerful/heal/chem,
+ new /datum/disease_ability/symptom/powerful/heal/metabolism,
+ new /datum/disease_ability/symptom/powerful/heal/dark,
+ new /datum/disease_ability/symptom/powerful/heal/water,
+ new /datum/disease_ability/symptom/powerful/heal/plasma,
+ new /datum/disease_ability/symptom/powerful/heal/radiation,
+ new /datum/disease_ability/symptom/powerful/heal/coma,
+ new /datum/disease_ability/symptom/powerful/youth
))
/datum/disease_ability
@@ -54,7 +77,13 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
stage_speed += initial(S.stage_speed)
transmittable += initial(S.transmittable)
threshold_block += " [initial(S.threshold_desc)]"
- stat_block = "Resistance: [resistance] Stealth: [stealth] Stage Speed: [stage_speed] Transmissibility: [transmittable] "
+ stat_block = "Resistance: [resistance] Stealth: [stealth] Stage Speed: [stage_speed] Transmissibility: [transmittable] "
+ if(symptoms.len == 1) //lazy boy's dream
+ name = initial(S.name)
+ if(short_desc == "")
+ short_desc = initial(S.desc)
+ if(long_desc == "")
+ long_desc = initial(S.desc)
/datum/disease_ability/proc/CanBuy(mob/camera/disease/D)
if(world.time < D.next_adaptation_time)
@@ -77,8 +106,10 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
for(var/T in symptoms)
var/datum/symptom/S = new T()
SD.symptoms += S
+ S.OnAdd(SD)
if(SD.processing)
- S.Start(SD)
+ if(S.Start(SD))
+ S.next_activation = world.time + rand(S.symptom_delay_min * 10, S.symptom_delay_max * 10)
SD.Refresh()
for(var/T in actions)
var/datum/action/A = new T()
@@ -105,6 +136,7 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
var/datum/symptom/S = locate(T) in SD.symptoms
if(S)
SD.symptoms -= S
+ S.OnRemove(SD)
if(SD.processing)
S.End(SD)
qdel(S)
@@ -152,8 +184,9 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
return FALSE
to_chat(D, "You force [L.real_name] to cough. ")
L.emote("cough")
- var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
- SD.spread(2)
+ if(L.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth
+ var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
+ SD.spread(2)
StartCooldown()
return TRUE
@@ -185,11 +218,12 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
return FALSE
to_chat(D, "You force [L.real_name] to sneeze. ")
L.emote("sneeze")
- var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
+ if(L.CanSpreadAirborneDisease()) //don't spread germs if they covered their mouth
+ var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
- for(var/mob/living/M in oview(4, SD.affected_mob))
- if(is_A_facing_B(SD.affected_mob, M) && disease_air_spread_walk(get_turf(SD.affected_mob), get_turf(M)))
- M.AirborneContractDisease(SD, TRUE)
+ for(var/mob/living/M in oview(4, SD.affected_mob))
+ if(is_A_facing_B(SD.affected_mob, M) && disease_air_spread_walk(get_turf(SD.affected_mob), get_turf(M)))
+ M.AirborneContractDisease(SD, TRUE)
StartCooldown()
return TRUE
@@ -235,154 +269,192 @@ GLOBAL_LIST_INIT(disease_ability_singletons, list(
StartCooldown()
return TRUE
-//passive symptom abilities
+/*******************BASE SYMPTOM TYPES*******************/
+// cost is for convenience and can be changed. If you're changing req_tot_points then don't use the subtype...
+//healing costs more so you have to techswitch from naughty disease otherwise we'd have friendly disease for easy greentext (no fun!)
-/datum/disease_ability/symptom/cough
- name = "Involuntary Coughing"
- symptoms = list(/datum/symptom/cough)
+/datum/disease_ability/symptom/mild
cost = 2
required_total_points = 4
+ category = "Symptom (Weak)"
+
+/datum/disease_ability/symptom/medium
+ cost = 4
+ required_total_points = 8
+ category = "Symptom"
+
+/datum/disease_ability/symptom/medium/heal
+ cost = 5
+ category = "Symptom (+)"
+
+/datum/disease_ability/symptom/powerful
+ cost = 4
+ required_total_points = 16
+ category = "Symptom (Strong)"
+
+/datum/disease_ability/symptom/powerful/heal
+ cost = 8
+ category = "Symptom (Strong+)"
+
+
+/******MILD******/
+
+/datum/disease_ability/symptom/mild/cough
+ name = "Involuntary Coughing"
+ symptoms = list(/datum/symptom/cough)
short_desc = "Cause victims to cough intermittently."
long_desc = "Cause victims to cough intermittently, spreading your infection if your transmissibility is high."
-/datum/disease_ability/symptom/sneeze
+/datum/disease_ability/symptom/mild/sneeze
name = "Involuntary Sneezing"
symptoms = list(/datum/symptom/sneeze)
- cost = 2
- required_total_points = 4
short_desc = "Cause victims to sneeze intermittently."
long_desc = "Cause victims to sneeze intermittently, spreading your infection and also increasing transmissibility and resistance, at the cost of stealth."
-/datum/disease_ability/symptom/beard
- //I don't think I need to justify the fact that this is the best symptom
- name = "Beard Growth"
- symptoms = list(/datum/symptom/beard)
- cost = 1
- required_total_points = 8
- short_desc = "Cause all victims to grow a luscious beard."
- long_desc = "Cause all victims to grow a luscious beard. Decreases stats slightly. Ineffective against Santa Claus."
+/******MEDIUM******/
-/datum/disease_ability/symptom/hallucigen
- name = "Hallucinations"
+/datum/disease_ability/symptom/medium/shedding
+ symptoms = list(/datum/symptom/shedding)
+
+/datum/disease_ability/symptom/medium/beard
+ symptoms = list(/datum/symptom/beard)
+ short_desc = "Cause all victims to grow a luscious beard."
+ long_desc = "Cause all victims to grow a luscious beard. Ineffective against Santa Claus."
+
+/datum/disease_ability/symptom/medium/hallucigen
symptoms = list(/datum/symptom/hallucigen)
- cost = 4
- required_total_points = 8
short_desc = "Cause victims to hallucinate."
long_desc = "Cause victims to hallucinate. Decreases stats, especially resistance."
-
-/datum/disease_ability/symptom/choking
- name = "Choking"
+/datum/disease_ability/symptom/medium/choking
symptoms = list(/datum/symptom/choking)
- cost = 4
- required_total_points = 8
short_desc = "Cause victims to choke."
long_desc = "Cause victims to choke, threatening asphyxiation. Decreases stats, especially transmissibility."
-
-/datum/disease_ability/symptom/confusion
- name = "Confusion"
+/datum/disease_ability/symptom/medium/confusion
symptoms = list(/datum/symptom/confusion)
- cost = 4
- required_total_points = 8
short_desc = "Cause victims to become confused."
long_desc = "Cause victims to become confused intermittently."
-
-/datum/disease_ability/symptom/youth
- name = "Eternal Youth"
- symptoms = list(/datum/symptom/youth)
- cost = 4
- required_total_points = 8
- short_desc = "Cause victims to become eternally young."
- long_desc = "Cause victims to become eternally young. Provides boosts to all stats except transmissibility."
-
-
-/datum/disease_ability/symptom/vomit
- name = "Vomiting"
+/datum/disease_ability/symptom/medium/vomit
symptoms = list(/datum/symptom/vomit)
- cost = 4
- required_total_points = 8
short_desc = "Cause victims to vomit."
long_desc = "Cause victims to vomit. Slightly increases transmissibility. Vomiting also also causes the victims to lose nutrition and removes some toxin damage."
-
-/datum/disease_ability/symptom/voice_change
- name = "Voice Changing"
+/datum/disease_ability/symptom/medium/voice_change
symptoms = list(/datum/symptom/voice_change)
- cost = 4
- required_total_points = 8
short_desc = "Change the voice of victims."
long_desc = "Change the voice of victims, causing confusion in communications."
-
-/datum/disease_ability/symptom/visionloss
- name = "Vision Loss"
+/datum/disease_ability/symptom/medium/visionloss
symptoms = list(/datum/symptom/visionloss)
- cost = 4
- required_total_points = 8
short_desc = "Damage the eyes of victims, eventually causing blindness."
long_desc = "Damage the eyes of victims, eventually causing blindness. Decreases all stats."
+/datum/disease_ability/symptom/medium/deafness
+ symptoms = list(/datum/symptom/deafness)
-/datum/disease_ability/symptom/viraladaptation
- name = "Self-Adaptation"
+/datum/disease_ability/symptom/medium/fever
+ symptoms = list(/datum/symptom/fever)
+
+/datum/disease_ability/symptom/medium/shivering
+ symptoms = list(/datum/symptom/shivering)
+
+/datum/disease_ability/symptom/medium/headache
+ symptoms = list(/datum/symptom/headache)
+
+/datum/disease_ability/symptom/medium/nano_boost
+ symptoms = list(/datum/symptom/nano_boost)
+
+/datum/disease_ability/symptom/medium/nano_destroy
+ symptoms = list(/datum/symptom/nano_destroy)
+
+/datum/disease_ability/symptom/medium/viraladaptation
symptoms = list(/datum/symptom/viraladaptation)
- cost = 4
- required_total_points = 8
short_desc = "Cause your infection to become more resistant to detection and eradication."
long_desc = "Cause your infection to mimic the function of normal body cells, becoming much harder to spot and to eradicate, but reducing its speed."
+/datum/disease_ability/symptom/medium/viralevolution
+ symptoms = list(/datum/symptom/viralevolution)
-/datum/disease_ability/symptom/vitiligo
- name = "Skin Paleness"
+/datum/disease_ability/symptom/medium/vitiligo
symptoms = list(/datum/symptom/vitiligo)
- cost = 1
- required_total_points = 8
- short_desc = "Cause victims to become pale."
- long_desc = "Cause victims to become pale. Decreases all stats."
+/datum/disease_ability/symptom/medium/revitiligo
+ symptoms = list(/datum/symptom/revitiligo)
-/datum/disease_ability/symptom/sensory_restoration
- name = "Sensory Restoration"
- symptoms = list(/datum/symptom/sensory_restoration)
- cost = 4
- required_total_points = 8
- short_desc = "Regenerate eye and ear damage of victims."
- long_desc = "Regenerate eye and ear damage of victims."
-
-
-/datum/disease_ability/symptom/itching
- name = "Itching"
+/datum/disease_ability/symptom/medium/itching
symptoms = list(/datum/symptom/itching)
- cost = 4
- required_total_points = 8
short_desc = "Cause victims to itch."
long_desc = "Cause victims to itch, increasing all stats except stealth."
-
-/datum/disease_ability/symptom/weight_loss
- name = "Weight Loss"
+/datum/disease_ability/symptom/medium/heal/weight_loss
symptoms = list(/datum/symptom/weight_loss)
- cost = 4
- required_total_points = 8
short_desc = "Cause victims to lose weight."
long_desc = "Cause victims to lose weight, and make it almost impossible for them to gain nutrition from food. Reduced nutrition allows your infection to spread more easily from hosts, especially by sneezing."
+/datum/disease_ability/symptom/medium/heal/sensory_restoration
+ symptoms = list(/datum/symptom/sensory_restoration)
+ short_desc = "Regenerate eye and ear damage of victims."
+ long_desc = "Regenerate eye and ear damage of victims."
-/datum/disease_ability/symptom/metabolism_heal
- name = "Metabolic Boost"
+/datum/disease_ability/symptom/medium/heal/mind_restoration
+ symptoms = list(/datum/symptom/mind_restoration)
+
+/******POWERFUL******/
+
+/datum/disease_ability/symptom/powerful/fire
+ symptoms = list(/datum/symptom/fire)
+
+/datum/disease_ability/symptom/powerful/flesh_eating
+ symptoms = list(/datum/symptom/flesh_eating)
+
+/*
+/datum/disease_ability/symptom/powerful/genetic_mutation
+ symptoms = list(/datum/symptom/genetic_mutation)
+ cost = 8
+*/
+
+/datum/disease_ability/symptom/powerful/inorganic_adaptation
+ symptoms = list(/datum/symptom/inorganic_adaptation)
+
+/datum/disease_ability/symptom/powerful/narcolepsy
+ symptoms = list(/datum/symptom/narcolepsy)
+
+/datum/disease_ability/symptom/powerful/youth
+ symptoms = list(/datum/symptom/youth)
+ short_desc = "Cause victims to become eternally young."
+ long_desc = "Cause victims to become eternally young. Provides boosts to all stats except transmissibility."
+
+/****HEALING SUBTYPE****/
+
+/datum/disease_ability/symptom/powerful/heal/starlight
+ symptoms = list(/datum/symptom/heal/starlight)
+
+/datum/disease_ability/symptom/powerful/heal/oxygen
+ symptoms = list(/datum/symptom/oxygen)
+
+/datum/disease_ability/symptom/powerful/heal/chem
+ symptoms = list(/datum/symptom/heal/chem)
+
+/datum/disease_ability/symptom/powerful/heal/metabolism
symptoms = list(/datum/symptom/heal/metabolism)
- cost = 4
- required_total_points = 16
short_desc = "Increase the metabolism of victims, causing them to process chemicals and grow hungry faster."
long_desc = "Increase the metabolism of victims, causing them to process chemicals twice as fast and grow hungry more quickly."
+/datum/disease_ability/symptom/powerful/heal/dark
+ symptoms = list(/datum/symptom/heal/darkness)
-/datum/disease_ability/symptom/coma_heal
- name = "Regenerative Coma"
+/datum/disease_ability/symptom/powerful/heal/water
+ symptoms = list(/datum/symptom/heal/water)
+
+/datum/disease_ability/symptom/powerful/heal/plasma
+ symptoms = list(/datum/symptom/heal/plasma)
+
+/datum/disease_ability/symptom/powerful/heal/radiation
+ symptoms = list(/datum/symptom/heal/radiation)
+
+/datum/disease_ability/symptom/powerful/heal/coma
symptoms = list(/datum/symptom/heal/coma)
- cost = 8
- required_total_points = 16
short_desc = "Cause victims to fall into a healing coma when hurt."
long_desc = "Cause victims to fall into a healing coma when hurt."
diff --git a/code/modules/antagonists/disease/disease_datum.dm b/code/modules/antagonists/disease/disease_datum.dm
index eb0feac0a2..1aef9ceba6 100644
--- a/code/modules/antagonists/disease/disease_datum.dm
+++ b/code/modules/antagonists/disease/disease_datum.dm
@@ -10,12 +10,10 @@
var/datum/objective/O = new /datum/objective/disease_infect()
O.owner = owner
objectives += O
- owner.objectives += O
O = new /datum/objective/disease_infect_centcom()
O.owner = owner
objectives += O
- owner.objectives += O
. = ..()
diff --git a/code/modules/antagonists/disease/disease_disease.dm b/code/modules/antagonists/disease/disease_disease.dm
index b4b8ac0956..c37abefab0 100644
--- a/code/modules/antagonists/disease/disease_disease.dm
+++ b/code/modules/antagonists/disease/disease_disease.dm
@@ -51,6 +51,7 @@
if(cures.len)
return
var/list/not_used = advance_cures.Copy()
+ not_used.Cut(1, 6) // Removes the first five tiers of cures.
cures = list(pick(pick_n_take(not_used)), pick(pick_n_take(not_used)))
// Get the cure name from the cure_id
diff --git a/code/modules/antagonists/disease/disease_event.dm b/code/modules/antagonists/disease/disease_event.dm
index 7183ed5455..385cee998b 100644
--- a/code/modules/antagonists/disease/disease_event.dm
+++ b/code/modules/antagonists/disease/disease_event.dm
@@ -18,7 +18,7 @@
var/mob/dead/observer/selected = pick_n_take(candidates)
var/mob/camera/disease/virus = new /mob/camera/disease(SSmapping.get_station_center())
- virus.key = selected.key
+ selected.transfer_ckey(virus, FALSE)
INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name)
message_admins("[ADMIN_LOOKUPFLW(virus)] has been made into a sentient disease by an event.")
log_game("[key_name(virus)] was spawned as a sentient disease by an event.")
diff --git a/code/modules/antagonists/disease/disease_mob.dm b/code/modules/antagonists/disease/disease_mob.dm
index 4d378af724..faea113ac5 100644
--- a/code/modules/antagonists/disease/disease_mob.dm
+++ b/code/modules/antagonists/disease/disease_mob.dm
@@ -18,7 +18,7 @@ the new instance inside the host to be updated to the template's stats.
layer = BELOW_MOB_LAYER
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
sight = SEE_SELF|SEE_THRU
- initial_language_holder = /datum/language_holder/empty
+ initial_language_holder = /datum/language_holder/universal
var/freemove = TRUE
var/freemove_end = 0
@@ -31,7 +31,6 @@ the new instance inside the host to be updated to the template's stats.
var/browser_open = FALSE
var/mob/living/following_host
- var/datum/component/redirect/move_listener
var/list/disease_instances
var/list/hosts //this list is associative, affected_mob -> disease_instance
var/datum/disease/advance/sentient_disease/disease_template
@@ -43,7 +42,7 @@ the new instance inside the host to be updated to the template's stats.
var/move_delay = 1
var/next_adaptation_time = 0
- var/adaptation_cooldown = 1200
+ var/adaptation_cooldown = 600
var/list/purchased_abilities
var/list/unpurchased_abilities
@@ -118,10 +117,28 @@ the new instance inside the host to be updated to the template's stats.
follow_next(Dir & NORTHWEST)
last_move_tick = world.time
+/mob/camera/disease/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
+ . = ..()
+ var/atom/movable/to_follow = speaker
+ if(radio_freq)
+ var/atom/movable/virtualspeaker/V = speaker
+ to_follow = V.source
+ var/link
+ if(to_follow in hosts)
+ link = FOLLOW_LINK(src, to_follow)
+ else
+ link = ""
+ // Recompose the message, because it's scrambled by default
+ message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
+ to_chat(src, "[link] [message]")
+
+
/mob/camera/disease/mind_initialize()
. = ..()
if(!mind.has_antag_datum(/datum/antagonist/disease))
mind.add_antag_datum(/datum/antagonist/disease)
+ var/datum/atom_hud/medsensor = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED]
+ medsensor.add_hud_to(src)
/mob/camera/disease/proc/pick_name()
var/static/list/taken_names
@@ -243,13 +260,10 @@ the new instance inside the host to be updated to the template's stats.
refresh_adaptation_menu()
/mob/camera/disease/proc/set_following(mob/living/L)
+ if(following_host)
+ UnregisterSignal(following_host, COMSIG_MOVABLE_MOVED)
+ RegisterSignal(L, COMSIG_MOVABLE_MOVED, .proc/follow_mob)
following_host = L
- if(!move_listener)
- move_listener = L.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/follow_mob)))
- else
- L.TakeComponent(move_listener)
- if(QDELING(move_listener))
- move_listener = null
follow_mob()
/mob/camera/disease/proc/follow_next(reverse = FALSE)
diff --git a/code/modules/antagonists/ert/ert.dm b/code/modules/antagonists/ert/ert.dm
index bb24af4f7a..5968c7643a 100644
--- a/code/modules/antagonists/ert/ert.dm
+++ b/code/modules/antagonists/ert/ert.dm
@@ -113,7 +113,6 @@
/datum/antagonist/ert/proc/forge_objectives()
if(ert_team)
objectives |= ert_team.objectives
- owner.objectives |= objectives
/datum/antagonist/ert/proc/equipERT()
var/mob/living/carbon/human/H = owner.current
diff --git a/code/modules/antagonists/greentext/greentext.dm b/code/modules/antagonists/greentext/greentext.dm
index ffaab71aca..13a3c2a07a 100644
--- a/code/modules/antagonists/greentext/greentext.dm
+++ b/code/modules/antagonists/greentext/greentext.dm
@@ -8,7 +8,6 @@
O.completed = TRUE //YES!
O.owner = owner
objectives += O
- owner.objectives += objectives
/datum/antagonist/greentext/on_gain()
forge_objectives()
diff --git a/code/modules/antagonists/highlander/highlander.dm b/code/modules/antagonists/highlander/highlander.dm
index 51e8d9a13b..49635356ac 100644
--- a/code/modules/antagonists/highlander/highlander.dm
+++ b/code/modules/antagonists/highlander/highlander.dm
@@ -24,8 +24,6 @@
hijack_objective.owner = owner
objectives += hijack_objective
- owner.objectives |= objectives
-
/datum/antagonist/highlander/on_gain()
forge_objectives()
owner.special_role = "highlander"
diff --git a/code/modules/antagonists/magic_servant/magic_servant.dm b/code/modules/antagonists/magic_servant/magic_servant.dm
new file mode 100644
index 0000000000..31b51f59f6
--- /dev/null
+++ b/code/modules/antagonists/magic_servant/magic_servant.dm
@@ -0,0 +1,9 @@
+/datum/antagonist/magic_servant
+ name = "Magic Servant"
+ show_in_roundend = FALSE
+ show_in_antagpanel = FALSE
+
+/datum/antagonist/magic_servant/proc/setup_master(mob/M)
+ var/datum/objective/O = new("Serve [M.real_name].")
+ O.owner = owner
+ objectives |= O
\ No newline at end of file
diff --git a/code/modules/antagonists/monkey/monkey.dm b/code/modules/antagonists/monkey/monkey.dm
index 9ce28eb60d..e480eb8674 100644
--- a/code/modules/antagonists/monkey/monkey.dm
+++ b/code/modules/antagonists/monkey/monkey.dm
@@ -63,7 +63,6 @@
/datum/antagonist/monkey/proc/forge_objectives()
objectives |= monkey_team.objectives
- owner.objectives |= objectives
/datum/antagonist/monkey/admin_remove(mob/admin)
var/mob/living/carbon/monkey/M = owner.current
diff --git a/code/modules/antagonists/ninja/ninja.dm b/code/modules/antagonists/ninja/ninja.dm
index a8bce90f1c..52e13bdc69 100644
--- a/code/modules/antagonists/ninja/ninja.dm
+++ b/code/modules/antagonists/ninja/ninja.dm
@@ -96,7 +96,6 @@
var/datum/objective/O = new /datum/objective/survive()
O.owner = owner
objectives += O
- owner.objectives |= objectives
/proc/remove_ninja(mob/living/L)
if(!L || !L.mind)
diff --git a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm
index edae8a4240..779dfb43a7 100644
--- a/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm
+++ b/code/modules/antagonists/nukeop/equipment/nuclear_challenge.dm
@@ -1,7 +1,8 @@
#define CHALLENGE_TELECRYSTALS 280
#define PLAYER_SCALING 1.5
#define CHALLENGE_TIME_LIMIT 3000
-#define CHALLENGE_MIN_PLAYERS 50
+#define CHALLENGE_PLAYERS_TARGET 50 //target players population. anything below is a malus to the challenge tc bonus.
+#define TELECRYSTALS_MALUS_SCALING 1 //the higher the value, the bigger the malus.
#define CHALLENGE_SHUTTLE_DELAY 15000 // 25 minutes, so the ops have at least 5 minutes before the shuttle is callable.
GLOBAL_LIST_EMPTY(jam_on_wardec)
@@ -62,12 +63,15 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
for(var/obj/machinery/computer/camera_advanced/shuttle_docker/D in GLOB.jam_on_wardec)
D.jammed = TRUE
-
+
GLOB.war_declared = TRUE
var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
var/actual_players = GLOB.joined_player_list.len - nukeops.len
+ var/tc_malus = 0
+ if(actual_players < CHALLENGE_PLAYERS_TARGET)
+ tc_malus = FLOOR(((CHALLENGE_TELECRYSTALS / CHALLENGE_PLAYERS_TARGET) * (CHALLENGE_PLAYERS_TARGET - actual_players)) * TELECRYSTALS_MALUS_SCALING, 1)
- new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS + CEILING(PLAYER_SCALING * actual_players, 1))
+ new uplink_type(get_turf(user), user.key, CHALLENGE_TELECRYSTALS - tc_malus + CEILING(PLAYER_SCALING * actual_players, 1))
CONFIG_SET(number/shuttle_refuel_delay, max(CONFIG_GET(number/shuttle_refuel_delay), CHALLENGE_SHUTTLE_DELAY))
SSblackbox.record_feedback("amount", "nuclear_challenge_mode", 1)
@@ -79,11 +83,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
to_chat(user, "You are already in the process of declaring war! Make your mind up.")
return FALSE
- var/list/nukeops = get_antag_minds(/datum/antagonist/nukeop)
- var/actual_players = GLOB.joined_player_list.len - nukeops.len
- if(actual_players < CHALLENGE_MIN_PLAYERS)
- to_chat(user, "The enemy crew is too small to be worth declaring war on.")
- return FALSE
if(!user.onSyndieBase())
to_chat(user, "You have to be at your base to use this.")
return FALSE
@@ -102,5 +101,6 @@ GLOBAL_VAR_INIT(war_declared, FALSE)
#undef CHALLENGE_TELECRYSTALS
#undef CHALLENGE_TIME_LIMIT
-#undef CHALLENGE_MIN_PLAYERS
+#undef CHALLENGE_PLAYERS_TARGET
+#undef TELECRYSTALS_MALUS_SCALING
#undef CHALLENGE_SHUTTLE_DELAY
diff --git a/code/modules/antagonists/nukeop/nukeop.dm b/code/modules/antagonists/nukeop/nukeop.dm
index 800448c02f..4604439fc8 100644
--- a/code/modules/antagonists/nukeop/nukeop.dm
+++ b/code/modules/antagonists/nukeop/nukeop.dm
@@ -87,7 +87,7 @@
/datum/antagonist/nukeop/proc/forge_objectives()
if(nuke_team)
- owner.objectives |= nuke_team.objectives
+ objectives |= nuke_team.objectives
/datum/antagonist/nukeop/proc/move_to_spawnpoint()
var/team_number = 1
diff --git a/code/modules/antagonists/official/official.dm b/code/modules/antagonists/official/official.dm
index 26de196cb4..9165a99d42 100644
--- a/code/modules/antagonists/official/official.dm
+++ b/code/modules/antagonists/official/official.dm
@@ -36,8 +36,6 @@
missionobj.completed = 1
mission = missionobj
objectives |= mission
- owner.objectives |= objectives
-
/datum/antagonist/official/on_gain()
forge_objectives()
diff --git a/code/modules/antagonists/overthrow/overthrow.dm b/code/modules/antagonists/overthrow/overthrow.dm
index 2f08824c0b..c8b253793e 100644
--- a/code/modules/antagonists/overthrow/overthrow.dm
+++ b/code/modules/antagonists/overthrow/overthrow.dm
@@ -26,7 +26,6 @@
// Sets objectives, equips all antags with the storage implant.
/datum/antagonist/overthrow/on_gain()
objectives += team.objectives
- owner.objectives += objectives
..()
owner.announce_objectives()
equip_overthrow()
@@ -34,7 +33,6 @@
/datum/antagonist/overthrow/on_removal()
owner.special_role = null
- owner.objectives -= objectives
..()
// Creates the overthrow team, or sets it. The objectives are static for all the team members.
@@ -107,9 +105,9 @@
/datum/antagonist/overthrow/proc/equip_overthrow()
if(!owner || !owner.current || !ishuman(owner.current)) // only equip existing human overthrow members. This excludes the AI, in particular.
return
- var/obj/item/implant/storage/S = locate(/obj/item/implant/storage) in owner.current
+ var/obj/item/implant/storage/S = locate(/obj/item/implant/storage) in owner.current.implants
if(!S)
- S = new(owner.current)
+ S = new
S.implant(owner.current)
var/I = pick(possible_useful_items)
if(ispath(I)) // in case some admin decides to fuck the list up for fun
diff --git a/code/modules/antagonists/overthrow/overthrow_team.dm b/code/modules/antagonists/overthrow/overthrow_team.dm
index 7f5d010013..a22f08d45c 100644
--- a/code/modules/antagonists/overthrow/overthrow_team.dm
+++ b/code/modules/antagonists/overthrow/overthrow_team.dm
@@ -35,7 +35,9 @@
objectives += heads_obj
for(var/i in members)
var/datum/mind/M = i
- M.objectives += heads_obj
+ var/datum/antagonist/overthrow/O = M.has_antag_datum(/datum/antagonist/overthrow)
+ if(O)
+ O.objectives += heads_obj
heads_obj.find_targets()
addtimer(CALLBACK(src,.proc/update_objectives),OBJECTIVE_UPDATING_TIME,TIMER_UNIQUE)
diff --git a/code/modules/antagonists/pirate/pirate.dm b/code/modules/antagonists/pirate/pirate.dm
index 96830562e9..ff33477909 100644
--- a/code/modules/antagonists/pirate/pirate.dm
+++ b/code/modules/antagonists/pirate/pirate.dm
@@ -31,12 +31,7 @@
/datum/antagonist/pirate/on_gain()
if(crew)
- owner.objectives |= crew.objectives
- . = ..()
-
-/datum/antagonist/pirate/on_removal()
- if(crew)
- owner.objectives -= crew.objectives
+ objectives |= crew.objectives
. = ..()
/datum/team/pirate
@@ -53,7 +48,9 @@
getbooty.update_explanation_text()
objectives += getbooty
for(var/datum/mind/M in members)
- M.objectives |= objectives
+ var/datum/antagonist/pirate/P = M.has_antag_datum(/datum/antagonist/pirate)
+ if(P)
+ P.objectives |= objectives
/datum/objective/loot
diff --git a/code/modules/antagonists/revenant/revenant.dm b/code/modules/antagonists/revenant/revenant.dm
index 87794993a7..b43024fb31 100644
--- a/code/modules/antagonists/revenant/revenant.dm
+++ b/code/modules/antagonists/revenant/revenant.dm
@@ -69,7 +69,7 @@
/mob/living/simple_animal/revenant/Initialize(mapload)
. = ..()
AddSpell(new /obj/effect/proc_holder/spell/targeted/night_vision/revenant(null))
- AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
+ AddSpell(new /obj/effect/proc_holder/spell/targeted/telepathy/revenant(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null))
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/blight(null))
@@ -377,14 +377,15 @@
/obj/item/ectoplasm/revenant/proc/reform()
if(QDELETED(src) || QDELETED(revenant) || inert)
return
- var/key_of_revenant
+ var/key_of_revenant = FALSE
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
forceMove(drop_location()) //In case it's in a backpack or someone's hand
revenant.forceMove(loc)
if(old_key)
for(var/mob/M in GLOB.dead_mob_list)
if(M.client && M.client.key == old_key) //Only recreates the mob if the mob the client is in is dead
- key_of_revenant = old_key
+ M.transfer_ckey(revenant.key, FALSE)
+ key_of_revenant = TRUE
break
if(!key_of_revenant)
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
@@ -396,22 +397,21 @@
visible_message("[src] settles down and seems lifeless. ")
return
var/mob/dead/observer/C = pick(candidates)
- key_of_revenant = C.key
- if(!key_of_revenant)
+ C.transfer_ckey(revenant.key, FALSE)
+ if(!revenant.key)
qdel(revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
inert = TRUE
visible_message("[src] settles down and seems lifeless. ")
return
- message_admins("[key_of_revenant] has been [old_key == key_of_revenant ? "re":""]made into a revenant by reforming ectoplasm.")
- log_game("[key_of_revenant] was [old_key == key_of_revenant ? "re":""]made as a revenant by reforming ectoplasm.")
+ message_admins("[key_of_revenant] has been [old_key == revenant.key ? "re":""]made into a revenant by reforming ectoplasm.")
+ log_game("[key_of_revenant] was [old_key == revenant.key ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("[src] suddenly rises into the air before fading away. ")
revenant.essence = essence
revenant.essence_regen_cap = essence
revenant.death_reset()
- revenant.key = key_of_revenant
revenant = null
qdel(src)
diff --git a/code/modules/antagonists/revenant/revenant_abilities.dm b/code/modules/antagonists/revenant/revenant_abilities.dm
index 112a31f44d..17d200a685 100644
--- a/code/modules/antagonists/revenant/revenant_abilities.dm
+++ b/code/modules/antagonists/revenant/revenant_abilities.dm
@@ -27,6 +27,7 @@
if(prob(10))
to_chat(target, "You feel as if you are being watched.")
return
+ face_atom(target)
draining = TRUE
essence_drained += rand(15, 20)
to_chat(src, "You search for the soul of [target]. ")
@@ -65,7 +66,7 @@
if(target.anti_magic_check(FALSE, TRUE))
to_chat(src, "Something's wrong! [target] seems to be resisting the siphoning, leaving you vulnerable! ")
target.visible_message("[target] slumps onto the ground. ", \
- "Violets lights, dancing in your vision, receding-- ")
+ "Violet lights, dancing in your vision, receding-- ")
draining = FALSE
return
var/datum/beam/B = Beam(target,icon_state="drain_life",time=INFINITY)
@@ -104,36 +105,16 @@
action_background_icon_state = "bg_revenant"
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
-/obj/effect/proc_holder/spell/targeted/revenant_transmit
- name = "Transmit"
- desc = "Telepathically transmits a message to the target."
+/obj/effect/proc_holder/spell/targeted/telepathy/revenant
+ name = "Revenant Transmit"
panel = "Revenant Abilities"
- charge_max = 0
- clothes_req = 0
- range = 7
- include_user = 0
action_icon = 'icons/mob/actions/actions_revenant.dmi'
action_icon_state = "r_transmit"
action_background_icon_state = "bg_revenant"
-
-/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
- for(var/mob/living/M in targets)
- var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
- if(!msg)
- charge_counter = charge_max
- return
- log_directed_talk(user, M, msg, LOG_SAY, "revenant whisper")
- to_chat(user, "You transmit to [M]: [msg] ")
- if(!M.anti_magic_check(FALSE, TRUE)) //hear no evil
- to_chat(M, "You hear something behind you talking... [msg] ")
- for(var/ded in GLOB.dead_mob_list)
- if(!isobserver(ded))
- continue
- var/follow_rev = FOLLOW_LINK(ded, user)
- var/follow_whispee = FOLLOW_LINK(ded, M)
- to_chat(ded, "[follow_rev] [user] Revenant Transmit: \"[msg]\" to [follow_whispee] [M] ")
-
-
+ notice = "revennotice"
+ boldnotice = "revenboldnotice"
+ holy_check = TRUE
+ tinfoil_check = FALSE
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
diff --git a/code/modules/antagonists/revenant/revenant_antag.dm b/code/modules/antagonists/revenant/revenant_antag.dm
index 476db96fb8..8d99edf26e 100644
--- a/code/modules/antagonists/revenant/revenant_antag.dm
+++ b/code/modules/antagonists/revenant/revenant_antag.dm
@@ -14,8 +14,6 @@
objective2.owner = owner
objectives += objective2
- owner.objectives |= objectives
-
/datum/antagonist/revenant/on_gain()
forge_objectives()
. = ..()
diff --git a/code/modules/antagonists/revenant/revenant_blight.dm b/code/modules/antagonists/revenant/revenant_blight.dm
index 7037ecae86..235e50008c 100644
--- a/code/modules/antagonists/revenant/revenant_blight.dm
+++ b/code/modules/antagonists/revenant/revenant_blight.dm
@@ -11,9 +11,9 @@
viable_mobtypes = list(/mob/living/carbon/human)
disease_flags = CURABLE
permeability_mod = 1
- severity = DISEASE_SEVERITY_HARMFUL
- var/stagedamage = 0 //Highest stage reached.
- var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
+ severity = DISEASE_SEVERITY_DANGEROUS
+ var/finalstage = FALSE //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
+ var/depression = FALSE
/datum/disease/revblight/cure()
if(affected_mob)
@@ -21,12 +21,13 @@
if(affected_mob.dna && affected_mob.dna.species)
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob)
affected_mob.dna.species.handle_hair(affected_mob)
- to_chat(affected_mob, "You feel better. ")
+ SEND_SIGNAL(affected_mob, COMSIG_CLEAR_MOOD_EVENT, "rev_blight")
..()
/datum/disease/revblight/stage_act()
if(!finalstage)
- if(affected_mob.lying && prob(stage*6))
+ if(affected_mob.lying && prob(stage*4))
+ to_chat(affected_mob, "You feel better. ")
cure()
return
if(prob(stage*3))
@@ -34,10 +35,6 @@
affected_mob.confused += 8
affected_mob.adjustStaminaLoss(8)
new /obj/effect/temp_visual/revenant(affected_mob.loc)
- if(stagedamage < stage)
- stagedamage++
- affected_mob.adjustToxLoss(stage*2) //should, normally, do about 30 toxin damage.
- new /obj/effect/temp_visual/revenant(affected_mob.loc)
if(prob(45))
affected_mob.adjustStaminaLoss(stage)
..() //So we don't increase a stage before applying the stage damage.
@@ -46,9 +43,14 @@
if(prob(5))
affected_mob.emote("pale")
if(3)
+ if(!depression)
+ SEND_SIGNAL(affected_mob, COMSIG_ADD_MOOD_EVENT, "rev_blight", /datum/mood_event/revenant_blight)
+ depression = TRUE
+ SEND_SIGNAL(affected_mob, COMSIG_MODIFY_SANITY, -0.12, SANITY_CRAZY)
if(prob(10))
affected_mob.emote(pick("pale","shiver"))
if(4)
+ SEND_SIGNAL(affected_mob, COMSIG_MODIFY_SANITY, -0.18, SANITY_CRAZY)
if(prob(15))
affected_mob.emote(pick("pale","shiver","cries"))
if(5)
@@ -56,12 +58,18 @@
finalstage = TRUE
to_chat(affected_mob, "You feel like [pick("nothing's worth it anymore", "nobody ever needed your help", "nothing you did mattered", "everything you tried to do was worthless")]. ")
affected_mob.adjustStaminaLoss(45)
- new /obj/effect/temp_visual/revenant(affected_mob.loc)
- if(affected_mob.dna && affected_mob.dna.species)
+ if(affected_mob.dna?.species)
affected_mob.dna.species.handle_mutant_bodyparts(affected_mob,"#1d2953")
affected_mob.dna.species.handle_hair(affected_mob,"#1d2953")
affected_mob.visible_message("[affected_mob] looks terrifyingly gaunt... ", "You suddenly feel like your skin is wrong ... ")
affected_mob.add_atom_colour("#1d2953", TEMPORARY_COLOUR_PRIORITY)
- addtimer(CALLBACK(src, .proc/cure), 100)
- else
- return
+ new /obj/effect/temp_visual/revenant(affected_mob.loc)
+ addtimer(CALLBACK(src, .proc/curses), 150)
+
+/datum/disease/revblight/proc/curses()
+ if(QDELETED(affected_mob))
+ return
+ affected_mob.playsound_local(affected_mob, 'sound/effects/curse5.ogg', 40, 1, -1)
+ to_chat(affected_mob, "You sense the terrific curse of a vengeful ghost befall upon you... ")
+ affected_mob.apply_necropolis_curse(null, 7 MINUTES) //Once the blight has done its course without being cured beforehand, it will cast a necrocurse to compensate how underpowered it's.
+ cure()
diff --git a/code/modules/antagonists/revenant/revenant_spawn_event.dm b/code/modules/antagonists/revenant/revenant_spawn_event.dm
index c9a892cd64..cb534b6613 100644
--- a/code/modules/antagonists/revenant/revenant_spawn_event.dm
+++ b/code/modules/antagonists/revenant/revenant_spawn_event.dm
@@ -52,7 +52,7 @@
return MAP_ERROR
var/mob/living/simple_animal/revenant/revvie = new(pick(spawn_locs))
- revvie.key = selected.key
+ selected.transfer_ckey(revvie, FALSE)
message_admins("[ADMIN_LOOKUPFLW(revvie)] has been made into a revenant by an event.")
log_game("[key_name(revvie)] was spawned as a revenant by an event.")
spawned_mobs += revvie
diff --git a/code/modules/antagonists/revolution/revolution.dm b/code/modules/antagonists/revolution/revolution.dm
index e10d83ffb7..fef7061488 100644
--- a/code/modules/antagonists/revolution/revolution.dm
+++ b/code/modules/antagonists/revolution/revolution.dm
@@ -66,10 +66,10 @@
return rev_team
/datum/antagonist/rev/proc/create_objectives()
- owner.objectives |= rev_team.objectives
+ objectives |= rev_team.objectives
/datum/antagonist/rev/proc/remove_objectives()
- owner.objectives -= rev_team.objectives
+ objectives -= rev_team.objectives
//Bump up to head_rev
/datum/antagonist/rev/proc/promote()
@@ -265,7 +265,8 @@
new_target.update_explanation_text()
objectives += new_target
for(var/datum/mind/M in members)
- M.objectives |= objectives
+ var/datum/antagonist/rev/R = M.has_antag_datum(/datum/antagonist/rev)
+ R.objectives |= objectives
addtimer(CALLBACK(src,.proc/update_objectives),HEAD_UPDATE_PERIOD,TIMER_UNIQUE)
diff --git a/code/modules/antagonists/santa/santa.dm b/code/modules/antagonists/santa/santa.dm
new file mode 100644
index 0000000000..bf42188cf6
--- /dev/null
+++ b/code/modules/antagonists/santa/santa.dm
@@ -0,0 +1,29 @@
+/datum/antagonist/santa
+ name = "Santa"
+ show_in_antagpanel = FALSE
+
+/datum/antagonist/santa/on_gain()
+ . = ..()
+ give_equipment()
+ give_objective()
+
+/datum/antagonist/santa/greet()
+ . = ..()
+ to_chat(owner, "You are Santa! Your objective is to bring joy to the people on this station. You can conjure more presents using a spell, and there are several presents in your bag. ")
+
+/datum/antagonist/santa/proc/give_equipment()
+ var/mob/living/carbon/human/H = owner.current
+ if(istype(H))
+ H.equipOutfit(/datum/outfit/santa)
+
+ owner.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/presents)
+ var/obj/effect/proc_holder/spell/targeted/area_teleport/teleport/telespell = new
+ telespell.clothes_req = 0 //santa robes aren't actually magical.
+ owner.AddSpell(telespell) //does the station have chimneys? WHO KNOWS!
+
+/datum/antagonist/santa/proc/give_objective()
+ var/datum/objective/santa_objective = new()
+ santa_objective.explanation_text = "Bring joy and presents to the station!"
+ santa_objective.completed = 1 //lets cut our santas some slack.
+ santa_objective.owner = owner
+ objectives |= santa_objective
\ No newline at end of file
diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm
index 4f31346136..f45555a6ee 100644
--- a/code/modules/antagonists/slaughter/slaughter.dm
+++ b/code/modules/antagonists/slaughter/slaughter.dm
@@ -34,7 +34,6 @@
melee_damage_upper = 30
see_in_dark = 8
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
- var/boost = 0
bloodcrawl = BLOODCRAWL_EAT
var/playstyle_string = "You are a slaughter demon, a terrible creature from another realm. You have a single desire: To kill. \
You may use the \"Blood Crawl\" ability near blood pools to travel through them, appearing and disappearing from the station at will. \
@@ -54,24 +53,18 @@
if(istype(loc, /obj/effect/dummy/phased_mob/slaughter))
bloodspell.phased = TRUE
-/mob/living/simple_animal/slaughter/Life()
- ..()
- if(boost Target eliminated: [victim.name]")
LAZYINITLIST(targets_stolen)
- for(var/objective_ in victim.objectives)
+ for(var/objective_ in victim.get_all_objectives())
if(istype(objective_, /datum/objective/assassinate/internal))
var/datum/objective/assassinate/internal/objective = objective_
if(objective.target==owner)
@@ -159,7 +158,7 @@
var/status_text = objective.check_completion() ? "neutralised" : "active"
to_chat(owner.current, " New target added to database: [objective.target.name] ([status_text]) ")
last_man_standing = TRUE
- for(var/objective_ in owner.objectives)
+ for(var/objective_ in objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
@@ -175,7 +174,7 @@
/datum/antagonist/traitor/internal_affairs/proc/iaa_process()
if(owner&&owner.current&&owner.current.stat!=DEAD)
- for(var/objective_ in owner.objectives)
+ for(var/objective_ in objectives)
if(!is_internal_objective(objective_))
continue
var/datum/objective/assassinate/internal/objective = objective_
diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm
index e43c2f6254..5dfc08b6cf 100644
--- a/code/modules/antagonists/traitor/datum_traitor.dm
+++ b/code/modules/antagonists/traitor/datum_traitor.dm
@@ -55,12 +55,10 @@
owner.special_role = null
..()
-/datum/antagonist/traitor/proc/add_objective(var/datum/objective/O)
- owner.objectives += O
+/datum/antagonist/traitor/proc/add_objective(datum/objective/O)
objectives += O
-/datum/antagonist/traitor/proc/remove_objective(var/datum/objective/O)
- owner.objectives -= O
+/datum/antagonist/traitor/proc/remove_objective(datum/objective/O)
objectives -= O
/datum/antagonist/traitor/proc/forge_traitor_objectives()
@@ -89,7 +87,7 @@
forge_single_objective()
if(is_hijacker && objective_count <= toa) //Don't assign hijack if it would exceed the number of objectives set in config.traitor_objectives_amount
- if (!(locate(/datum/objective/hijack) in owner.objectives))
+ if (!(locate(/datum/objective/hijack) in objectives))
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = owner
add_objective(hijack_objective)
@@ -97,7 +95,7 @@
var/martyr_compatibility = 1 //You can't succeed in stealing if you're dead.
- for(var/datum/objective/O in owner.objectives)
+ for(var/datum/objective/O in objectives)
if(!O.martyr_compatible)
martyr_compatibility = 0
break
@@ -109,7 +107,7 @@
return
else
- if(!(locate(/datum/objective/escape) in owner.objectives))
+ if(!(locate(/datum/objective/escape) in objectives))
var/datum/objective/escape/escape_objective = new
escape_objective.owner = owner
add_objective(escape_objective)
@@ -159,7 +157,7 @@
kill_objective.find_target()
add_objective(kill_objective)
else
- if(prob(15) && !(locate(/datum/objective/download) in owner.objectives) && !(owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
+ if(prob(15) && !(locate(/datum/objective/download) in objectives) && !(owner.assigned_role in list("Research Director", "Scientist", "Roboticist")))
var/datum/objective/download/download_objective = new
download_objective.owner = owner
download_objective.gen_amount_goal()
diff --git a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
index ff4f7276bc..e1d607c34b 100644
--- a/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
+++ b/code/modules/antagonists/traitor/equipment/Malf_Modules.dm
@@ -304,7 +304,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
sleep(30)
if(!owner || QDELETED(owner))
return
- priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/ai/aimalf.ogg')
+ priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", "aimalf")
set_security_level("delta")
var/obj/machinery/doomsday_device/DOOM = new(owner_AI)
owner_AI.nuking = TRUE
diff --git a/code/modules/antagonists/valentines/heartbreaker.dm b/code/modules/antagonists/valentines/heartbreaker.dm
index 4f228910d7..b78e8d574f 100644
--- a/code/modules/antagonists/valentines/heartbreaker.dm
+++ b/code/modules/antagonists/valentines/heartbreaker.dm
@@ -9,7 +9,6 @@
var/datum/objective/martyr/normiesgetout = new
normiesgetout.owner = owner
objectives += normiesgetout
- owner.objectives += objectives
/datum/antagonist/heartbreaker/on_gain()
forge_objectives()
diff --git a/code/modules/antagonists/valentines/valentine.dm b/code/modules/antagonists/valentines/valentine.dm
index 21e54374a4..19c08f3076 100644
--- a/code/modules/antagonists/valentines/valentine.dm
+++ b/code/modules/antagonists/valentines/valentine.dm
@@ -12,7 +12,6 @@
protect_objective.human_check = FALSE
protect_objective.explanation_text = "Protect [date.name], your date."
objectives += protect_objective
- owner.objectives += objectives
/datum/antagonist/valentine/on_gain()
forge_objectives()
@@ -34,8 +33,8 @@
//Squashed up a bit
/datum/antagonist/valentine/roundend_report()
var/objectives_complete = TRUE
- if(owner.objectives.len)
- for(var/datum/objective/objective in owner.objectives)
+ if(objectives.len)
+ for(var/datum/objective/objective in objectives)
if(!objective.check_completion())
objectives_complete = FALSE
break
@@ -51,8 +50,8 @@
/datum/antagonist/valentine/chem/roundend_report()
var/objectives_complete = TRUE
- if(owner.objectives.len)
- for(var/datum/objective/objective in owner.objectives)
+ if(objectives.len)
+ for(var/datum/objective/objective in objectives)
if(!objective.check_completion())
objectives_complete = FALSE
break
diff --git a/code/modules/antagonists/wishgranter/wishgranter.dm b/code/modules/antagonists/wishgranter/wishgranter.dm
index 318de51eb4..21cab26d1e 100644
--- a/code/modules/antagonists/wishgranter/wishgranter.dm
+++ b/code/modules/antagonists/wishgranter/wishgranter.dm
@@ -8,7 +8,6 @@
var/datum/objective/hijack/hijack = new
hijack.owner = owner
objectives += hijack
- owner.objectives |= objectives
/datum/antagonist/wishgranter/on_gain()
owner.special_role = "Avatar of the Wish Granter"
diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm
index 8642484895..38aa0ad7f5 100644
--- a/code/modules/antagonists/wizard/equipment/artefact.dm
+++ b/code/modules/antagonists/wizard/equipment/artefact.dm
@@ -113,7 +113,7 @@
/obj/singularity/wizard/attack_tk(mob/user)
if(iscarbon(user))
var/mob/living/carbon/C = user
- GET_COMPONENT_FROM(insaneinthemembrane, /datum/component/mood, C)
+ var/datum/component/mood/insaneinthemembrane = C.GetComponent(/datum/component/mood)
if(insaneinthemembrane.sanity < 15)
return //they've already seen it and are about to die, or are just too insane to care
to_chat(C, "OH GOD! NONE OF IT IS REAL! NONE OF IT IS REEEEEEEEEEEEEEEEEEEEEEEEAL! ")
@@ -198,7 +198,7 @@
to_chat(user, "This artifact can only affect three undead at a time! ")
return
- M.set_species(/datum/species/skeleton, icon_update=0)
+ M.set_species(/datum/species/skeleton/space, icon_update=0)
M.revive(full_heal = 1, admin_revive = 1)
spooky_scaries |= M
to_chat(M, "You have been revived by [user.real_name]! ")
@@ -255,7 +255,7 @@
/obj/item/voodoo/attackby(obj/item/I, mob/user, params)
if(target && cooldown < world.time)
- if(I.is_hot())
+ if(I.get_temperature())
to_chat(target, "You suddenly feel very hot ")
target.adjust_bodytemperature(50)
GiveHint(target)
@@ -324,14 +324,11 @@
cooldown = world.time + cooldown_time
/obj/item/voodoo/proc/update_targets()
- possible = list()
+ LAZYINITLIST(possible)
if(!voodoo_link)
return
- var/list/prints = voodoo_link.return_fingerprints()
- if(!length(prints))
- return FALSE
for(var/mob/living/carbon/human/H in GLOB.alive_mob_list)
- if(prints[md5(H.dna.uni_identity)])
+ if(md5(H.dna.uni_identity) in voodoo_link.fingerprints)
possible |= H
/obj/item/voodoo/proc/GiveHint(mob/victim,force=0)
diff --git a/code/modules/antagonists/wizard/equipment/soulstone.dm b/code/modules/antagonists/wizard/equipment/soulstone.dm
index 40551ae2fc..6f4c3fca10 100644
--- a/code/modules/antagonists/wizard/equipment/soulstone.dm
+++ b/code/modules/antagonists/wizard/equipment/soulstone.dm
@@ -218,7 +218,7 @@
newstruct.master = stoner
var/datum/action/innate/seek_master/SM = new()
SM.Grant(newstruct)
- newstruct.key = target.key
+ target.transfer_ckey(newstruct)
var/obj/screen/alert/bloodsense/BS
if(newstruct.mind && ((stoner && iscultist(stoner)) || cultoverride) && SSticker && SSticker.mode)
SSticker.mode.add_cultist(newstruct.mind, 0)
@@ -238,12 +238,13 @@
T.stop_sound_channel(CHANNEL_HEARTBEAT)
T.invisibility = INVISIBILITY_ABSTRACT
T.dust_animation()
+ QDEL_IN(T, 5)
var/mob/living/simple_animal/shade/S = new /mob/living/simple_animal/shade(src)
S.status_flags |= GODMODE //So they won't die inside the stone somehow
S.canmove = FALSE//Can't move out of the soul stone
S.name = "Shade of [T.real_name]"
S.real_name = "Shade of [T.real_name]"
- S.key = T.key
+ T.transfer_ckey(S)
S.language_holder = U.language_holder.copy(S)
if(U)
S.faction |= "[REF(U)]" //Add the master as a faction, allowing inter-mob cooperation
diff --git a/code/modules/antagonists/wizard/wizard.dm b/code/modules/antagonists/wizard/wizard.dm
index e6cae518b6..89324f0691 100644
--- a/code/modules/antagonists/wizard/wizard.dm
+++ b/code/modules/antagonists/wizard/wizard.dm
@@ -57,19 +57,19 @@
if(!GLOB.wizardstart.len)
SSjob.SendToLateJoin(owner.current)
to_chat(owner, "HOT INSERTION, GO GO GO")
- owner.current.forceMove(pick(GLOB.wizardstart))
+ else
+ owner.current.forceMove(pick(GLOB.wizardstart))
/datum/antagonist/wizard/proc/create_objectives()
var/datum/objective/new_objective = new("Cause as much creative mayhem as you can aboard the station! The more outlandish your methods of achieving this, the better! Make sure there's a decent amount of crew alive to tell of your tale.")
+ new_objective.completed = TRUE //So they can greentext without admin intervention.
new_objective.owner = owner
objectives += new_objective
- var/datum/objective/escape/escape_objective = new
- escape_objective.owner = owner
- objectives += escape_objective
-
- for(var/datum/objective/O in objectives)
- owner.objectives += O
+ if (!(locate(/datum/objective/escape) in objectives))
+ var/datum/objective/escape/escape_objective = new
+ escape_objective.owner = owner
+ objectives += escape_objective
/datum/antagonist/wizard/on_removal()
unregister()
@@ -183,7 +183,6 @@
new_objective.owner = owner
new_objective.target = master
new_objective.explanation_text = "Protect [master.current.real_name], the wizard."
- owner.objectives += new_objective
objectives += new_objective
//Random event wizard
@@ -245,13 +244,12 @@
if(!istype(M))
return
- var/obj/item/implant/exile/Implant = new/obj/item/implant/exile(M)
+ var/obj/item/implant/exile/Implant = new
Implant.implant(M)
/datum/antagonist/wizard/academy/create_objectives()
var/datum/objective/new_objective = new("Protect Wizard Academy from the intruders")
new_objective.owner = owner
- owner.objectives += new_objective
objectives += new_objective
//Solo wizard report
diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm
index 186eb1b024..6b87278e00 100644
--- a/code/modules/assembly/flash.dm
+++ b/code/modules/assembly/flash.dm
@@ -201,8 +201,10 @@
/obj/item/assembly/flash/cyborg
/obj/item/assembly/flash/cyborg/attack(mob/living/M, mob/user)
- ..()
+ . = ..()
new /obj/effect/temp_visual/borgflash(get_turf(src))
+ if(. && !CONFIG_GET(flag/disable_borg_flash_knockdown) && iscarbon(M) && !M.resting && !M.get_eye_protection())
+ M.Knockdown(80)
/obj/item/assembly/flash/cyborg/attack_self(mob/user)
..()
diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm
index 07f31a6678..7405549b3d 100644
--- a/code/modules/assembly/infrared.dm
+++ b/code/modules/assembly/infrared.dm
@@ -10,7 +10,7 @@
var/maxlength = 8
var/list/obj/effect/beam/i_beam/beams
var/olddir = 0
- var/datum/component/redirect/listener
+ var/turf/listeningTo
var/hearing_range = 3
/obj/item/assembly/infra/Initialize()
@@ -33,7 +33,7 @@
/obj/item/assembly/infra/Destroy()
STOP_PROCESSING(SSobj, src)
- QDEL_NULL(listener)
+ listeningTo = null
QDEL_LIST(beams)
. = ..()
@@ -163,8 +163,12 @@
next_activate = world.time + 30
/obj/item/assembly/infra/proc/switchListener(turf/newloc)
- QDEL_NULL(listener)
- listener = newloc.AddComponent(/datum/component/redirect, list(COMSIG_ATOM_EXITED = CALLBACK(src, .proc/check_exit)))
+ if(listeningTo == newloc)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_ATOM_EXITED)
+ RegisterSignal(newloc, COMSIG_ATOM_EXITED, .proc/check_exit)
+ listeningTo = newloc
/obj/item/assembly/infra/proc/check_exit(datum/source, atom/movable/offender)
if(QDELETED(src))
diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm
index 8e320b2f3e..f9c831a65a 100644
--- a/code/modules/atmospherics/gasmixtures/reactions.dm
+++ b/code/modules/atmospherics/gasmixtures/reactions.dm
@@ -210,9 +210,9 @@
return cached_results["fire"] ? REACTING : NO_REACTION
-//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again)
+//fusion: a terrible idea that was fun but broken. Now reworked to be less broken and more interesting. Again (and again, and again). Again!
//Fusion Rework Counter: Please increment this if you make a major overhaul to this system again.
-//5 reworks
+//6 reworks
/datum/gas_reaction/fusion
exclude = FALSE
@@ -220,100 +220,79 @@
name = "Plasmic Fusion"
id = "fusion"
-//Since fusion isn't really intended to happen in successive chains, the requirements are very high
/datum/gas_reaction/fusion/init_reqs()
min_requirements = list(
"TEMP" = FUSION_TEMPERATURE_THRESHOLD,
- "ENER" = FUSION_ENERGY_THRESHOLD,
+ /datum/gas/tritium = FUSION_TRITIUM_MOLES_USED,
/datum/gas/plasma = FUSION_MOLE_THRESHOLD,
- /datum/gas/tritium = FUSION_MOLE_THRESHOLD
- )
+ /datum/gas/carbon_dioxide = FUSION_MOLE_THRESHOLD)
/datum/gas_reaction/fusion/react(datum/gas_mixture/air, datum/holder)
var/list/cached_gases = air.gases
- var/temperature = air.temperature
- if(!air.analyzer_results)
- air.analyzer_results = new
- var/list/cached_scan_results = air.analyzer_results
var/turf/open/location
if (istype(holder,/datum/pipeline)) //Find the tile the reaction is occuring on, or a random part of the network if it's a pipenet.
var/datum/pipeline/fusion_pipenet = holder
location = get_turf(pick(fusion_pipenet.members))
else
location = get_turf(holder)
-
+ if(!air.analyzer_results)
+ air.analyzer_results = new
+ var/list/cached_scan_results = air.analyzer_results
var/old_heat_capacity = air.heat_capacity()
- var/reaction_energy = 0
-
- var/mediation = FUSION_MEDIATION_FACTOR*(air.heat_capacity()-(cached_gases[/datum/gas/plasma]*GLOB.meta_gas_specific_heats[/datum/gas/plasma]))/(air.total_moles()-cached_gases[/datum/gas/plasma]) //This is the average specific heat of the mixture,not including plasma.
-
- var/gases_fused = air.total_moles() - cached_gases[/datum/gas/plasma]
- var/plasma_differential = (cached_gases[/datum/gas/plasma] - gases_fused) / air.total_moles()
- var/reaction_efficiency = FUSION_EFFICIENCY_BASE ** -((plasma_differential ** 2) / FUSION_EFFICIENCY_DIVISOR) //https://www.desmos.com/calculator/6jjx3vdrvx
-
+ var/reaction_energy = 0 //Reaction energy can be negative or positive, for both exothermic and endothermic reactions.
+ var/initial_plasma = cached_gases[/datum/gas/plasma]
+ var/initial_carbon = cached_gases[/datum/gas/carbon_dioxide]
+ var/scale_factor = (air.volume)/(PI) //We scale it down by volume/Pi because for fusion conditions, moles roughly = 2*volume, but we want it to be based off something constant between reactions.
+ var/toroidal_size = (2*PI)+TORADIANS(arctan((air.volume-TOROID_VOLUME_BREAKEVEN)/TOROID_VOLUME_BREAKEVEN)) //The size of the phase space hypertorus
var/gas_power = 0
+ var/list/gas_fusion_powers = GLOB.meta_gas_fusions
for (var/gas_id in cached_gases)
- gas_power += reaction_efficiency * (GLOB.meta_gas_fusions[gas_id]*cached_gases[gas_id])
+ gas_power += (gas_fusion_powers[gas_id]*cached_gases[gas_id])
+ var/instability = MODULUS((gas_power*INSTABILITY_GAS_POWER_FACTOR)**2,toroidal_size) //Instability effects how chaotic the behavior of the reaction is
+ cached_scan_results[id] = instability//used for analyzer feedback
- var/power_ratio = gas_power/mediation
- cached_scan_results[id] = power_ratio //used for analyzer feedback
+ var/plasma = (initial_plasma-FUSION_MOLE_THRESHOLD)/(scale_factor) //We have to scale the amounts of carbon and plasma down a significant amount in order to show the chaotic dynamics we want
+ var/carbon = (initial_carbon-FUSION_MOLE_THRESHOLD)/(scale_factor) //We also subtract out the threshold amount to make it harder for fusion to burn itself out.
- for (var/gas_id in cached_gases) //and now we fuse
- cached_gases[gas_id] = 0
+ //The reaction is a specific form of the Kicked Rotator system, which displays chaotic behavior and can be used to model particle interactions.
+ plasma = MODULUS(plasma - (instability*sin(TODEGREES(carbon))), toroidal_size)
+ carbon = MODULUS(carbon - plasma, toroidal_size)
- var/radiation_power = (FUSION_RADIATION_FACTOR * power_ratio) / (power_ratio + FUSION_RADIATION_CONSTANT) //https://www.desmos.com/calculator/4i1f296phl
- var/zap_power = ((FUSION_ZAP_POWER_ASYMPTOTE * power_ratio) / (power_ratio + FUSION_ZAP_POWER_CONSTANT)) + FUSION_ZAP_POWER_BASE //https://www.desmos.com/calculator/n0zkdpxnrr
- var/do_explosion = FALSE
- var/zap_range //these ones are set later
- var/fusion_prepare_to_die_edition_rng
- if (power_ratio > FUSION_SUPER_TIER_THRESHOLD) //power ratio 50+: SUPER TIER. The gases become so energized that they fuse into a ton of tritium, which is pretty nice! Until you consider the fact that everything just exploded, the canister is probably going to break and you're irradiated.
- reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_SUPER * (power_ratio / FUSION_ENERGY_DIVISOR_SUPER)
- cached_gases[/datum/gas/tritium] += gases_fused * FUSION_GAS_CREATION_FACTOR_TRITIUM //60% of the gas is converted to energy, 40% to trit
- fusion_prepare_to_die_edition_rng = 100 //Wait a minute..
- do_explosion = TRUE
- zap_range = FUSION_ZAP_RANGE_SUPER
+ cached_gases[/datum/gas/plasma] = plasma*scale_factor + FUSION_MOLE_THRESHOLD //Scales the gases back up
+ cached_gases[/datum/gas/carbon_dioxide] = carbon*scale_factor + FUSION_MOLE_THRESHOLD
+ var/delta_plasma = initial_plasma - cached_gases[/datum/gas/plasma]
- else if (power_ratio > FUSION_HIGH_TIER_THRESHOLD) //power ratio 20-50; High tier. The reaction is so energized that it fuses into a small amount of stimulum, and some pluoxium. Very dangerous, but super cool and super useful.
- reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_HIGH * (power_ratio / FUSION_ENERGY_DIVISOR_HIGH)
- cached_gases[/datum/gas/stimulum] += gases_fused * FUSION_GAS_CREATION_FACTOR_STIM //40% of the gas is converted to energy, 60% to stim and pluox
- cached_gases[/datum/gas/pluoxium] += gases_fused * FUSION_GAS_CREATION_FACTOR_PLUOX
- fusion_prepare_to_die_edition_rng = power_ratio //Now we're getting into dangerous territory
- do_explosion = TRUE
- zap_range = FUSION_ZAP_RANGE_HIGH
-
- else if (power_ratio > FUSION_MID_TIER_THRESHOLD) //power_ratio 5 to 20; Mediation is overpowered, fusion reaction starts to break down.
- reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_MID * (power_ratio / FUSION_ENERGY_DIVISOR_MID)
- cached_gases[/datum/gas/nitryl] += gases_fused * FUSION_GAS_CREATION_FACTOR_NITRYL //20% of the gas is converted to energy, 80% to nitryl and N2O
- cached_gases[/datum/gas/nitrous_oxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_N2O
- fusion_prepare_to_die_edition_rng = power_ratio * FUSION_MID_TIER_RAD_PROB_FACTOR //Still unlikely, but don't stand next to the reaction unprotected
- zap_range = FUSION_ZAP_RANGE_MID
-
- else //power ratio 0 to 5; Gas power is overpowered. Fusion isn't nearly as powerful.
- reaction_energy += gases_fused * FUSION_RELEASE_ENERGY_LOW * (power_ratio / FUSION_ENERGY_DIVISOR_LOW)
- cached_gases[/datum/gas/bz] += gases_fused * FUSION_GAS_CREATION_FACTOR_BZ //10% of the gas is converted to energy, 90% to BZ and CO2
- cached_gases[/datum/gas/carbon_dioxide] += gases_fused * FUSION_GAS_CREATION_FACTOR_CO2
- fusion_prepare_to_die_edition_rng = power_ratio * FUSION_LOW_TIER_RAD_PROB_FACTOR //Low, but still something to look out for
- zap_range = FUSION_ZAP_RANGE_LOW
-
- //All the deadly consequences of fusion, consolidated for your viewing pleasure
- if (location)
- if(prob(fusion_prepare_to_die_edition_rng)) //Some.. permanent effects
- if(do_explosion)
- explosion(location, 0, 0, 5, power_ratio, TRUE, TRUE) //large shockwave, the actual radius is quite small - people will recognize that you're doing fusion
- radiation_pulse(location, radiation_power) //You mean causing a super-tier fusion reaction in the halls is a bad idea?
- SSresearch.science_tech.add_point_type(TECHWEB_POINT_TYPE_DEFAULT, 30000)//The science is cool though.
- playsound(location, 'sound/effects/supermatter.ogg', 100, 0)
- else
- playsound(location, 'sound/effects/phasein.ogg', 75, 0)
- //These will always happen, so be prepared
- tesla_zap(location, zap_range, zap_power, TESLA_FUSION_FLAGS) //larpers beware
- location.fire_nuclear_particles(power_ratio) //see code/modules/projectile/energy/nuclear_particle.dm
+ reaction_energy += delta_plasma*PLASMA_BINDING_ENERGY //Energy is gained or lost corresponding to the creation or destruction of mass.
+ if(instability < FUSION_INSTABILITY_ENDOTHERMALITY)
+ reaction_energy = max(reaction_energy,0) //Stable reactions don't end up endothermic.
+ else if (reaction_energy < 0)
+ reaction_energy *= (instability-FUSION_INSTABILITY_ENDOTHERMALITY)**0.5
+ if(air.thermal_energy() + reaction_energy < 0) //No using energy that doesn't exist.
+ cached_gases[/datum/gas/plasma] = initial_plasma
+ cached_gases[/datum/gas/carbon_dioxide] = initial_carbon
+ return NO_REACTION
+ cached_gases[/datum/gas/tritium] -= FUSION_TRITIUM_MOLES_USED
+ //The decay of the tritium and the reaction's energy produces waste gases, different ones depending on whether the reaction is endo or exothermic
if(reaction_energy > 0)
+ cached_gases[/datum/gas/oxygen] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
+ cached_gases[/datum/gas/nitrous_oxide] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*FUSION_TRITIUM_CONVERSION_COEFFICIENT)
+ else
+ cached_gases[/datum/gas/bz] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
+ cached_gases[/datum/gas/nitryl] += FUSION_TRITIUM_MOLES_USED*(reaction_energy*-FUSION_TRITIUM_CONVERSION_COEFFICIENT)
+
+ if(reaction_energy)
+ if(location)
+ var/particle_chance = ((PARTICLE_CHANCE_CONSTANT)/(reaction_energy-PARTICLE_CHANCE_CONSTANT)) + 1//Asymptopically approaches 100% as the energy of the reaction goes up.
+ if(prob(PERCENT(particle_chance)))
+ location.fire_nuclear_particle()
+ var/rad_power = max((FUSION_RAD_COEFFICIENT/instability) + FUSION_RAD_MAX,0)
+ radiation_pulse(location,rad_power)
+
var/new_heat_capacity = air.heat_capacity()
if(new_heat_capacity > MINIMUM_HEAT_CAPACITY)
- air.temperature = max(((temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB)
+ air.temperature = CLAMP(((air.temperature*old_heat_capacity + reaction_energy)/new_heat_capacity),TCMB,INFINITY)
return REACTING
/datum/gas_reaction/nitrylformation //The formation of nitryl. Endothermic. Requires N2O as a catalyst.
diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
index 35b30107d8..ccd13d8d4a 100644
--- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
+++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm
@@ -394,6 +394,21 @@
. = TRUE
update_icon()
+/obj/machinery/atmospherics/components/unary/cryo_cell/CtrlClick(mob/user)
+ if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK) && !state_open)
+ on = !on
+ update_icon()
+ return ..()
+
+/obj/machinery/atmospherics/components/unary/cryo_cell/AltClick(mob/user)
+ if(user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
+ if(state_open)
+ close_machine()
+ else
+ open_machine()
+ update_icon()
+ return ..()
+
/obj/machinery/atmospherics/components/unary/cryo_cell/update_remote_sight(mob/living/user)
return // we don't see the pipe network while inside cryo.
diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm
index 74f81ec9a0..a0927a2578 100644
--- a/code/modules/awaymissions/corpse.dm
+++ b/code/modules/awaymissions/corpse.dm
@@ -17,6 +17,7 @@
var/faction = null
var/permanent = FALSE //If true, the spawner will not disappear upon running out of uses.
var/random = FALSE //Don't set a name or gender, just go random
+ var/antagonist_type
var/objectives = null
var/uses = 1 //how many times can we spawn from it. set to -1 for infinite.
var/brute_damage = 0
@@ -111,9 +112,16 @@
if(show_flavour)
to_chat(M, "[flavour_text]")
var/datum/mind/MM = M.mind
+ var/datum/antagonist/A
+ if(antagonist_type)
+ A = MM.add_antag_datum(antagonist_type)
if(objectives)
+ if(!A)
+ A = MM.add_antag_datum(/datum/antagonist/custom)
for(var/objective in objectives)
- MM.objectives += new/datum/objective(objective)
+ var/datum/objective/O = new/datum/objective(objective)
+ O.owner = MM
+ A.objectives += O
if(assignedrole)
M.mind.assigned_role = assignedrole
special(M, name)
@@ -587,3 +595,57 @@
shoes = /obj/item/clothing/shoes/sneakers/black
suit = /obj/item/clothing/suit/armor/vest
glasses = /obj/item/clothing/glasses/sunglasses/reagent
+
+/obj/effect/mob_spawn/human/lavaknight
+ name = "odd cryogenics pod"
+ desc = "A humming cryo pod. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant."
+ mob_name = "a displaced knight from another dimension"
+ icon = 'icons/obj/machines/sleeper.dmi'
+ icon_state = "sleeper"
+ roundstart = FALSE
+ id_job = "Knight"
+ job_description = "Cydonian Knight"
+ death = FALSE
+ random = TRUE
+ outfit = /datum/outfit/lavaknight
+ mob_species = /datum/species/human
+ flavour_text = "Y ou are a knight who conveniently has some form of retrograde amnesia. \
+ You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \
+ Remember: hostile creatures and such are fair game for attacking, but under no circumstances are you to attack anything capable of thought and/or speech unless it has made it its life's calling to chase you to the ends of the earth."
+ assignedrole = "Cydonian Knight"
+
+/obj/effect/mob_spawn/human/lavaknight/special(mob/living/new_spawn)
+ if(ishuman(new_spawn))
+ var/mob/living/carbon/human/H = new_spawn
+ H.dna.features["mam_ears"] = "Cat, Big" //cat people
+ H.dna.features["mcolor"] = H.hair_color
+ H.update_body()
+
+/obj/effect/mob_spawn/human/lavaknight/Destroy()
+ new/obj/structure/showcase/machinery/oldpod/used(drop_location())
+ return ..()
+
+/datum/outfit/lavaknight
+ name = "Cydonian Knight"
+ uniform = /obj/item/clothing/under/assistantformal
+ mask = /obj/item/clothing/mask/breath
+ shoes = /obj/item/clothing/shoes/sneakers/black
+ r_pocket = /obj/item/melee/transforming/energy/sword/cx
+ suit = /obj/item/clothing/suit/space/hardsuit/lavaknight
+ suit_store = /obj/item/tank/internals/oxygen
+ id = /obj/item/card/id/knight/blue
+
+/obj/effect/mob_spawn/human/lavaknight/captain
+ name = "odd gilded cryogenics pod"
+ desc = "A humming cryo pod that appears to be gilded. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant."
+ flavour_text = "Y ou are a knight who conveniently has some form of retrograde amnesia. \
+ You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \
+ Remember: hostile creatures and such are fair game for attacking, but under no circumstances are you to attack anything capable of thought and/or speech unless it has made it its life's calling to chase you to the ends of the earth. \
+ You feel a natural instict to lead, and as such, you should strive to lead your comrades to safety, and hopefully home. You also feel a burning determination to uphold your vow, as well as your fellow comrade's."
+ outfit = /datum/outfit/lavaknight/captain
+ id_job = "Knight Captain"
+
+/datum/outfit/lavaknight/captain
+ name ="Cydonian Knight Captain"
+ l_pocket = /obj/item/twohanded/dualsaber/hypereutactic
+ id = /obj/item/card/id/knight/captain
diff --git a/code/modules/awaymissions/mission_code/Academy.dm b/code/modules/awaymissions/mission_code/Academy.dm
index 57d8420fa8..77cdf8441b 100644
--- a/code/modules/awaymissions/mission_code/Academy.dm
+++ b/code/modules/awaymissions/mission_code/Academy.dm
@@ -133,7 +133,7 @@
var/mob/dead/observer/C = pick(candidates)
message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Wizard Academy Defender")
current_wizard.ghostize() // on the off chance braindead defender gets back in
- current_wizard.key = C.key
+ C.transfer_ckey(current_wizard, FALSE)
/obj/structure/academy_wizard_spawner/proc/summon_wizard()
var/turf/T = src.loc
@@ -210,8 +210,6 @@
if(4)
//Destroy Equipment
for (var/obj/item/I in user)
- if (istype(I, /obj/item/implant))
- continue
qdel(I)
if(5)
//Monkeying
@@ -266,15 +264,16 @@
var/mob/living/carbon/human/H = new(drop_location())
H.equipOutfit(/datum/outfit/butler)
var/datum/mind/servant_mind = new /datum/mind()
- var/datum/objective/O = new("Serve [user.real_name].")
- servant_mind.objectives += O
+ var/datum/antagonist/magic_servant/A = new
+ servant_mind.add_antag_datum(A)
+ A.setup_master(user)
servant_mind.transfer_to(H)
var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as [user.real_name] Servant?", ROLE_WIZARD, null, ROLE_WIZARD, 50, H)
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
message_admins("[ADMIN_LOOKUPFLW(C)] was spawned as Dice Servant")
- H.key = C.key
+ C.transfer_ckey(H, FALSE)
var/obj/effect/proc_holder/spell/targeted/summonmob/S = new
S.target_mob = H
diff --git a/code/modules/cargo/bounties/assistant.dm b/code/modules/cargo/bounties/assistant.dm
index cf4efaa8c6..4edcb04e8f 100644
--- a/code/modules/cargo/bounties/assistant.dm
+++ b/code/modules/cargo/bounties/assistant.dm
@@ -1,46 +1,46 @@
/datum/bounty/item/assistant/strange_object
name = "Strange Object"
description = "Nanotrasen has taken an interest in strange objects. Find one in maint, and ship it off to CentCom right away."
- reward = 1200
+ reward = 600
wanted_types = list(/obj/item/relic)
/datum/bounty/item/assistant/scooter
name = "Scooter"
description = "Nanotrasen has determined walking to be wasteful. Ship a scooter to CentCom to speed operations up."
- reward = 1080 // the mat hoffman
+ reward = 850 // the mat hoffman
wanted_types = list(/obj/vehicle/ridden/scooter)
include_subtypes = FALSE
/datum/bounty/item/assistant/skateboard
name = "Skateboard"
description = "Nanotrasen has determined walking to be wasteful. Ship a skateboard to CentCom to speed operations up."
- reward = 900 // the tony hawk
+ reward = 700 // the tony hawk
wanted_types = list(/obj/vehicle/ridden/scooter/skateboard)
/datum/bounty/item/assistant/stunprod
name = "Stunprod"
description = "CentCom demands a stunprod to use against dissidents. Craft one, then ship it."
- reward = 1300
+ reward = 800
wanted_types = list(/obj/item/melee/baton/cattleprod)
/datum/bounty/item/assistant/soap
name = "Soap"
description = "Soap has gone missing from CentCom's bathrooms and nobody knows who took it. Replace it and be the hero CentCom needs."
- reward = 2000
+ reward = 1000
required_count = 3
wanted_types = list(/obj/item/soap)
/datum/bounty/item/assistant/spear
name = "Spears"
description = "CentCom's security forces are going through budget cuts. You will be paid if you ship a set of spears."
- reward = 2000
+ reward = 1000
required_count = 5
wanted_types = list(/obj/item/twohanded/spear)
/datum/bounty/item/assistant/toolbox
name = "Toolboxes"
description = "There's an absence of robustness at Central Command. Hurry up and ship some toolboxes as a solution."
- reward = 2000
+ reward = 1000
required_count = 6
wanted_types = list(/obj/item/storage/toolbox)
@@ -53,81 +53,81 @@
/datum/bounty/item/assistant/clown_box
name = "Clown Box"
description = "The universe needs laughter. Stamp cardboard with a clown stamp and ship it out."
- reward = 1500
+ reward = 750
wanted_types = list(/obj/item/storage/box/clown)
/datum/bounty/item/assistant/cheesiehonkers
name = "Cheesie Honkers"
description = "Apparently the company that makes Cheesie Honkers is going out of business soon. CentCom wants to stock up before it happens!"
- reward = 1200
+ reward = 1000
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/cheesiehonkers)
/datum/bounty/item/assistant/baseball_bat
name = "Baseball Bat"
description = "Baseball fever is going on at CentCom! Be a dear and ship them some baseball bats, so that management can live out their childhood dream."
- reward = 2000
+ reward = 1000
required_count = 5
wanted_types = list(/obj/item/melee/baseball_bat)
/datum/bounty/item/assistant/extendohand
name = "Extendo-Hand"
description = "Commander Betsy is getting old, and can't bend over to get the telescreen remote anymore. Management has requested an extendo-hand to help her out."
- reward = 2500
+ reward = 1250
wanted_types = list(/obj/item/extendohand)
/datum/bounty/item/assistant/donut
name = "Donuts"
description = "CentCom's security forces are facing heavy losses against the Syndicate. Ship donuts to raise morale."
- reward = 3000
+ reward = 2000
required_count = 10
wanted_types = list(/obj/item/reagent_containers/food/snacks/donut)
/datum/bounty/item/assistant/donkpocket
name = "Donk-Pockets"
description = "Consumer safety recall: Warning. Donk-Pockets manufactured in the past year contain hazardous lizard biomatter. Return units to CentCom immediately."
- reward = 3000
+ reward = 1000
required_count = 10
wanted_types = list(/obj/item/reagent_containers/food/snacks/donkpocket)
/datum/bounty/item/assistant/briefcase
name = "Briefcase"
description = "Central Command will be holding a business convention this year. Ship a few briefcases in support."
- reward = 2500
+ reward = 1500
required_count = 5
wanted_types = list(/obj/item/storage/briefcase, /obj/item/storage/secure/briefcase)
/datum/bounty/item/assistant/sunglasses
name = "Sunglasses"
description = "A famous blues duo is passing through the sector, but they've lost their shades and they can't perform. Ship new sunglasses to CentCom to rectify this."
- reward = 3000
+ reward = 1000
required_count = 2
wanted_types = list(/obj/item/clothing/glasses/sunglasses)
/datum/bounty/item/assistant/monkey_hide
name = "Monkey Hide"
description = "One of the scientists at CentCom is interested in testing products on monkey skin. Your mission is to acquire monkey's hide and ship it."
- reward = 1500
+ reward = 500
wanted_types = list(/obj/item/stack/sheet/animalhide/monkey)
/datum/bounty/item/assistant/shard
name = "Shards"
description = "A killer clown has been stalking CentCom, and staff have been unable to catch her because she's not wearing shoes. Please ship some shards so that a booby trap can be constructed."
- reward = 1500
+ reward = 500
required_count = 15
wanted_types = list(/obj/item/shard)
/datum/bounty/item/assistant/comfy_chair
name = "Comfy Chairs"
description = "Commander Pat is unhappy with his chair. He claims it hurts his back. Ship some alternatives out to humor him."
- reward = 1500
+ reward = 900
required_count = 5
wanted_types = list(/obj/structure/chair/comfy)
/datum/bounty/item/assistant/geranium
name = "Geraniums"
description = "Commander Zot has the hots for Commander Zena. Send a shipment of geraniums - her favorite flower - and he'll happily reward you."
- reward = 4000
+ reward = 1000
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/poppy/geranium)
@@ -142,7 +142,7 @@
/datum/bounty/item/assistant/shadyjims
name = "Shady Jim's"
description = "There's an irate officer at CentCom demanding that he receive a box of Shady Jim's cigarettes. Please ship one. He's starting to make threats."
- reward = 500
+ reward = 750
wanted_types = list(/obj/item/storage/fancy/cigarettes/cigpack_shadyjims)
/datum/bounty/item/assistant/potted_plants
diff --git a/code/modules/cargo/bounties/botany.dm b/code/modules/cargo/bounties/botany.dm
index 34906b321a..754de480cd 100644
--- a/code/modules/cargo/bounties/botany.dm
+++ b/code/modules/cargo/bounties/botany.dm
@@ -1,5 +1,5 @@
/datum/bounty/item/botany
- reward = 5000
+ reward = 1200
var/datum/bounty/item/botany/multiplier = 0 //adds bonus reward money; increased for higher tier or rare mutations
var/datum/bounty/item/botany/bonus_desc //for adding extra flavor text to bounty descriptions
var/datum/bounty/item/botany/foodtype = "meal" //same here
@@ -64,7 +64,7 @@
multiplier = 4 //hush money
bonus_desc = "Do not mention this shipment to security."
foodtype = "\"meal\""
-
+
/datum/bounty/item/botany/cannabis_white
name = "Lifeweed Leaves"
wanted_types = list(/obj/item/reagent_containers/food/snacks/grown/cannabis/white)
diff --git a/code/modules/cargo/bounties/chef.dm b/code/modules/cargo/bounties/chef.dm
index b9d9ebc184..719a2d10a5 100644
--- a/code/modules/cargo/bounties/chef.dm
+++ b/code/modules/cargo/bounties/chef.dm
@@ -1,34 +1,34 @@
/datum/bounty/item/chef/birthday_cake
name = "Birthday Cake"
description = "Nanotrasen's birthday is coming up! Ship them a birthday cake to celebrate!"
- reward = 4000
+ reward = 1000
wanted_types = list(/obj/item/reagent_containers/food/snacks/store/cake/birthday, /obj/item/reagent_containers/food/snacks/cakeslice/birthday)
/datum/bounty/item/chef/soup
name = "Soup"
description = "To quell the homeless uprising, Nanotrasen will be serving soup to all underpaid workers. Ship any type of soup."
- reward = 3000
+ reward = 700
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/soup)
/datum/bounty/item/chef/popcorn
name = "Popcorn Bags"
description = "Upper management wants to host a movie night. Ship bags of popcorn for the occasion."
- reward = 3000
+ reward = 800
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/popcorn)
/datum/bounty/item/chef/onionrings
name = "Onion Rings"
description = "Nanotrasen is remembering Saturn day. Ship onion rings to show the station's support."
- reward = 3000
+ reward = 800
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/onionrings)
/datum/bounty/item/chef/icecreamsandwich
name = "Ice Cream Sandwiches"
description = "Upper management has been screaming non-stop for ice cream. Please send some."
- reward = 4000
+ reward = 800
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/icecreamsandwich)
@@ -36,7 +36,7 @@
name = "Bread"
description = "Problems with central planning have led to bread prices skyrocketing. Ship some bread to ease tensions."
reward = 1000
- wanted_types = list(/obj/item/reagent_containers/food/snacks/store/bread, /obj/item/reagent_containers/food/snacks/breadslice, /obj/item/reagent_containers/food/snacks/bun, /obj/item/reagent_containers/food/snacks/pizzabread, /obj/item/reagent_containers/food/snacks/rawpastrybase)
+ wanted_types = list(/obj/item/reagent_containers/food/snacks/store/bread, /obj/item/reagent_containers/food/snacks/breadslice, /obj/item/reagent_containers/food/snacks/bun, /obj/item/reagent_containers/food/snacks/pizzabread, /obj/item/reagent_containers/food/snacks/rawpastrybase)
/datum/bounty/item/chef/pie
name = "Pie"
@@ -47,21 +47,21 @@
/datum/bounty/item/chef/salad
name = "Salad or Rice Bowls"
description = "CentCom management is going on a health binge. Your order is to ship salad or rice bowls."
- reward = 3000
+ reward = 1200
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/salad)
/datum/bounty/item/chef/carrotfries
name = "Carrot Fries"
description = "Night sight can mean life or death! A shipment of carrot fries is the order."
- reward = 3500
+ reward = 1300
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/carrotfries)
/datum/bounty/item/chef/superbite
name = "Super Bite Burger"
description = "Commander Tubbs thinks he can set a competitive eating world record. All he needs is a super bite burger shipped to him."
- reward = 12000
+ reward = 1800
wanted_types = list(/obj/item/reagent_containers/food/snacks/burger/superbite)
/datum/bounty/item/chef/poppypretzel
@@ -73,19 +73,19 @@
/datum/bounty/item/chef/cubancarp
name = "Cuban Carp"
description = "To celebrate the birth of Castro XXVII, ship one cuban carp to CentCom."
- reward = 8000
+ reward = 3000
wanted_types = list(/obj/item/reagent_containers/food/snacks/cubancarp)
/datum/bounty/item/chef/hotdog
name = "Hot Dog"
description = "Nanotrasen is conducting taste tests to determine the best hot dog recipe. Ship your station's version to participate."
- reward = 8000
+ reward = 4000
wanted_types = list(/obj/item/reagent_containers/food/snacks/hotdog)
/datum/bounty/item/chef/eggplantparm
name = "Eggplant Parmigianas"
description = "A famous singer will be arriving at CentCom, and their contract demands that they only be served Eggplant Parmigiana. Ship some, please!"
- reward = 3500
+ reward = 2500
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/eggplantparm)
@@ -99,33 +99,33 @@
/datum/bounty/item/chef/chawanmushi
name = "Chawanmushi"
description = "Nanotrasen wants to improve relations with its sister company, Japanotrasen. Ship Chawanmushi immediately."
- reward = 8000
+ reward = 5000
wanted_types = list(/obj/item/reagent_containers/food/snacks/chawanmushi)
/datum/bounty/item/chef/kebab
name = "Kebabs"
description = "Remove all kebab from station you are best food. Ship to CentCom to remove from the premises."
- reward = 3500
+ reward = 1500
required_count = 3
wanted_types = list(/obj/item/reagent_containers/food/snacks/kebab)
/datum/bounty/item/chef/soylentgreen
name = "Soylent Green"
description = "CentCom has heard wonderful things about the product 'Soylent Green', and would love to try some. If you endulge them, expect a pleasant bonus."
- reward = 5000
+ reward = 4000
wanted_types = list(/obj/item/reagent_containers/food/snacks/soylentgreen)
/datum/bounty/item/chef/pancakes
name = "Pancakes"
description = "Here at Nanotrasen we consider employees to be family. And you know what families love? Pancakes. Ship a baker's dozen."
- reward = 5000
+ reward = 4000
required_count = 13
wanted_types = list(/datum/crafting_recipe/food/pancakes)
/datum/bounty/item/chef/nuggies
name = "Chicken Nuggets"
description = "The vice president's son won't shut up about chicken nuggies. Would you mind shipping some?"
- reward = 4000
+ reward = 2500
required_count = 6
wanted_types = list(/obj/item/reagent_containers/food/snacks/nugget)
diff --git a/code/modules/cargo/bounties/engineering.dm b/code/modules/cargo/bounties/engineering.dm
index cf2cd7d93c..1f16788c4d 100644
--- a/code/modules/cargo/bounties/engineering.dm
+++ b/code/modules/cargo/bounties/engineering.dm
@@ -27,41 +27,41 @@
/datum/bounty/item/engineering/pacman
name = "P.A.C.M.A.N.-type portable generator"
description = "A neighboring station had a problem with their SMES, and now need something to power their communications console. Can you send them a P.AC.M.A.N.?"
- reward = 3500 //2500 for the cargo one
+ reward = 1500 //2500 for the cargo one
wanted_types = list(/obj/machinery/power/port_gen/pacman)
/datum/bounty/item/engineering/canisters
name = "Gas Canisters"
description = "After a recent debacle in a nearby sector, 10 gas canisters are needed for containing an experimental aerosol before it kills all the local fauna."
- reward = 5000
+ reward = 3000
required_count = 10 //easy to make
wanted_types = list(/obj/machinery/portable_atmospherics/canister)
/datum/bounty/item/engineering/microwave
name = "Microwaves"
description = "Due to a shortage of microwaves, our chefs are incapable of keeping up with our sheer volume of orders. We need at least three microwaves to keep up with our crew's dietary habits."
- reward = 2000
+ reward = 1000
required_count = 3
wanted_types = list(/obj/machinery/microwave)
/datum/bounty/item/engineering/hydroponicstrays
name = "Hydroponics Tray"
description = "The garden has become a hot spot of late, they need a few more hydroponics tray to grow more flowers."
- reward = 2500
+ reward = 1500
required_count = 5
wanted_types = list(/obj/machinery/hydroponics)
/datum/bounty/item/engineering/rcd
name = "Spare RCD"
description = "Construction and repairs to are shuttles are going slowly. As it turns out, we're a little short on RCDs, can you send us a few?"
- reward = 2500
+ reward = 1500
required_count = 3
wanted_types = list(/obj/item/construction/rcd)
/datum/bounty/item/engineering/rpd
name = "Spare RPD"
description = "Our Atmospheric Technicians are still living in the past, relying on stationary pipe dispensers to produce the pipes necessary to accomplish their strenuous tasks. They could use an upgrade. Could you send us some Rapid Pipe Dispensers?"
- reward = 3000
+ reward = 2500
required_count = 3
wanted_types = list(/obj/item/pipe_dispenser)
@@ -75,19 +75,19 @@
/datum/bounty/item/engineering/arcadetrail
name = "Orion Trail Arcade Games"
description = "The staff have nothing to do when off-work. Can you send us some Orion Trail games to play?"
- reward = 3000
+ reward = 1500
required_count = 5
wanted_types = list(/obj/machinery/computer/arcade/orion_trail)
/datum/bounty/item/engineering/arcadebattle
name = "Battle Arcade Games"
description = "The staff have nothing to do when off-work. Can you send us some Battle Arcade games to play?"
- reward = 3000
+ reward = 1500
required_count = 5
wanted_types = list(/obj/machinery/computer/arcade/battle)
/datum/bounty/item/engineering/energy_ball
name = "Contained Tesla Ball"
description = "Station 24 is being overrun by hordes of angry Mothpeople. They are requesting the ultimate bug zapper."
- reward = 75000 //requires 14k credits of purchases, not to mention cooperation with engineering/heads of staff to set up inside the cramped shuttle
+ reward = 50000 //requires 14k credits of purchases, not to mention cooperation with engineering/heads of staff to set up inside the cramped shuttle
wanted_types = list(/obj/singularity/energy_ball)
diff --git a/code/modules/cargo/bounties/medical.dm b/code/modules/cargo/bounties/medical.dm
index 3129051754..22964e1fb7 100644
--- a/code/modules/cargo/bounties/medical.dm
+++ b/code/modules/cargo/bounties/medical.dm
@@ -7,34 +7,34 @@
/datum/bounty/item/medical/lung
name = "Lungs"
description = "A recent explosion at Central Command has left multiple staff with punctured lungs. Ship spare lungs to be rewarded."
- reward = 10000
+ reward = 3000
required_count = 3
wanted_types = list(/obj/item/organ/lungs)
/datum/bounty/item/medical/appendix
name = "Appendix"
description = "Chef Gibb of Central Command wants to prepare a meal using a very special delicacy: an appendix. If you ship one, he'll pay."
- reward = 5000 //there are no synthetic appendixes
+ reward = 3500 //there are no synthetic appendixes
wanted_types = list(/obj/item/organ/appendix)
/datum/bounty/item/medical/ears
name = "Ears"
description = "Multiple staff at Station 12 have been left deaf due to unauthorized clowning. Ship them new ears."
- reward = 10000
+ reward = 5000
required_count = 3
wanted_types = list(/obj/item/organ/ears)
/datum/bounty/item/medical/liver
name = "Livers"
description = "Multiple high-ranking CentCom diplomats have been hospitalized with liver failure after a recent meeting with Third Soviet Union ambassadors. Help us out, will you?"
- reward = 10000
+ reward = 5500
required_count = 3
wanted_types = list(/obj/item/organ/liver)
/datum/bounty/item/medical/eye
name = "Organic Eyes"
description = "Station 5's Research Director Willem is requesting a few pairs of non-robotic eyes. Don't ask questions, just ship them."
- reward = 10000
+ reward = 3000
required_count = 3
wanted_types = list(/obj/item/organ/eyes)
exclude_types = list(/obj/item/organ/eyes/robotic)
@@ -42,7 +42,7 @@
/datum/bounty/item/medical/tongue
name = "Tongues"
description = "A recent attack by Mime extremists has left staff at Station 23 speechless. Ship some spare tongues."
- reward = 10000
+ reward = 4500
required_count = 3
wanted_types = list(/obj/item/organ/tongue)
@@ -79,7 +79,7 @@
required_count = 200
wanted_types = (L,/datum/reagent/blood)
if(istype(L,/datum/reagent/blood))
- wanted_types += L
+ wanted_types += L
/datum/bounty/item/medical/bloodu //Dosnt work do to how blood is yet*
name = "U-Type Blood"
@@ -88,40 +88,40 @@
required_count = 200
wanted_types = (U,/datum/reagent/blood)
if(istype(U,/datum/reagent/blood))
- wanted_types += U
+ wanted_types += U
*/
/datum/bounty/item/medical/surgery
name = "Surgery tool implants"
description = "Our medical interns keep dropping their Shambler's Juice while they're performing open heart surgery. One of them even had the audacity to say he only had two hands!"
- reward = 10000
+ reward = 7000
required_count = 3
wanted_types = list(/obj/item/organ/cyberimp/arm/surgery)
/datum/bounty/item/medical/chemmaker
name = "Portable Chem Dispenser"
description = "After a new chemist mixed up some water and a banana, we lost our only chem dispenser. Please send us a replacement and you will be compensated."
- reward = 7000
+ reward = 5000
wanted_types = list(/obj/machinery/chem_dispenser)
/datum/bounty/item/medical/advhealthscaner
name = "Advanced Health Analyzer"
description = "A ERT Medical unit needs the new 'advanced health analyzer', for a mission at a Station 4. Can you send some?."
- reward = 4000
+ reward = 3000
required_count = 5
wanted_types = list(/obj/item/healthanalyzer/advanced)
/datum/bounty/item/medical/wallmounts
name = "Defibrillator wall mounts"
description = "New Space OSHA regulation state that are new cloning medical wing needs a few 'Easy to access defibrillartors'. Can you send a few before we get a lawsuit?"
- reward = 5000
+ reward = 2000
required_count = 3
wanted_types = list(/obj/machinery/defibrillator_mount)
/datum/bounty/item/medical/defibrillator
name = "New defibillators"
description = "After years of storge are defibrillator units have become more liabilities then we want. Please send us some new ones to replace these old ones."
- reward = 5000
+ reward = 2250
required_count = 5
wanted_types = list(/obj/item/defibrillator)
diff --git a/code/modules/cargo/bounties/mining.dm b/code/modules/cargo/bounties/mining.dm
index 51d93f83b5..1f3266af62 100644
--- a/code/modules/cargo/bounties/mining.dm
+++ b/code/modules/cargo/bounties/mining.dm
@@ -8,58 +8,58 @@
/datum/bounty/item/mining/goliath_boat
name = "Goliath Hide Boat"
description = "Commander Menkov wants to participate in the annual Lavaland Regatta. He is asking your shipwrights to build the swiftest boat known to man."
- reward = 10000
+ reward = 5500
wanted_types = list(/obj/vehicle/ridden/lavaboat)
/datum/bounty/item/mining/bone_oar
name = "Bone Oars"
description = "Commander Menkov requires oars to participate in the annual Lavaland Regatta. Ship a pair over."
- reward = 4000
+ reward = 2000
required_count = 2
wanted_types = list(/obj/item/oar)
/datum/bounty/item/mining/bone_axe
name = "Bone Axe"
description = "Station 12 has had their fire axes stolen by marauding clowns. Ship them a bone axe as a replacement."
- reward = 7500
+ reward = 3500
wanted_types = list(/obj/item/twohanded/fireaxe/boneaxe)
/datum/bounty/item/mining/bone_armor
name = "Bone Armor"
description = "Station 14 has volunteered their lizard crew for ballistic armor testing. Ship over some bone armor."
- reward = 5000
+ reward = 2000
wanted_types = list(/obj/item/clothing/suit/armor/bone)
/datum/bounty/item/mining/skull_helmet
name = "Skull Helmet"
description = "Station 42's Head of Security has her birthday tomorrow! We want to suprise her with a fashionable skull helmet."
- reward = 4000
+ reward = 2000
wanted_types = list(/obj/item/clothing/head/helmet/skull)
/datum/bounty/item/mining/bone_talisman
name = "Bone Talismans"
description = "Station 14's Research Director claims that pagan bone talismans protect their wearer. Ship them a few so they can start testing."
- reward = 7500
+ reward = 3500
required_count = 3
wanted_types = list(/obj/item/clothing/accessory/talisman)
/datum/bounty/item/mining/bone_dagger
name = "Bone Daggers"
description = "Central Command's canteen is undergoing budget cuts. Ship over some bone daggers so our Chef can keep working."
- reward = 5000
+ reward = 1000
required_count = 3
wanted_types = list(/obj/item/kitchen/knife/combat/bone)
/datum/bounty/item/mining/basalt
name = "Artificial Basalt Tiles"
description = "Central Command's Ash Walker exhibit needs to be expanded again, we just need some more basalt flooring."
- reward = 5000
+ reward = 2200
required_count = 60
wanted_types = list(/obj/item/stack/tile/basalt)
/datum/bounty/item/mining/fruit
name = "Cactus Fruit"
description = "Central Command's Ash Walker habitat needs more fauna, send us some local fruit seeds!"
- reward = 2000
+ reward = 1000
required_count = 1
wanted_types = list(/obj/item/seeds/lavaland/cactus)
diff --git a/code/modules/cargo/bounties/reagent.dm b/code/modules/cargo/bounties/reagent.dm
index 9f1c76db3d..5137d0a6f3 100644
--- a/code/modules/cargo/bounties/reagent.dm
+++ b/code/modules/cargo/bounties/reagent.dm
@@ -116,11 +116,11 @@ datum/bounty/reagent/complex_drink/New()
wanted_reagent = new reagent_type
name = wanted_reagent.name
description = "CentCom is offering a reward for talented mixologists. Ship a container of [name] to claim the prize."
- reward += rand(0, 4) * 500
+ reward += rand(0, 4) * 300
/datum/bounty/reagent/chemical
name = "Chemical"
- reward = 4000
+ reward = 2750
required_volume = 30
datum/bounty/reagent/chemical/New()
diff --git a/code/modules/cargo/bounties/science.dm b/code/modules/cargo/bounties/science.dm
index 2ac79f6ee8..6102d8d685 100644
--- a/code/modules/cargo/bounties/science.dm
+++ b/code/modules/cargo/bounties/science.dm
@@ -1,116 +1,116 @@
/datum/bounty/item/science/boh
name = "Bag of Holding"
description = "Nanotrasen would make good use of high-capacity backpacks. If you have any, please ship them."
- reward = 10000
+ reward = 5000
wanted_types = list(/obj/item/storage/backpack/holding)
/datum/bounty/item/science/tboh
name = "Trash Bag of Holding"
description = "Nanotrasen would make good use of high-capacity trash bags. If you have any, please ship them."
- reward = 10000
+ reward = 3000
wanted_types = list(/obj/item/storage/backpack/holding)
/datum/bounty/item/science/bluespace_syringe
name = "Bluespace Syringe"
description = "Nanotrasen would make good use of high-capacity syringes. If you have any, please ship them."
- reward = 10000
+ reward = 1500
wanted_types = list(/obj/item/reagent_containers/syringe/bluespace)
/datum/bounty/item/science/bluespace_body_bag
name = "Bluespace Body Bag"
description = "Nanotrasen would make good use of high-capacity body bags. If you have any, please ship them."
- reward = 10000
+ reward = 5000
wanted_types = list(/obj/item/bodybag/bluespace)
/datum/bounty/item/science/nightvision_goggles
name = "Night Vision Goggles"
description = "An electrical storm has busted all the lights at CentCom. While management is waiting for replacements, perhaps some night vision goggles can be shipped?"
- reward = 10000
+ reward = 1000
wanted_types = list(/obj/item/clothing/glasses/night, /obj/item/clothing/glasses/meson/night, /obj/item/clothing/glasses/hud/health/night, /obj/item/clothing/glasses/hud/security/night, /obj/item/clothing/glasses/hud/diagnostic/night)
/datum/bounty/item/science/experimental_welding_tool
name = "Experimental Welding Tool"
description = "A recent accident has left most of CentCom's welding tools exploded. Ship replacements to be rewarded."
- reward = 10000
+ reward = 5000
required_count = 3
wanted_types = list(/obj/item/weldingtool/experimental)
/datum/bounty/item/science/cryostasis_beaker
name = "Cryostasis Beaker"
description = "Chemists at Central Command have discovered a new chemical that can only be held in cryostasis beakers. The only problem is they don't have any! Rectify this to receive payment."
- reward = 10000
+ reward = 2000
wanted_types = list(/obj/item/reagent_containers/glass/beaker/noreact)
/datum/bounty/item/science/diamond_drill
name = "Diamond Mining Drill"
description = "Central Command is willing to pay three months salary in exchange for one diamond mining drill."
- reward = 15000
+ reward = 5500
wanted_types = list(/obj/item/pickaxe/drill/diamonddrill, /obj/item/mecha_parts/mecha_equipment/drill/diamonddrill)
/datum/bounty/item/science/floor_buffer
name = "Floor Buffer Upgrade"
description = "One of CentCom's janitors made a small fortune betting on carp races. Now they'd like to commission an upgrade to their floor buffer."
- reward = 10000
+ reward = 3000
wanted_types = list(/obj/item/janiupgrade)
/datum/bounty/item/science/advanced_mop
name = "Advanced Mop"
description = "Excuse me. I'd like to request $17 for a push broom rebristling. Either that, or an advanced mop."
- reward = 10000
+ reward = 3000
wanted_types = list(/obj/item/mop/advanced)
/datum/bounty/item/science/advanced_egun
name = "Advanced Energy Gun"
description = "With the price of rechargers on the rise, upper management is interested in purchasing guns that are self-powered. If you ship one, they'll pay."
- reward = 10000
+ reward = 1800
wanted_types = list(/obj/item/gun/energy/e_gun/nuclear)
/datum/bounty/item/science/bscells
name = "Bluespace Power Cells"
description = "Someone in upper management keeps using the excuse that his tablet battery dies when he's in the middle of work. This will be the last time he doesn't have his presentation, I swear to -"
- reward = 7000
+ reward = 3000
required_count = 10 //Easy to make
wanted_types = list(/obj/item/stock_parts/cell/bluespace)
/datum/bounty/item/science/t4manip
name = "Femto-Manipulators"
description = "One of our Chief Engineers has OCD. Can you send us some femto-manipulators so he stops complaining that his ID doesn't fit perfectly in the PDA slot?"
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/manipulator/femto)
/datum/bounty/item/science/t4bins
name = "Bluespace Matter Bins"
description = "The local Janitorial union has gone on strike. Can you send us some bluespace bins so we don't have to take out our own trash?"
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/matter_bin/bluespace)
/datum/bounty/item/science/t4capacitor
name = "Quadratic Capacitor"
description = "One of our linguists doesn't understand why they're called Quadratic capacitors. Can you give him a few so he leaves us alone about it?"
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/capacitor/quadratic)
/datum/bounty/item/science/t4triphasic
name = "Triphasic Scanning Module"
description = "One of our scientists got into the liberty caps and is demanding new scanning modules so he can talk to ghosts. At this point we just want him out of our office."
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/scanning_module/triphasic)
/datum/bounty/item/science/t4microlaser
name = "Quad-Ultra Micro-Laser"
description = "The cats on Vega 9 are breeding out of control. We need something to corral them into one area so we can saturation bomb it."
- reward = 7000
+ reward = 2000
required_count = 20 //Easy to make
wanted_types = list(/obj/item/stock_parts/micro_laser/quadultra)
/datum/bounty/item/science/fakecrystals
name = "synthetic bluespace crystals"
description = "Don't, uh, tell anyone, but one of our BSA arrays might have had a little... accident. Send us some bluespace crystals so we can recalibrate it before anyone realizes. The whole set uses artificial bluespace crystals, so we need and not any other type of bluespace crystals..."
- reward = 10000
+ reward = 8000
required_count = 5
wanted_types = list(/obj/item/stack/ore/bluespace_crystal/artificial)
exclude_types = list(/obj/item/stack/ore/bluespace_crystal,
diff --git a/code/modules/cargo/bounties/security.dm b/code/modules/cargo/bounties/security.dm
index cae8d10c61..6ed86cd4b7 100644
--- a/code/modules/cargo/bounties/security.dm
+++ b/code/modules/cargo/bounties/security.dm
@@ -1,54 +1,54 @@
/datum/bounty/item/security/riotshotgun
name = "Riot Shotguns"
description = "Hooligans have boarded CentCom! Ship riot shotguns quick, or things are going to get dirty."
- reward = 5000
+ reward = 2500
required_count = 2
wanted_types = list(/obj/item/gun/ballistic/shotgun/riot)
/datum/bounty/item/security/recharger
name = "Rechargers"
description = "Nanotrasen military academy is conducting marksmanship exercises. They request that rechargers be shipped."
- reward = 2000
+ reward = 1700
required_count = 3
wanted_types = list(/obj/machinery/recharger)
/datum/bounty/item/security/practice
name = "Practice Laser Gun"
description = "Nanotrasen Military Academy is conducting routine marksmanship exercises. The clown hid all the practice lasers, and we're not using live weapons after last time."
- reward = 3000
+ reward = 1500
required_count = 3
wanted_types = list(/obj/item/gun/energy/laser/practice)
/datum/bounty/item/security/flashshield
name = "Strobe Shield"
description = "One of our Emergency Response Agents thinks there's vampires in a local station. Send him something to help with his fear of the dark and protect him, too."
- reward = 5000
+ reward = 3000
wanted_types = list(/obj/item/assembly/flash/shield)
/datum/bounty/item/security/sechuds
name = "Sec HUDs"
description = "Nanotrasen military academy has started to train officers how to use Sec HUDs to the fullest affect. Please send spare Sec HUDs so we can teach the men."
- reward = 3000
+ reward = 1250
required_count = 5
wanted_types = list(/obj/item/clothing/glasses/hud/security)
/datum/bounty/item/security/techslugs
name = "Tech Slugs"
description = "Nanotrasen Military Academy is conducting an ammo loading and use lessons, on the new 'Tech Slugs'. Problem is we don't have any, please fix this..."
- reward = 7500
+ reward = 3500
required_count = 15
wanted_types = list(/obj/item/ammo_casing/shotgun/techshell)
-/datum/bounty/item/security/WT550
+/datum/bounty/item/security/wt550
name = "Spare WT-550 clips"
description = "Nanotrasen Military Academy's ammunition is running low, please send in spare ammo for practice."
- reward = 7500
+ reward = 1500
required_count = 5
wanted_types = list(/obj/item/ammo_box/magazine/wt550m9)
/datum/bounty/item/security/pins
name = "Test range firing pins"
description = "Nanotrasen Military Academy just got a new set of guns, sadly they didn't come with any pins. Can you send us some Test range locked firing pins?"
- reward = 5000
+ reward = 2750
required_count = 3
wanted_types = list(/obj/item/firing_pin/test_range)
diff --git a/code/modules/cargo/bounties/slime.dm b/code/modules/cargo/bounties/slime.dm
index 4aa0797c70..f52f995a27 100644
--- a/code/modules/cargo/bounties/slime.dm
+++ b/code/modules/cargo/bounties/slime.dm
@@ -1,10 +1,10 @@
/datum/bounty/item/slime
- reward = 3000
+ reward = 1950
/datum/bounty/item/slime/New()
..()
description = "Nanotrasen's science lead is hunting for the rare and exotic [name]. A bounty has been offered for finding it."
- reward += rand(0, 4) * 500
+ reward += rand(0, 4) * 250
/datum/bounty/item/slime/green
name = "Green Slime Extract"
diff --git a/code/modules/cargo/bounties/special.dm b/code/modules/cargo/bounties/special.dm
index adffaf999a..be91b1d8aa 100644
--- a/code/modules/cargo/bounties/special.dm
+++ b/code/modules/cargo/bounties/special.dm
@@ -1,14 +1,14 @@
/datum/bounty/item/alien_organs
name = "Alien Organs"
description = "Nanotrasen is interested in studying Xenomorph biology. Ship a set of organs to be thoroughly compensated."
- reward = 25000
+ reward = 13500
required_count = 3
wanted_types = list(/obj/item/organ/brain/alien, /obj/item/organ/alien, /obj/item/organ/body_egg/alien_embryo)
/datum/bounty/item/syndicate_documents
name = "Syndicate Documents"
description = "Intel regarding the syndicate is highly prized at CentCom. If you find syndicate documents, ship them. You could save lives."
- reward = 15000
+ reward = 10000
wanted_types = list(/obj/item/documents/syndicate, /obj/item/documents/photocopy)
/datum/bounty/item/syndicate_documents/applies_to(obj/O)
@@ -22,15 +22,15 @@
/datum/bounty/item/adamantine
name = "Adamantine"
description = "Nanotrasen's anomalous materials division is in desparate need for Adamantine. Send them a large shipment and we'll make it worth your while."
- reward = 35000
+ reward = 15000
required_count = 10
wanted_types = list(/obj/item/stack/sheet/mineral/adamantine)
/datum/bounty/more_bounties
name = "More Bounties"
description = "Complete enough bounties and CentCom will issue new ones!"
- reward = 3 // number of bounties
- var/required_bounties = 5
+ reward = 8 // number of bounties
+ var/required_bounties = 3
/datum/bounty/more_bounties/can_claim()
return ..() && completed_bounty_count() >= required_bounties
diff --git a/code/modules/cargo/bounties/virus.dm b/code/modules/cargo/bounties/virus.dm
index 8f078a2668..938ac7708d 100644
--- a/code/modules/cargo/bounties/virus.dm
+++ b/code/modules/cargo/bounties/virus.dm
@@ -1,5 +1,5 @@
/datum/bounty/virus
- reward = 5000
+ reward = 3000
var/shipped = FALSE
var/stat_value = 0
var/stat_name = ""
@@ -11,7 +11,7 @@
stat_value *= -1
name = "Virus ([stat_name] of [stat_value])"
description = "Nanotrasen is interested in a virus with a [stat_name] stat of exactly [stat_value]. Central Command will pay handsomely for such a virus."
- reward += rand(0, 4) * 500
+ reward += rand(0, 4) * 400
/datum/bounty/virus/completion_string()
return shipped ? "Shipped" : "Not Shipped"
diff --git a/code/modules/cargo/exports.dm b/code/modules/cargo/exports.dm
index b7550465d9..9a99f201b3 100644
--- a/code/modules/cargo/exports.dm
+++ b/code/modules/cargo/exports.dm
@@ -1,6 +1,6 @@
/* How it works:
The shuttle arrives at CentCom dock and calls sell(), which recursively loops through all the shuttle contents that are unanchored.
-
+
Each object in the loop is checked for applies_to() of various export datums, except the invalid ones.
*/
@@ -31,7 +31,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
setupExports()
var/list/contents = AM.GetAllContents()
-
+
var/datum/export_report/report = external_report
if(!report) //If we don't have any longer transaction going on
report = new
@@ -58,7 +58,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
var/unit_name = "" // Unit name. Only used in "Received [total_amount] [name]s [message]." message
var/message = ""
var/cost = 100 // Cost of item, in cargo credits. Must not alow for infinite price dupes, see above.
- var/k_elasticity = 1/30 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity"
+ var/k_elasticity = 1/20 //coefficient used in marginal price calculation that roughly corresponds to the inverse of price elasticity, or "quantity elasticity" - CIT EDIT 30 - > 20
var/list/export_types = list() // Type of the exported object. If none, the export datum is considered base type.
var/include_subtypes = TRUE // Set to FALSE to make the datum apply only to a strict type.
var/list/exclude_types = list() // Types excluded from export
@@ -125,9 +125,9 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
if(amount <=0 || the_cost <=0)
return FALSE
-
+
report.total_value[src] += the_cost
-
+
if(istype(O, /datum/export/material))
report.total_amount[src] += amount*MINERAL_MATERIAL_AMOUNT
else
@@ -148,7 +148,7 @@ Credit dupes that require a lot of manual work shouldn't be removed, unless they
var/total_value = ex.total_value[src]
var/total_amount = ex.total_amount[src]
-
+
var/msg = "[total_value] credits: Received [total_amount] "
if(total_value > 0)
msg = "+" + msg
diff --git a/code/modules/cargo/exports/gear.dm b/code/modules/cargo/exports/gear.dm
index 125e0f708b..7ff14df04c 100644
--- a/code/modules/cargo/exports/gear.dm
+++ b/code/modules/cargo/exports/gear.dm
@@ -1,83 +1,800 @@
/datum/export/gear
+ include_subtypes = FALSE
+
+//blanket
+/datum/export/gear/hat
+ cost = 3
+ unit_name = "clothing"
+ export_types = list(/obj/item/clothing)
+ include_subtypes = TRUE
+
+//Hats
+
+//Blanket
+/datum/export/gear/hat
+ cost = 5
+ unit_name = "hat"
+ export_types = list(/obj/item/clothing/head)
+ include_subtypes = TRUE
/datum/export/gear/sec_helmet
- cost = 100
+ cost = 70
unit_name = "helmet"
export_types = list(/obj/item/clothing/head/helmet/sec)
-/datum/export/gear/sec_armor
- cost = 100
- unit_name = "armor vest"
- export_types = list(/obj/item/clothing/suit/armor/vest)
+/datum/export/gear/sec_soft
+ cost = 50
+ unit_name = "soft sec cap"
+ export_types = list(/obj/item/clothing/head/soft/sec)
-/datum/export/gear/riot_shield
- cost = 100
- unit_name = "riot shield"
- export_types = list(/obj/item/shield/riot)
+/datum/export/gear/sec_helmetalt
+ cost = 50
+ unit_name = "bullet proof helmet"
+ export_types = list(/obj/item/clothing/head/helmet/alt)
+/datum/export/gear/sec_helmetold
+ cost = 10
+ unit_name = "old helmet"
+ export_types = list(/obj/item/clothing/head/helmet/old)
+
+/datum/export/gear/sec_helmetblue
+ cost = 75
+ unit_name = "blue helmet"
+ export_types = list(/obj/item/clothing/head/helmet/blueshirt)
+
+/datum/export/gear/sec_helmetriot
+ cost = 100
+ unit_name = "riot helmet"
+ export_types = list(/obj/item/clothing/head/helmet/riot)
+
+/datum/export/gear/sec_helmet_light
+ cost = 20
+ unit_name = "justice helmet"
+ export_types = list(/obj/item/clothing/head/helmet/justice/escape)
+ include_subtypes = TRUE
+
+/datum/export/gear/syndicate_helmetswat
+ cost = 250
+ unit_name = "syndicate helmet"
+ export_types = list(/obj/item/clothing/head/helmet/swat)
+
+/datum/export/gear/sec_helmetswat
+ cost = 150
+ unit_name = "swat helmet"
+ export_types = list(/obj/item/clothing/head/helmet/swat/nanotrasen)
+
+/datum/export/gear/thunder_helmet
+ cost = 120
+ unit_name = "thunder dome helmet"
+ export_types = list(/obj/item/clothing/head/helmet/thunderdome)
+
+/datum/export/gear/roman_real
+ cost = 30
+ unit_name = "roman helmet"
+ export_types = list(/obj/item/clothing/head/helmet/roman)
+
+/datum/export/gear/roman_realalt
+ cost = 60
+ unit_name = "legionnaire helmet"
+ export_types = list(/obj/item/clothing/head/helmet/roman/legionnaire)
+
+/datum/export/gear/roman_fake
+ cost = 10
+ unit_name = "toy roman helmet"
+ export_types = list(/obj/item/clothing/head/helmet/roman/fake)
+
+/datum/export/gear/roman_fakealt
+ cost = 20
+ unit_name = "toy legionnaire helmet"
+ export_types = list(/obj/item/clothing/head/helmet/roman/legionnaire/fake)
+
+/datum/export/gear/ash_walker_helm
+ cost = 70
+ unit_name = "gladiator helmet"
+ export_types = list(/obj/item/clothing/head/helmet/gladiator)
+
+/datum/export/gear/lasertag
+ cost = 30 //Has armor
+ unit_name = "lasertag helmet"
+ export_types = list(/obj/item/clothing/head/helmet/redtaghelm)
+
+/datum/export/gear/lasertag/blue
+ export_types = list(/obj/item/clothing/head/helmet/bluetaghelm)
+
+/datum/export/gear/knight_helmet
+ cost = 200
+ k_elasticity = 1/5 //Rare, dont flood it
+ unit_name = "knight helmet"
+ export_types = list(/obj/item/clothing/head/helmet/knight, /obj/item/clothing/head/helmet/knight/blue, /obj/item/clothing/head/helmet/knight/yellow, /obj/item/clothing/head/helmet/knight/red)
+
+/datum/export/gear/skull_hat
+ cost = 70
+ k_elasticity = 1/15 //Its just a skull
+ unit_name = "skull"
+ export_types = list(/obj/item/clothing/head/helmet/skull)
+
+/datum/export/gear/durathread_helm
+ cost = 100
+ k_elasticity = 1/15
+ unit_name = "durathread hat"
+ export_types = list(/obj/item/clothing/head/helmet/durathread, /obj/item/clothing/head/beret/durathread, /obj/item/clothing/head/beanie/durathread)
+
+/datum/export/gear/hard_hats
+ cost = 50
+ unit_name = "hard hat"
+ export_types = list(/obj/item/clothing/head/hardhat, /obj/item/clothing/head/hardhat/orange, /obj/item/clothing/head/hardhat/white, /obj/item/clothing/head/hardhat/dblue)
+
+/datum/export/gear/atmos_helm
+ cost = 200 //Armored, fire proof, light, and presser proof
+ unit_name = "atmos hard hat"
+ export_types = list(/obj/item/clothing/head/hardhat/atmos)
+
+/datum/export/gear/crowns
+ cost = 350 //Armored, gold 300cr of gold to make so give them 50 more for working
+ k_elasticity = 1/5 //Anti-floods
+ unit_name = "crown"
+ export_types = list(/obj/item/clothing/head/crown, /obj/item/clothing/head/crown/fancy)
+
+/datum/export/gear/cchat
+ cost = 40
+ unit_name = "centcom hat"
+ export_types = list(/obj/item/clothing/head/centhat)
+
+/datum/export/gear/caphat
+ cost = 150
+ unit_name = "command hat"
+ export_types = list(/obj/item/clothing/head/caphat, /obj/item/clothing/head/caphat/parade, /obj/item/clothing/head/caphat/beret)
+
+/datum/export/gear/hophat
+ cost = 130
+ unit_name = "hop hat"
+ export_types = list(/obj/item/clothing/head/hopcap, /obj/item/clothing/head/hopcap/beret)
+
+/datum/export/gear/dechat
+ cost = 75
+ k_elasticity = 1/8 //Anti-floods
+ unit_name = "fedora"
+ export_types = list(/obj/item/clothing/head/fedora/det_hat, /obj/item/clothing/head/fedora/curator, /obj/item/clothing/head/fedora)
+
+/datum/export/gear/hoshat
+ cost = 140
+ unit_name = "hos hat"
+ export_types = list(/obj/item/clothing/head/HoS, /obj/item/clothing/head/HoS/beret, /obj/item/clothing/head/beret/sec/navyhos)
+
+/datum/export/gear/syndahoshat
+ cost = 300
+ unit_name = "syndicate command hat"
+ export_types = list(/obj/item/clothing/head/HoS/syndicate, /obj/item/clothing/head/HoS/beret/syndicate)
+
+/datum/export/gear/wardenhat
+ cost = 90
+ unit_name = "warden hat"
+ export_types = list(/obj/item/clothing/head/warden, /obj/item/clothing/head/warden/drill, /obj/item/clothing/head/beret/sec/navywarden)
+
+/datum/export/gear/sechats
+ cost = 60
+ unit_name = "sec beret"
+ export_types = list(/obj/item/clothing/head/beret/sec, /obj/item/clothing/head/beret/sec/navyofficer)
+
+/datum/export/gear/berets
+ cost = 30
+ unit_name = "beret"
+ export_types = list(/obj/item/clothing/head/beret/qm, /obj/item/clothing/head/beret/rd, /obj/item/clothing/head/beret/cmo, /obj/item/clothing/head/beret)
+
+/datum/export/gear/berets
+ cost = 30
+ unit_name = "beret"
+ export_types = list(/obj/item/clothing/head/beret/qm, /obj/item/clothing/head/beret/rd, /obj/item/clothing/head/beret/cmo, /obj/item/clothing/head/beret)
+
+/datum/export/gear/collectable
+ cost = 500
+ unit_name = "collectable hat"
+ k_elasticity = 1/10 //dont flood these
+ export_types = list(/obj/item/clothing/head/collectable)
+ include_subtypes = TRUE
+
+/datum/export/gear/fancyhats
+ cost = 75
+ unit_name = "fancy hat"
+ k_elasticity = 1/10 //dont flood these
+ export_types = list(/obj/item/clothing/head/that, /obj/item/clothing/head/bowler, /obj/item/clothing/head/lizard, /obj/item/clothing/head/canada)
+
+/datum/export/gear/welders
+ cost = 30
+ unit_name = "welder helm"
+ k_elasticity = 1/20 //dont flood these
+ export_types = list(/obj/item/clothing/head/welding)
+
+/datum/export/gear/magichat //Magic as is Antags-Wiz/Cults
+ cost = 450
+ unit_name = "magic hat"
+ export_types = list(/obj/item/clothing/head/wizard, /obj/item/clothing/head/culthood, /obj/item/clothing/head/magus, /obj/item/clothing/head/helmet/clockwork)
+ exclude_types = list(/obj/item/clothing/head/wizard/fake, /obj/item/clothing/head/wizard/marisa/fake)
+ include_subtypes = TRUE
+
+//Shoes
+
+//Blanket
+/datum/export/gear/shoes
+ cost = 1 //Really dont want to sell EVERY SHOE EVER - yet*
+ unit_name = "shoes"
+ export_types = list(/obj/item/clothing/shoes)
+ include_subtypes = TRUE
+
+/datum/export/gear/clown_shoesmk
+ cost = 600
+ unit_name = "mk-honk prototype shoes"
+ export_types = list(/obj/item/clothing/shoes/clown_shoes/banana_shoes)
+
+/datum/export/gear/magboots
+ cost = 50
+ unit_name = "magboots"
+ export_types = list(/obj/item/clothing/shoes/magboots, /obj/item/clothing/shoes/magboots/atmos)
+
+/datum/export/gear/nosellboots
+ cost = -5000 //We DONT want scew antags
+ unit_name = "error shipment stolen"
+ export_types = list(/obj/item/clothing/shoes/magboots/advance, /obj/item/clothing/shoes/magboots/deathsquad)
+
+/datum/export/gear/syndamagboots
+ cost = 250
+ unit_name = "blood redmagboots"
+ export_types = list(/obj/item/clothing/shoes/magboots/syndie)
+
+/datum/export/gear/combatboots
+ cost = 30
+ unit_name = "combat boots"
+ export_types = list(/obj/item/clothing/shoes/combat)
+
+/datum/export/gear/swatboots
+ cost = 45
+ unit_name = "swat boots"
+ export_types = list(/obj/item/clothing/shoes/combat/swat)
+
+/datum/export/gear/galoshes
+ cost = 50
+ unit_name = "galoshes"
+ export_types = list(/obj/item/clothing/shoes/galoshes, /obj/item/clothing/shoes/galoshes/dry)
+
+/datum/export/gear/clown
+ cost = 10
+ unit_name = "clown shoes"
+ export_types = list(/obj/item/clothing/shoes/clown_shoes, /obj/item/clothing/shoes/clown_shoes/jester)
+
+/datum/export/gear/dressshoes
+ cost = 10
+ unit_name = "dress shoes"
+ export_types = list(/obj/item/clothing/shoes/laceup, /obj/item/clothing/shoes/singerb, /obj/item/clothing/shoes/singery)
+
+/datum/export/gear/working
+ cost = 15
+ unit_name = "boots"
+ export_types = list(/obj/item/clothing/shoes/jackboots/fast, /obj/item/clothing/shoes/winterboots, /obj/item/clothing/shoes/jackboots, /obj/item/clothing/shoes/workboots, /obj/item/clothing/shoes/workboots/mining)
+
+/datum/export/gear/hopboots
+ cost = 350 //costs 1000 credits for miners to get
+ unit_name = "jump boots"
+ export_types = list(/obj/item/clothing/shoes/bhop)
+
+/datum/export/gear/magicboots //Magic as in Antag - Wiz/Cults
+ cost = 450
+ unit_name = "magic shoes"
+ export_types = list(/obj/item/clothing/shoes/sandal/marisa, /obj/item/clothing/shoes/sandal/magic, /obj/item/clothing/shoes/cult, /obj/item/clothing/shoes/clockwork, /obj/item/clothing/shoes/clown_shoes/taeclowndo, /obj/item/clothing/shoes/sandal/slippers)
+ include_subtypes = TRUE
+
+//Headsets/Ears
+
+//Blanket
+/datum/export/gear/ears
+ cost = 2 //We dont want to sell every headset ever
+ unit_name = "ear gear"
+ export_types = list(/obj/item/clothing/ears, /obj/item/radio/headset)
+ include_subtypes = TRUE
+
+//Gloves
+
+//Blanket
+/datum/export/gear/gloves
+ cost = 4 //Glove crafting can be done
+ unit_name = "gloves"
+ export_types = list(/obj/item/clothing/gloves)
+ include_subtypes = TRUE
+
+/datum/export/gear/boxing
+ cost = 10 //Padding as well as a weapon
+ unit_name = "boxing gloves"
+ export_types = list(/obj/item/clothing/gloves/boxing)
+ include_subtypes = TRUE
+
+/datum/export/gear/combatgloves
+ cost = 80
+ unit_name = "combat gloves"
+ export_types = list(/obj/item/clothing/gloves/combat, /obj/item/clothing/gloves/rapid, /obj/item/clothing/gloves/krav_maga)
+ include_subtypes = TRUE
+
+/datum/export/gear/bonegloves
+ cost = 30
+ unit_name = "bone bracers"
+ export_types = list(/obj/item/clothing/gloves/bracer)
+
+/datum/export/gear/yellowgloves
+ cost = 50
+ unit_name = "insulated gloves"
+ export_types = list(/obj/item/clothing/gloves/color/yellow, /obj/item/clothing/gloves/color/red/insulated)
+
+/datum/export/gear/leathergloves
+ cost = 20
+ unit_name = "leather gloves"
+ export_types = list(/obj/item/clothing/gloves/botanic_leather)
+
+/datum/export/gear/fancy
+ cost = 25
+ unit_name = "fancy gloves"
+ export_types = list(/obj/item/clothing/gloves/color/black, /obj/item/clothing/gloves/color/captain, /obj/item/clothing/gloves/color/white)
+
+/datum/export/gear/magicgloves//Magic as in Antag - Wiz/Cults
+ cost = 400
+ unit_name = "magic gloves"
+ export_types = list(/obj/item/clothing/gloves/clockwork)
+ include_subtypes = TRUE
+
+//Ties/neck
+
+//Blanket
+/datum/export/gear/neck
+ cost = 5 //Fancy!
+ unit_name = "neck based gear"
+ export_types = list(/obj/item/clothing/neck)
+ include_subtypes = TRUE
+
+/datum/export/gear/collar
+ cost = 7
+ unit_name = "collar"
+ export_types = list(/obj/item/clothing/neck/petcollar)
+ include_subtypes = TRUE
+
+/datum/export/gear/bling
+ cost = 15 //Needs a coin
+ unit_name = "gold plated necklace"
+ export_types = list(/obj/item/clothing/neck/necklace/dope)
+
+//masks
+
+//Blanket
+/datum/export/gear/masks
+ cost = 3 //Mostly just fake stuff and clowngear
+ unit_name = "face gear"
+ export_types = list(/obj/item/clothing/mask)
+ include_subtypes = TRUE
+
+/datum/export/gear/gasmask
+ cost = 4
+ unit_name = "gas mask"
+ export_types = list(/obj/item/clothing/mask/gas, /obj/item/clothing/mask/gas/glass)
+
+/datum/export/gear/minermask
+ cost = 10
+ unit_name = "armored mask"
+ export_types = list(/obj/item/clothing/mask/gas/welding, /obj/item/clothing/mask/gas/explorer, /obj/item/clothing/mask/gas/syndicate)
+
+/datum/export/gear/sechailer
+ cost = 6
+ unit_name = "sec hailer"
+ export_types = list(/obj/item/clothing/mask/gas/sechailer)
+ include_subtypes = TRUE
/datum/export/gear/mask/breath
cost = 2
unit_name = "breath mask"
export_types = list(/obj/item/clothing/mask/breath)
-/datum/export/gear/mask/gas
- cost = 10
- unit_name = "gas mask"
- export_types = list(/obj/item/clothing/mask/gas)
- include_subtypes = FALSE
+//Hardsuits //If you steal/fine more they are worth selling
+//Blanket
+/datum/export/gear/hardsuit
+ cost = 250 //Its just metal/plastic after all
+ unit_name = "unknown hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit)
+ include_subtypes = TRUE
-/datum/export/gear/space/helmet
- cost = 75
+/datum/export/gear/engi_hardsuit
+ cost = 500
+ unit_name = "engine hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/engine)
+
+/datum/export/gear/atmos_hardsuit
+ cost = 600
+ unit_name = "atmos hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/engine/atmos)
+
+/datum/export/gear/engi_hardsuit
+ cost = 1000
+ unit_name = "elite engine hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/engine/elite)
+
+/datum/export/gear/mining_hardsuit
+ cost = 350 //common
+ unit_name = "mining hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/mining)
+
+/datum/export/gear/sec_hardsuit
+ cost = 750
+ unit_name = "sec hardsuit"
+ export_types = list(/obj/item/clothing/head/helmet/space/hardsuit/mining, /obj/item/clothing/head/helmet/space/hardsuit/syndi/owl)
+
+/datum/export/gear/syndi_hardsuit
+ cost = 1250
+ unit_name = "syndi hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/syndi)
+
+/datum/export/gear/syndi_hardsuit
+ cost = 2750
+ unit_name = "elite syndi hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/syndi/elite)
+
+/datum/export/gear/medical_hardsuit
+ cost = 350 //Not all that good
+ unit_name = "meidcal hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/medical)
+
+/datum/export/gear/rd_hardsuit
+ cost = 850 //rare
+ unit_name = "prototype hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/rd)
+
+/datum/export/gear/sec_hardsuit
+ cost = 750
+ unit_name = "sec hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/security)
+
+/datum/export/gear/command_hardsuit
+ cost = 1300
+ unit_name = "command hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/security/hos, /obj/item/clothing/suit/space/hardsuit/captain)
+
+/datum/export/gear/magic_hardsuit
+ cost = 3000
+ unit_name = "magic hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/wizard, /obj/item/clothing/suit/space/hardsuit/shielded/wizard, /obj/item/clothing/suit/space/hardsuit/cult)
+ include_subtypes = TRUE
+
+/datum/export/gear/shield_hardsuit
+ cost = 2000
+ unit_name = "shielded hardsuit"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/shielded)
+ include_subtypes = TRUE
+
+/datum/export/gear/rigs
+ cost = 2750
+ unit_name = "RIG"
+ export_types = list(/obj/item/clothing/suit/space/hardsuit/ancient, /obj/item/clothing/suit/space/hardsuit/ancient/mason)
+
+//Soft Suits
+
+//Blanket
+datum/export/gear/space/helmet
+ cost = 55
unit_name = "space helmet"
- export_types = list(/obj/item/clothing/head/helmet/space, /obj/item/clothing/head/helmet/space/eva, /obj/item/clothing/head/helmet/space/nasavoid)
- include_subtypes = FALSE
+ export_types = list(/obj/item/clothing/head/helmet/space)
+ include_subtypes = TRUE
/datum/export/gear/space/suit
- cost = 150
+ cost = 60
unit_name = "space suit"
- export_types = list(/obj/item/clothing/suit/space, /obj/item/clothing/suit/space/eva, /obj/item/clothing/suit/space/nasavoid)
- include_subtypes = FALSE
+ export_types = list(/obj/item/clothing/suit/space)
+ include_subtypes = TRUE
+datum/export/gear/space/helmet/plasma
+ cost = 100
+ unit_name = "plasmaman space helmet"
+ export_types = list(/obj/item/clothing/suit/space/eva/plasmaman)
-/datum/export/gear/space/syndiehelmet
- cost = 150
- unit_name = "Syndicate space helmet"
+/datum/export/gear/space/suit/plasma
+ cost = 100
+ unit_name = "plasmaman space suit"
+ export_types = list(/obj/item/clothing/suit/space/eva/plasmaman)
+
+datum/export/gear/space/helmet/synda
+ cost = 150 //Flash proof
+ unit_name = "syndicate space helmet"
export_types = list(/obj/item/clothing/head/helmet/space/syndicate)
+ include_subtypes = TRUE
-/datum/export/gear/space/syndiesuit
- cost = 300
- unit_name = "Syndicate space suit"
- export_types = list(/obj/item/clothing/suit/space/syndicate)
+/datum/export/gear/space/suit/synda
+ cost = 150
+ unit_name = "syndicate space suit"
+ export_types = list(/obj/item/clothing/head/helmet/space/syndicate)
+ include_subtypes = TRUE
+//Glasses
+
+//Blanket
+datum/export/gear/glasses //glasses are not worth selling
+ cost = 3
+ unit_name = "glasses"
+ export_types = list(/obj/item/clothing/glasses)
+ include_subtypes = TRUE
+
+/datum/export/gear/mesons
+ cost = 6
+ unit_name = "mesons"
+ export_types = list(/obj/item/clothing/glasses/meson, /obj/item/clothing/glasses/material/mining)
+ include_subtypes = TRUE
+
+/datum/export/gear/scigoggles
+ cost = 8
+ unit_name = "chem giggles"
+ export_types = list(/obj/item/clothing/glasses/science)
+ include_subtypes = TRUE
+
+/datum/export/gear/nvgoggles
+ cost = 20
+ unit_name = "night vison giggles"
+ export_types = list(/obj/item/clothing/glasses/night)
+ include_subtypes = TRUE
+
+/datum/export/gear/sunglasses
+ cost = 12
+ unit_name = "sunglasses"
+ export_types = list(/obj/item/clothing/glasses/sunglasses)
+ include_subtypes = TRUE
+
+/datum/export/gear/huds
+ cost = 10
+ unit_name = "huds"
+ export_types = list(/obj/item/clothing/glasses/hud)
+ include_subtypes = TRUE
+
+/datum/export/gear/huds/glasses
+ cost = 22
+ export_types = list(/obj/item/clothing/glasses/hud/health/sunglasses, /obj/item/clothing/glasses/hud/security/sunglasses)
+
+/datum/export/gear/weldinggoggles
+ cost = 20
+ unit_name = "welding goggles"
+ export_types = list(/obj/item/clothing/glasses/welding)
+ include_subtypes = TRUE
+
+/datum/export/gear/thermals
+ cost = 30
+ unit_name = "heat seeing goggles"
+ export_types = list(/obj/item/clothing/glasses/thermal, /obj/item/clothing/glasses/hud/toggle/thermal)
+ include_subtypes = TRUE
+
+/datum/export/gear/magic_glasses
+ cost = 140
+ unit_name = "magic goggles"
+ export_types = list(/obj/item/clothing/glasses/godeye, /obj/item/clothing/glasses/hud/health/night/cultblind, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor)
+ include_subtypes = TRUE
+
+//////////
+//UNDER///
+//////////
+
+/datum/export/gear/jumpsuit
+ cost = 3
+ unit_name = "jumpsuit"
+ k_elasticity = 1/100 //you can craft white jumpsuits, if someone does that 300 times, they deserve the 800 credits
+ export_types = list(/obj/item/clothing/under)
+ include_subtypes = TRUE
+
+/datum/export/gear/fancy_jumpsuit
+ cost = 10
+ unit_name = "fancy clothing"
+ k_elasticity = 1/90 //These will be what sells
+ export_types = list(/obj/item/clothing/under/scratch, /obj/item/clothing/under/sl_suit, /obj/item/clothing/under/rank/vice, /obj/item/clothing/under/suit_jacket, \
+ /obj/item/clothing/under/burial, /obj/item/clothing/under/skirt/black, /obj/item/clothing/under/captainparade, /obj/item/clothing/under/hosparademale, \
+ /obj/item/clothing/under/hosparadefem, /obj/item/clothing/under/assistantformal, /obj/item/clothing/under/stripeddress, /obj/item/clothing/under/redeveninggown, \
+ /obj/item/clothing/under/plaid_skirt, /obj/item/clothing/under/geisha, /obj/item/clothing/under/trek, /obj/item/clothing/under/wedding, /obj/item/clothing/under/aviatoruniform,\
+ /obj/item/clothing/under/mega, /obj/item/clothing/under/cia, /obj/item/clothing/under/casualwear, /obj/item/clothing/under/rank)
+ include_subtypes = TRUE
+
+/datum/export/gear/armored_jumpsuit
+ cost = 15
+ unit_name = "armored_jumpsuit"
+ k_elasticity = 1/90 //These will be what sells
+ export_types = list(/obj/item/clothing/under/durathread, /obj/item/clothing/under/rank/security, /obj/item/clothing/under/plasmaman, /obj/item/clothing/under/syndicate, \
+ /obj/item/clothing/under/rank/det, /obj/item/clothing/under/rank/head_of_security, /obj/item/clothing/under/rank/security/spacepol)
+ exclude_types = list(/obj/item/clothing/under/syndicate/tacticool, /obj/item/clothing/under/syndicate/tacticool/skirt)
+ include_subtypes = TRUE
+
+/datum/export/gear/jumpsuit_addon
+ cost = 12 //Few and rare as well as quick drop off of vaule
+ unit_name = "jumpsuit add on"
+ k_elasticity = 1/10
+ export_types = list(/obj/item/clothing/accessory)
+ include_subtypes = TRUE
+
+/datum/export/gear/robes_magic
+ cost = 120
+ unit_name = "magic robes"
+ export_types = list(/obj/item/clothing/suit/wizrobe, /obj/item/clothing/suit/cultrobes, /obj/item/clothing/suit/magusred, /obj/item/clothing/suit/hooded/cultrobes)
+ exclude_types = list(/obj/item/clothing/suit/wizrobe/fake)
+ include_subtypes = TRUE
+
+//Amror
+/datum/export/gear/armor
+ cost = 80
+ unit_name = "misc armor"
+ export_types = list(/obj/item/clothing/suit/armor)
+ include_subtypes = TRUE
+
+/datum/export/gear/sec_armor
+ cost = 180
+ unit_name = "sec armor"
+ export_types = list(/obj/item/clothing/suit/armor/vest/leather, /obj/item/clothing/suit/armor/bulletproof, /obj/item/clothing/suit/armor/vest/det_suit)
+ include_subtypes = TRUE
+
+/datum/export/gear/hosarmor
+ cost = 380
+ unit_name = "hos armor"
+ export_types = list(/obj/item/clothing/suit/armor/hos)
+ include_subtypes = TRUE
+
+/datum/export/gear/wardenarmor
+ cost = 280
+ unit_name = "warden armor"
+ export_types = list(/obj/item/clothing/suit/armor/vest/warden)
+ include_subtypes = TRUE
+
+/datum/export/gear/reflector
+ cost = 500
+ unit_name = "reflector armor"
+ export_types = list(/obj/item/clothing/suit/armor/laserproof)
+ include_subtypes = TRUE
+
+/datum/export/gear/heavy_armor
+ cost = 600 //REALY hard to fine/make takes lots of slimes
+ unit_name = "heavy armor"
+ export_types = list(/obj/item/clothing/suit/armor/heavy)
+ include_subtypes = TRUE
+
+/datum/export/gear/plate_armor
+ cost = 200
+ unit_name = "plate armor"
+ export_types = list(/obj/item/clothing/suit/armor/riot/knight)
+ include_subtypes = TRUE
+
+/datum/export/gear/riot_armor
+ cost = 250
+ unit_name = "riot armor"
+ export_types = list(/obj/item/clothing/suit/armor/riot)
+ include_subtypes = TRUE
+
+/datum/export/gear/bone_armor
+ cost = 50
+ unit_name = "bone armor"
+ export_types = list(/obj/item/clothing/suit/armor/bone)
+ include_subtypes = TRUE
+
+/datum/export/gear/swat_armor
+ cost = 350
+ unit_name = "swat mki armor"
+ export_types = list(/obj/item/clothing/suit/space/swat)
+ include_subtypes = TRUE
+
+/datum/export/gear/dragon_armor
+ cost = 750
+ unit_name = "drake bone armor"
+ export_types = list(/obj/item/clothing/suit/hooded/cloak/drake)
+ include_subtypes = TRUE
+
+/datum/export/gear/commandamor
+ cost = 480
+ unit_name = "command armor"
+ export_types = list(/obj/item/clothing/suit/armor/vest/capcarapace, /obj/item/clothing/suit/armor/centcom)
+ include_subtypes = TRUE
+
+/datum/export/gear/reactive_base
+ cost = 600
+ k_elasticity = 1/2 //Lets not go over board
+ unit_name = "hollow reactive armor"
+ export_types = list(/obj/item/reactive_armour_shell, /obj/item/clothing/suit/armor/reactive)
+
+/datum/export/gear/reactive_active
+ cost = 1200
+ k_elasticity = 1/3 //Lets not go over board
+ unit_name = "working reactive armor"
+ export_types = list(/obj/item/clothing/suit/armor/reactive/repulse, /obj/item/clothing/suit/armor/reactive/tesla, /obj/item/clothing/suit/armor/reactive/teleport)
+
+///////////////////////////
+//Bomb/Rad/Bio Suits/Fire//
+///////////////////////////
/datum/export/gear/radhelmet
- cost = 50
+ cost = 20
unit_name = "radsuit hood"
export_types = list(/obj/item/clothing/head/radiation)
/datum/export/gear/radsuit
- cost = 100
+ cost = 40
unit_name = "radsuit"
export_types = list(/obj/item/clothing/suit/radiation)
+/datum/export/gear/firehelmet
+ cost = 10
+ unit_name = "firesuit helmet"
+ export_types = list(/obj/item/clothing/head/hardhat/red)
+
+/datum/export/gear/fireatmos
+ cost = 120
+ unit_name = "atmos firesuit"
+ export_types = list(/obj/item/clothing/suit/fire/atmos)
+
+/datum/export/gear/firesuit
+ cost = 20
+ unit_name = "firesuit"
+ export_types = list(/obj/item/clothing/suit/fire, /obj/item/clothing/suit/fire/firefighter, /obj/item/clothing/suit/fire/heavy)
+
/datum/export/gear/biohood
- cost = 50
+ cost = 40
unit_name = "biosuit hood"
export_types = list(/obj/item/clothing/head/bio_hood)
+ include_subtypes = TRUE
/datum/export/gear/biosuit
- cost = 100
+ cost = 60
unit_name = "biosuit"
export_types = list(/obj/item/clothing/suit/bio_suit)
+ include_subtypes = TRUE
/datum/export/gear/bombhelmet
- cost = 50
+ cost = 40
unit_name = "bomb suit hood"
export_types = list(/obj/item/clothing/head/bomb_hood)
+ include_subtypes = TRUE
/datum/export/gear/bombsuit
- cost = 100
+ cost = 60
unit_name = "bomb suit"
export_types = list(/obj/item/clothing/suit/bomb_suit)
+ include_subtypes = TRUE
+
+////////////////////
+//Cloaks and Coats//
+////////////////////
+
+/datum/export/gear/cloaks
+ cost = 30
+ unit_name = "cloak"
+ export_types = list(/obj/item/clothing/neck/cloak)
+ include_subtypes = TRUE
+
+/datum/export/gear/cloaksmining
+ cost = 90
+ unit_name = "lava land cloak"
+ export_types = list(/obj/item/clothing/suit/hooded/cloak/goliath)
+ include_subtypes = TRUE
+
+/datum/export/gear/labcoats
+ cost = 15
+ unit_name = "labcoats"
+ export_types = list(/obj/item/clothing/suit/toggle/labcoat)
+ include_subtypes = TRUE
+
+/datum/export/gear/wintercoats
+ cost = 25
+ unit_name = "wintercoats"
+ export_types = list(/obj/item/clothing/suit/hooded/wintercoat)
+ include_subtypes = TRUE
+
+//////////
+//SUITS///
+//////////
+
+/datum/export/gear/suits
+ cost = 40
+ unit_name = "suit"
+ export_types = list(/obj/item/clothing/suit)
+ include_subtypes = TRUE
+
+//////////////////////
+//Chameleon Gear//////
+//////////////////////
+/datum/export/gear/chameleon //Selling a full kit is easy money for 2 tc
+ cost = 280
+ unit_name = "chameleon item"
+ export_types = list(/obj/item/clothing/head/chameleon, /obj/item/clothing/mask/chameleon, /obj/item/clothing/under/chameleon, /obj/item/clothing/suit/chameleon, /obj/item/clothing/glasses/chameleon,\
+ /obj/item/clothing/gloves/chameleon, /obj/item/clothing/head/chameleon, /obj/item/clothing/shoes/chameleon, /obj/item/storage/backpack/chameleon, \
+ /obj/item/storage/belt/chameleon, /obj/item/radio/headset/chameleon, /obj/item/pda/chameleon, /obj/item/stamp/chameleon, /obj/item/clothing/neck/cloak/chameleon)
+ include_subtypes = TRUE
\ No newline at end of file
diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm
index bf77d836fb..ce4502ba99 100644
--- a/code/modules/cargo/exports/large_objects.dm
+++ b/code/modules/cargo/exports/large_objects.dm
@@ -1,3 +1,6 @@
+/datum/export/large
+ k_elasticity = 0
+
/datum/export/large/crate
cost = 500
k_elasticity = 0
@@ -21,13 +24,13 @@
export_types = list(/obj/structure/ore_box)
/datum/export/large/crate/wood
- cost = 240
+ cost = 140
unit_name = "wooden crate"
export_types = list(/obj/structure/closet/crate/wooden)
exclude_types = list()
/datum/export/large/crate/coffin
- cost = 250//50 wooden crates cost 2000 points, and you can make 10 coffins in seconds with those planks. Each coffin selling for 250 means you can make a net gain of 500 points for wasting your time making coffins.
+ cost = 150
unit_name = "coffin"
export_types = list(/obj/structure/closet/crate/coffin)
@@ -131,104 +134,219 @@
unit_name = "security barrier"
export_types = list(/obj/item/grenade/barrier, /obj/structure/barricade/security)
+/datum/export/large/frame
+ cost = 20
+ unit_name = "structure frame"
+ export_types = list(/obj/structure/frame, /obj/structure/table_frame)
+ include_subtypes = TRUE
+
+/datum/export/large/pacman
+ cost = 125
+ unit_name = "pacman"
+ export_types = list(/obj/machinery/power/port_gen/pacman)
+
+/datum/export/large/pacman
+ cost = 150
+ unit_name = "super pacman"
+ export_types = list(/obj/machinery/power/port_gen/pacman/super)
+
+/datum/export/large/pacman
+ cost = 175
+ unit_name = "mrs super pacman"
+ export_types = list(/obj/machinery/power/port_gen/pacman/mrs)
+
+/datum/export/large/hydroponics
+ cost = 120
+ unit_name = "hydroponics tray"
+ export_types = list(/obj/machinery/hydroponics)
+
+/datum/export/large/nice_chair
+ cost = 12
+ unit_name = "Padded Chair"
+ export_types = list(/obj/structure/chair/comfy)
+
/datum/export/large/gas_canister
cost = 10 //Base cost of canister. You get more for nice gases inside.
unit_name = "Gas Canister"
export_types = list(/obj/machinery/portable_atmospherics/canister)
+
/datum/export/large/gas_canister/get_cost(obj/O)
var/obj/machinery/portable_atmospherics/canister/C = O
var/worth = 10
var/gases = C.air_contents.gases
- worth += gases[/datum/gas/bz]*4
+ worth += gases[/datum/gas/bz]*4
worth += gases[/datum/gas/stimulum]*25
worth += gases[/datum/gas/hypernoblium]*1000
- worth += gases[/datum/gas/miasma]*15
+ worth += gases[/datum/gas/miasma]*4
worth += gases[/datum/gas/tritium]*7
worth += gases[/datum/gas/pluoxium]*6
worth += gases[/datum/gas/nitryl]*30
return worth
-/datum/export/large/odysseus
+
+//////////////
+//Matstatues//
+//////////////
+
+/datum/export/large/nukestatue
+ cost = 175
+ unit_name = "Nuke statue"
+ export_types = list(/obj/structure/statue/uranium/nuke)
+
+/datum/export/large/engstatue
+ cost = 175
+ unit_name = "Engine statue"
+ export_types = list(/obj/structure/statue/uranium/eng)
+
+/datum/export/large/plasmastatue
+ cost = 720
+ unit_name = "Scientist statue"
+ export_types = list(/obj/structure/statue/plasma/scientist)
+
+/datum/export/large/hosstatue
+ cost = 225
+ unit_name = "HoS statue"
+ export_types = list(/obj/structure/statue/gold/hos)
+
+/datum/export/large/rdstatue
+ cost = 225
+ unit_name = "RD statue"
+ export_types = list(/obj/structure/statue/gold/rd)
+
+/datum/export/large/hopstatue
+ cost = 225
+ unit_name = "HoP statue"
+ export_types = list(/obj/structure/statue/gold/hop)
+
+/datum/export/large/cmostatue
+ cost = 225
+ unit_name = "CMO statue"
+ export_types = list(/obj/structure/statue/gold/cmo)
+
+/datum/export/large/cestatue
+ cost = 225
+ unit_name = "CE statue"
+ export_types = list(/obj/structure/statue/gold/ce)
+
+/datum/export/large/mdstatue
+ cost = 200
+ unit_name = "MD statue"
+ export_types = list(/obj/structure/statue/silver/md)
+
+/datum/export/large/janitorstatue
+ cost = 200
+ unit_name = "Janitor statue"
+ export_types = list(/obj/structure/statue/silver/janitor)
+
+/datum/export/large/secstatue
+ cost = 200
+ unit_name = "Sec statue"
+ export_types = list(/obj/structure/statue/silver/sec)
+
+/datum/export/large/medborgstatue
+ cost = 200
+ unit_name = "Medborg statue"
+ export_types = list(/obj/structure/statue/silver/medborg)
+
+/datum/export/large/secborgstatue
+ cost = 200
+ unit_name = "Secborg statue"
+ export_types = list(/obj/structure/statue/silver/secborg)
+
+/datum/export/large/capstatue
+ cost = 1200
+ unit_name = "Captain statue"
+ export_types = list(/obj/structure/statue/diamond/captain)
+
+/datum/export/large/aistatue
+ cost = 1200
+ unit_name = "AI statue"
+ export_types = list(/obj/structure/statue/diamond/ai1, /obj/structure/statue/diamond/ai2)
+
+/datum/export/large/clownstatue
+ cost = 2750
+ unit_name = "Clown statue"
+ export_types = list(/obj/structure/statue/bananium/clown)
+
+/datum/export/large/sandstatue
+ cost = 90 //Big cash
+ unit_name = "sandstone statue"
+ export_types = list(/obj/structure/statue/sandstone/assistant)
+
+////////////
+//MECHS/////
+////////////
+
+/datum/export/large/mech
+ include_subtypes = FALSE
+
+/datum/export/large/mech/odysseus
cost = 5500
unit_name = "working odysseus"
export_types = list(/obj/mecha/medical/odysseus)
- include_subtypes = FALSE
-/datum/export/large/ripley
+/datum/export/large/mech/ripley
cost = 6500
unit_name = "working ripley"
export_types = list(/obj/mecha/working/ripley)
- include_subtypes = FALSE
-/datum/export/large/firefighter
+/datum/export/large/mech/firefighter
cost = 9000
unit_name = "working firefighter"
export_types = list(/obj/mecha/working/ripley/firefighter)
- include_subtypes = FALSE
-/datum/export/large/gygax
+/datum/export/large/mech/gygax
cost = 19000
unit_name = "working gygax"
export_types = list(/obj/mecha/combat/gygax)
- include_subtypes = FALSE
-/datum/export/large/durand
+/datum/export/large/mech/durand
cost = 10000
unit_name = "working durand"
export_types = list(/obj/mecha/combat/durand)
- include_subtypes = FALSE
-/datum/export/large/phazon
+/datum/export/large/mech/phazon
cost = 25000 //Little over half do to needing a core
unit_name = "working phazon"
export_types = list(/obj/mecha/combat/phazon)
- include_subtypes = FALSE
-/datum/export/large/marauder
+/datum/export/large/mech/marauder
cost = 15000 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price.
unit_name = "working marauder"
export_types = list(/obj/mecha/combat/marauder)
- include_subtypes = FALSE
-/datum/export/large/deathripley
+/datum/export/large/mech/deathripley
cost = 8500 //Still a "Combat class" mech - Illegal tech as well! 165% "normal" boundy price.
unit_name = "working illegally modified"
export_types = list(/obj/mecha/working/ripley/deathripley)
- include_subtypes = FALSE
-/datum/export/large/gygaxdark
+/datum/export/large/mech/gygaxdark
cost = 28500 //Still a Combat class mech - Illegal tech as well! 150% "normal" boundy price.
unit_name = "working illegally modified gygax"
export_types = list(/obj/mecha/combat/gygax/dark)
- include_subtypes = FALSE
-/datum/export/large/oldripley
+/datum/export/large/mech/oldripley
cost = 6250 //old mech - Scrap metal ! 50% "normal" boundy price.
unit_name = "working miner ripley"
export_types = list(/obj/mecha/working/ripley/mining)
- include_subtypes = FALSE
-/datum/export/large/honk
+/datum/export/large/mech/honk
cost = 12000 //Still a "Combat class" mech - Comats bordem honk!
unit_name = "working honker"
export_types = list(/obj/mecha/combat/honker)
- include_subtypes = FALSE
-/datum/export/large/reticence
+/datum/export/large/mech/reticence
cost = 12000 //Still a "Combat class" mech - Has cloking and lethal weaponds.
unit_name = "working reticence"
export_types = list(/obj/mecha/combat/reticence)
- include_subtypes = FALSE
-/datum/export/large/seraph
+/datum/export/large/mech/seraph
cost = 25500 //Still a Combat class mech - CC tech as well! 150% "normal" boundy price.
unit_name = "working seraph"
export_types = list(/obj/mecha/combat/marauder/seraph)
- include_subtypes = FALSE
-/datum/export/large/mauler
+/datum/export/large/mech/mauler
cost = 12000 //Still a Combat class mech - CC lethal weaponds.
unit_name = "working legally modified marauder"
export_types = list(/obj/mecha/combat/marauder/mauler)
- include_subtypes = FALSE
diff --git a/code/modules/cargo/exports/manifest.dm b/code/modules/cargo/exports/manifest.dm
index d03f5a46ce..60515781f9 100644
--- a/code/modules/cargo/exports/manifest.dm
+++ b/code/modules/cargo/exports/manifest.dm
@@ -80,7 +80,7 @@
// Paper work done correctly
/datum/export/paperwork_correct
- cost = 150
+ cost = 120 // finicky number 20 x 120 = 2400 per crate
k_elasticity = 0
unit_name = "correct paperwork"
export_types = list(/obj/item/folder/paperwork_correct)
diff --git a/code/modules/cargo/exports/materials.dm b/code/modules/cargo/exports/materials.dm
index 04dc76fd52..cd11660ed8 100644
--- a/code/modules/cargo/exports/materials.dm
+++ b/code/modules/cargo/exports/materials.dm
@@ -1,4 +1,5 @@
/datum/export/material
+ k_elasticity = 0
cost = 5 // Cost per MINERAL_MATERIAL_AMOUNT, which is 2000cm3 as of April 2016.
message = "cm3 of developer's tears. Please, report this on github"
var/material_id = null
@@ -27,51 +28,56 @@
return round(amount/MINERAL_MATERIAL_AMOUNT)
-// Materials. Nothing but plasma is really worth selling. Better leave it all to RnD and sell some plasma instead.
+// Materials. Selling raw can lead to a big payout but takes a lot of work for miners to get a lot. Best to craft art/rnd gear
/datum/export/material/bananium
- cost = 1000
+ cost = 500
material_id = MAT_BANANIUM
message = "cm3 of bananium"
/datum/export/material/diamond
- cost = 500
+ cost = 250
material_id = MAT_DIAMOND
message = "cm3 of diamonds"
/datum/export/material/plasma
- cost = 200
+ cost = 100
k_elasticity = 0
material_id = MAT_PLASMA
message = "cm3 of plasma"
/datum/export/material/uranium
- cost = 100
+ cost = 50
material_id = MAT_URANIUM
message = "cm3 of uranium"
/datum/export/material/gold
- cost = 125
+ cost = 60
material_id = MAT_GOLD
message = "cm3 of gold"
/datum/export/material/silver
- cost = 50
+ cost = 25
material_id = MAT_SILVER
message = "cm3 of silver"
/datum/export/material/titanium
- cost = 125
+ cost = 60
material_id = MAT_TITANIUM
message = "cm3 of titanium"
/datum/export/material/plastitanium
- cost = 325 // plasma + titanium costs
+ cost = 165 // plasma + titanium costs
material_id = MAT_TITANIUM // code can only check for one material_id; plastitanium is half plasma, half titanium
message = "cm3 of plastitanium"
-/datum/export/material/metal
+/datum/export/material/plastic
cost = 5
+ material_id = MAT_PLASTIC
+ message = "cm3 of plastic"
+
+/datum/export/material/metal
+ cost = 3
message = "cm3 of metal"
material_id = MAT_METAL
export_types = list(
@@ -79,7 +85,7 @@
/obj/item/stack/rods, /obj/item/stack/ore, /obj/item/coin)
/datum/export/material/glass
- cost = 5
+ cost = 3
message = "cm3 of glass"
material_id = MAT_GLASS
export_types = list(/obj/item/stack/sheet/glass, /obj/item/stack/ore,
diff --git a/code/modules/cargo/exports/orgains_robotics.dm b/code/modules/cargo/exports/orgains_robotics.dm
new file mode 100644
index 0000000000..924d27c1d2
--- /dev/null
+++ b/code/modules/cargo/exports/orgains_robotics.dm
@@ -0,0 +1,141 @@
+// Orgains and Robotics exports. Hearts, new lims, implants, etc.
+
+/datum/export/robotics
+ include_subtypes = FALSE
+ k_elasticity = 0 //ALWAYS worth selling upgrades
+
+/datum/export/implant
+ include_subtypes = FALSE
+ k_elasticity = 0 //ALWAYS worth selling upgrades
+
+/datum/export/orgains
+ include_subtypes = TRUE
+ k_elasticity = 0 //ALWAYS worth selling orgains
+
+/datum/export/implant/autodoc
+ cost = 150
+ unit_name = "autsurgeon"
+ export_types = list(/obj/item/autosurgeon)
+ include_subtypes = TRUE
+
+/datum/export/implant/implant
+ cost = 50
+ unit_name = "implant"
+ export_types = list(/obj/item/implant)
+ include_subtypes = TRUE
+
+/datum/export/implant/cnsreboot
+ cost = 350
+ unit_name = "anti drop implant"
+ export_types = list(/obj/item/organ/cyberimp/brain/anti_drop)
+
+/datum/export/implant/antistun
+ cost = 450
+ unit_name = "rebooter implant"
+ export_types = list(/obj/item/organ/cyberimp/brain/anti_stun)
+
+/datum/export/implant/breathtube
+ cost = 150
+ unit_name = "breath implant"
+ export_types = list(/obj/item/organ/cyberimp/mouth/breathing_tube)
+
+/datum/export/implant/hungerbgone
+ cost = 200
+ unit_name = "nutriment implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/nutriment)
+
+/datum/export/implant/hungerbgoneplus
+ cost = 300
+ unit_name = "upgraded nutriment implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/nutriment/plus)
+
+/datum/export/implant/reviver
+ cost = 350
+ unit_name = "reviver implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/reviver)
+
+/datum/export/implant/thrusters
+ cost = 150
+ unit_name = "thrusters set implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/thrusters)
+
+/datum/export/implant/thrusters
+ cost = 150
+ unit_name = "thrusters set implant"
+ export_types = list(/obj/item/organ/cyberimp/chest/thrusters)
+
+/datum/export/implant/arm
+ cost = 200
+ unit_name = "arm set implant"
+ export_types = list(/obj/item/organ/cyberimp/arm/toolset, /obj/item/organ/cyberimp/arm/surgery)
+ include_subtypes = TRUE
+
+/datum/export/implant/combatarm
+ cost = 800
+ unit_name = "combat arm set implant"
+ export_types = list(/obj/item/organ/cyberimp/arm/gun/laser, /obj/item/organ/cyberimp/arm/gun/taser, /obj/item/organ/cyberimp/arm/esword, /obj/item/organ/cyberimp/arm/medibeam, /obj/item/organ/cyberimp/arm/combat, /obj/item/organ/cyberimp/arm/flash, /obj/item/organ/cyberimp/arm/baton)
+ include_subtypes = TRUE
+
+/datum/export/orgains/heart
+ cost = 250
+ unit_name = "heart"
+ export_types = list(/obj/item/organ/heart)
+ exclude_types = list(/obj/item/organ/heart/cursed, /obj/item/organ/heart/cybernetic)
+
+/datum/export/orgains/tongue
+ cost = 75
+ unit_name = "tongue"
+ export_types = list(/obj/item/organ/tongue)
+
+/datum/export/orgains/eyes
+ cost = 50 //So many things take your eyes out anyways
+ unit_name = "eyes"
+ export_types = list(/obj/item/organ/eyes)
+ exclude_types = list(/obj/item/organ/eyes/robotic)
+
+/datum/export/orgains/stomach
+ cost = 50 //can be replaced
+ unit_name = "stomach"
+ export_types = list(/obj/item/organ/stomach)
+
+/datum/export/orgains/lungs
+ cost = 150
+ unit_name = "lungs"
+ export_types = list(/obj/item/organ/lungs)
+ exclude_types = list(/obj/item/organ/lungs/cybernetic, /obj/item/organ/lungs/cybernetic/upgraded)
+
+/datum/export/orgains/liver
+ cost = 175
+ unit_name = "liver"
+ export_types = list(/obj/item/organ/liver)
+ exclude_types = list(/obj/item/organ/liver/cybernetic, /obj/item/organ/liver/cybernetic/upgraded)
+
+/datum/export/orgains/tail //Shhh
+ cost = 500
+ unit_name = "error shipment failer"
+ export_types = list(/obj/item/organ/tail)
+
+/datum/export/orgains/vocal_cords
+ cost = 500
+ unit_name = "vocal cords"
+ export_types = list(/obj/item/organ/vocal_cords) //These are gotten via different races
+
+/datum/export/robotics/lims
+ cost = 30
+ unit_name = "robotic lim replacement"
+ export_types = list(/obj/item/bodypart/l_arm/robot, /obj/item/bodypart/r_arm/robot, /obj/item/bodypart/l_leg/robot, /obj/item/bodypart/r_leg/robot, /obj/item/bodypart/chest/robot, /obj/item/bodypart/head/robot)
+
+/datum/export/robotics/surpluse
+ cost = 40
+ unit_name = "robotic lim replacement"
+ export_types = list(/obj/item/bodypart/l_arm/robot/surplus, /obj/item/bodypart/r_arm/robot/surplus, /obj/item/bodypart/l_leg/robot/surplus, /obj/item/bodypart/r_leg/robot/surplus)
+
+/datum/export/robotics/surplus_upgraded
+ cost = 50
+ unit_name = "upgraded robotic lim replacement"
+ export_types = list(/obj/item/bodypart/l_arm/robot/surplus_upgraded, /obj/item/bodypart/r_arm/robot/surplus_upgraded, /obj/item/bodypart/l_leg/robot/surplus_upgraded, /obj/item/bodypart/r_leg/robot/surplus_upgraded)
+
+/datum/export/robotics/surgery_gear_basic
+ cost = 5
+ unit_name = "surgery tool"
+ export_types = list(/obj/item/retractor, /obj/item/hemostat, /obj/item/cautery, /obj/item/surgicaldrill, /obj/item/scalpel, /obj/item/circular_saw, /obj/item/surgical_drapes)
diff --git a/code/modules/cargo/exports/parts.dm b/code/modules/cargo/exports/parts.dm
index e6fda5f6b1..b505bb5da4 100644
--- a/code/modules/cargo/exports/parts.dm
+++ b/code/modules/cargo/exports/parts.dm
@@ -6,16 +6,96 @@
export_types = list(/obj/item/solar_assembly)
/datum/export/solar/tracker_board
- cost = 100
+ cost = 30
unit_name = "solar tracker board"
export_types = list(/obj/item/electronics/tracker)
/datum/export/solar/control_board
- cost = 150
+ cost = 75
unit_name = "solar panel control board"
export_types = list(/obj/item/circuitboard/computer/solar_control)
/datum/export/swarmer
- cost = 2000
+ cost = 500
unit_name = "deactivated alien deconstruction drone"
export_types = list(/obj/item/deactivated_swarmer)
+
+//Board
+
+/datum/export/board
+ cost = 5
+ unit_name = "circuit board"
+ export_types = list(/obj/item/circuitboard)
+ include_subtypes = TRUE
+
+/datum/export/board/SMES
+ cost = 20
+ k_elasticity = 1/2 //Only a few
+ unit_name = "smes board"
+ export_types = list(/obj/item/circuitboard/machine/smes)
+
+//Stock Parts
+
+/datum/export/subspace
+ cost = 3
+ unit_name = "subspace part"
+ export_types = list(/obj/item/stock_parts/subspace)
+ include_subtypes = TRUE
+
+/datum/export/t1
+ cost = 1
+ unit_name = "basic stock part"
+ export_types = list(/obj/item/stock_parts/capacitor, /obj/item/stock_parts/scanning_module, /obj/item/stock_parts/manipulator, /obj/item/stock_parts/micro_laser, /obj/item/stock_parts/matter_bin)
+
+/datum/export/t2
+ cost = 2
+ unit_name = "upgraded stock part"
+ export_types = list(/obj/item/stock_parts/capacitor/adv, /obj/item/stock_parts/scanning_module/adv, /obj/item/stock_parts/manipulator/nano, /obj/item/stock_parts/micro_laser/high, /obj/item/stock_parts/matter_bin/adv)
+
+/datum/export/t3
+ cost = 3
+ unit_name = "advanced stock part"
+ export_types = list(/obj/item/stock_parts/capacitor/super, /obj/item/stock_parts/scanning_module/phasic, /obj/item/stock_parts/manipulator/pico, /obj/item/stock_parts/micro_laser/ultra, /obj/item/stock_parts/matter_bin/super)
+
+/datum/export/t4
+ cost = 4
+ unit_name = "blue space stock part"
+ export_types = list(/obj/item/stock_parts/capacitor/quadratic, /obj/item/stock_parts/scanning_module/triphasic, /obj/item/stock_parts/manipulator/femto, /obj/item/stock_parts/micro_laser/quadultra, /obj/item/stock_parts/matter_bin/bluespace)
+
+//Cells
+
+/datum/export/cell
+ cost = 5
+ unit_name = "power cell"
+ export_types = list(/obj/item/stock_parts/cell)
+ include_subtypes = TRUE
+
+/datum/export/cell
+ cost = 10
+ unit_name = "upgraded power cell"
+ export_types = list(/obj/item/stock_parts/cell/upgraded, /obj/item/stock_parts/cell/upgraded/plus)
+
+/datum/export/cellhigh
+ cost = 15
+ unit_name = "high power cell"
+ export_types = list(/obj/item/stock_parts/cell/high, /obj/item/stock_parts/cell/high/plus)
+
+/datum/export/cellhyper
+ cost = 20
+ unit_name = "super-capacity power cell"
+ export_types = list(/obj/item/stock_parts/cell/super, /obj/item/stock_parts/cell/hyper)
+
+/datum/export/cellbs
+ cost = 25
+ unit_name = "bluespace power cell"
+ export_types = list(/obj/item/stock_parts/cell/bluespace)
+
+/datum/export/cellyellow
+ cost = 40
+ unit_name = "slime power cell"
+ export_types = list(/obj/item/stock_parts/cell/high/slime)
+
+/datum/export/cellyellowhyper
+ cost = 120 //Takes a lot to make and is really good
+ unit_name = "hyper slime power cell"
+ export_types = list(/obj/item/stock_parts/cell/high/slime/hypercharged)
\ No newline at end of file
diff --git a/code/modules/cargo/exports/sheets.dm b/code/modules/cargo/exports/sheets.dm
index 708eb34133..8397a7dc1f 100644
--- a/code/modules/cargo/exports/sheets.dm
+++ b/code/modules/cargo/exports/sheets.dm
@@ -1,5 +1,6 @@
/datum/export/stack
unit_name = "sheet"
+ k_elasticity = 0
/datum/export/stack/get_amount(obj/O)
var/obj/item/stack/S = O
@@ -9,47 +10,52 @@
// Hides
+/datum/export/stack/leather
+ cost = 30
+ unit_name = "leather"
+ export_types = list(/obj/item/stack/sheet/leather)
+
/datum/export/stack/skin/monkey
- cost = 50
+ cost = 30
unit_name = "monkey hide"
export_types = list(/obj/item/stack/sheet/animalhide/monkey)
/datum/export/stack/skin/human
- cost = 100
+ cost = 70
export_category = EXPORT_CONTRABAND
unit_name = "piece"
message = "of human skin"
export_types = list(/obj/item/stack/sheet/animalhide/human)
/datum/export/stack/skin/goliath_hide
- cost = 200
+ cost = 160
unit_name = "goliath hide"
export_types = list(/obj/item/stack/sheet/animalhide/goliath_hide)
/datum/export/stack/skin/cat
- cost = 150
+ cost = 120
export_category = EXPORT_CONTRABAND
unit_name = "cat hide"
export_types = list(/obj/item/stack/sheet/animalhide/cat)
/datum/export/stack/skin/corgi
- cost = 200
+ cost = 140
export_category = EXPORT_CONTRABAND
unit_name = "corgi hide"
export_types = list(/obj/item/stack/sheet/animalhide/corgi)
/datum/export/stack/skin/lizard
- cost = 150
+ cost = 50
unit_name = "lizard hide"
export_types = list(/obj/item/stack/sheet/animalhide/lizard)
/datum/export/stack/skin/gondola
- cost = 5000
+ cost = 1000
unit_name = "gondola hide"
export_types = list(/obj/item/stack/sheet/animalhide/gondola)
/datum/export/stack/skin/xeno
- cost = 500
+ cost = 300
unit_name = "alien hide"
export_types = list(/obj/item/stack/sheet/animalhide/xeno)
@@ -57,23 +63,23 @@
// For base materials, see materials.dm
/datum/export/stack/plasteel
- cost = 155 // 2000u of plasma + 2000u of metal.
+ cost = 105 // 2000u of plasma + 2000u of metal.
message = "of plasteel"
export_types = list(/obj/item/stack/sheet/plasteel)
// 1 glass + 0.5 metal, cost is rounded up.
/datum/export/stack/rglass
- cost = 8
+ cost = 6
message = "of reinforced glass"
export_types = list(/obj/item/stack/sheet/rglass)
/datum/export/stack/bscrystal
- cost = 300
+ cost = 150
message = "of bluespace crystals"
export_types = list(/obj/item/stack/sheet/bluespace_crystal)
/datum/export/stack/wood
- cost = 30
+ cost = 15
unit_name = "wood plank"
export_types = list(/obj/item/stack/sheet/mineral/wood)
@@ -93,16 +99,50 @@
unit_name = "cable piece"
export_types = list(/obj/item/stack/cable_coil)
+/datum/export/stack/cloth
+ cost = 10
+ unit_name = "sheets"
+ message = "of cloth"
+ export_types = list(/obj/item/stack/sheet/cloth)
+
+/datum/export/stack/duracloth
+ cost = 40
+ unit_name = "sheets"
+ message = "of duracloth"
+ export_types = list(/obj/item/stack/sheet/durathread)
+
// Weird Stuff
/datum/export/stack/abductor
- cost = 1000
+ cost = 400
message = "of alien alloy"
export_types = list(/obj/item/stack/sheet/mineral/abductor)
/datum/export/stack/adamantine
unit_name = "bar"
- cost = 500
+ cost = 250
message = "of adamantine"
export_types = list(/obj/item/stack/sheet/mineral/adamantine)
+/datum/export/stack/bone
+ cost = 20
+ message = "of bones"
+ export_types = list(/obj/item/stack/sheet/bone)
+
+/datum/export/stack/bronze
+ unit_name = "tiles"
+ cost = 5
+ message = "of brozne"
+ export_types = list(/obj/item/stack/tile/bronze)
+
+/datum/export/stack/brass
+ unit_name = "tiles"
+ cost = 50
+ message = "of brass"
+ export_types = list(/obj/item/stack/tile/brass)
+
+/datum/export/stack/paper
+ unit_name = "sheets"
+ cost = 30
+ message = "of paperframes"
+ export_types = list(/obj/item/stack/sheet/paperframes)
\ No newline at end of file
diff --git a/code/modules/cargo/exports/tools.dm b/code/modules/cargo/exports/tools.dm
index 9e58e4ba95..4984bfe9b9 100644
--- a/code/modules/cargo/exports/tools.dm
+++ b/code/modules/cargo/exports/tools.dm
@@ -1,5 +1,5 @@
/datum/export/toolbox
- cost = 4
+ cost = 6
unit_name = "toolbox"
export_types = list(/obj/item/storage/toolbox)
@@ -8,7 +8,80 @@
// electrical toolbox: 36cr
// robust: priceless
+// Adv tools
+
+/datum/export/gear/powerdrill
+ cost = 25
+ k_elasticity = 1/40 //Market can only take so much
+ unit_name = "power tool"
+ export_types = list(/obj/item/crowbar/power, /obj/item/screwdriver/power, \
+ /obj/item/weldingtool/experimental, /obj/item/wirecutters/power, /obj/item/wrench/power)
+ include_subtypes = TRUE
+
+/datum/export/gear/advtool
+ cost = 175
+ k_elasticity = 0 //Only known to be made by 2 station, market is hungery for it
+ unit_name = "adv tool"
+ export_types = list(/obj/item/crowbar/advanced, /obj/item/crowbar/abductor, /obj/item/screwdriver/abductor, /obj/item/screwdriver/advanced, \
+ /obj/item/weldingtool/abductor, /obj/item/weldingtool/advanced, /obj/item/wirecutters/abductor, /obj/item/wirecutters/advanced, \
+ /obj/item/wrench/abductor, /obj/item/wrench/advanced)
+ include_subtypes = TRUE
+
+// Lights/Eletronic
+
+/datum/export/lights
+ cost = 10
+ unit_name = "light fixer"
+ export_types = list(/obj/item/wallframe/light_fixture)
+ include_subtypes = TRUE
+
+/datum/export/apc_board
+ cost = 5
+ unit_name = "apc electronics"
+ export_types = list(/obj/item/electronics/apc)
+ include_subtypes = TRUE
+
+/datum/export/apc_frame
+ cost = 3
+ unit_name = "apc frame"
+ export_types = list(/obj/item/wallframe/apc)
+ include_subtypes = TRUE
+
+/datum/export/floodlights
+ cost = 15
+ unit_name = "floodlight fixer"
+ export_types = list(/obj/structure/floodlight_frame)
+ include_subtypes = TRUE
+
+/datum/export/bolbstubes
+ cost = 1 //Time
+ unit_name = "light replacement"
+ export_types = list(/obj/item/light/tube, /obj/item/light/bulb)
+
+/datum/export/lightreplacer
+ cost = 20
+ unit_name = "lightreplacer"
+ export_types = list(/obj/item/lightreplacer)
+
// Basic tools
+/datum/export/basicmining
+ cost = 20
+ unit_name = "basic mining tool"
+ export_types = list(/obj/item/pickaxe, /obj/item/pickaxe/mini, /obj/item/shovel, /obj/item/resonator)
+ include_subtypes = FALSE
+
+/datum/export/upgradedmining
+ cost = 50
+ unit_name = "mining tool"
+ export_types = list(/obj/item/pickaxe/silver, /obj/item/pickaxe/drill, /obj/item/gun/energy/plasmacutter, /obj/item/resonator/upgraded)
+ include_subtypes = FALSE
+
+/datum/export/advdmining
+ cost = 150
+ unit_name = "advanced mining tool"
+ export_types = list(/obj/item/pickaxe/diamond, /obj/item/pickaxe/drill/diamonddrill, /obj/item/pickaxe/drill/jackhammer, /obj/item/gun/energy/plasmacutter/adv)
+ include_subtypes = FALSE
+
/datum/export/screwdriver
cost = 2
unit_name = "screwdriver"
@@ -31,7 +104,6 @@
message = "of wirecutters"
export_types = list(/obj/item/wirecutters)
-
/datum/export/weldingtool
cost = 5
unit_name = "welding tool"
@@ -48,9 +120,8 @@
unit_name = "industrial welding tool"
export_types = list(/obj/item/weldingtool/largetank, /obj/item/weldingtool/hugetank)
-
/datum/export/extinguisher
- cost = 15
+ cost = 10
unit_name = "fire extinguisher"
export_types = list(/obj/item/extinguisher)
include_subtypes = FALSE
@@ -60,9 +131,8 @@
unit_name = "pocket fire extinguisher"
export_types = list(/obj/item/extinguisher/mini)
-
/datum/export/flashlight
- cost = 5
+ cost = 3
unit_name = "flashlight"
export_types = list(/obj/item/flashlight)
include_subtypes = FALSE
@@ -73,11 +143,10 @@
export_types = list(/obj/item/flashlight/flare)
/datum/export/flashlight/seclite
- cost = 10
+ cost = 5
unit_name = "seclite"
export_types = list(/obj/item/flashlight/seclite)
-
/datum/export/analyzer
cost = 5
unit_name = "analyzer"
@@ -88,14 +157,12 @@
unit_name = "t-ray scanner"
export_types = list(/obj/item/t_scanner)
-
/datum/export/radio
cost = 5
unit_name = "radio"
export_types = list(/obj/item/radio)
exclude_types = list(/obj/item/radio/mech)
-
/datum/export/rcd
cost = 100
unit_name = "rapid construction device"
@@ -111,6 +178,21 @@
unit_name = "rapid piping device"
export_types = list(/obj/item/pipe_dispenser)
+/datum/export/rld
+ cost = 150
+ unit_name = "rapid light device"
+ export_types = list(/obj/item/construction/rld)
+
+/datum/export/rped
+ cost = 100
+ unit_name = "rapid part exchange device"
+ export_types = list(/obj/item/storage/part_replacer)
+
+/datum/export/bsrped
+ cost = 200
+ unit_name = "blue space part exchange device"
+ export_types = list(/obj/item/storage/part_replacer/bluespace)
+
/datum/export/singulo //failsafe in case someone decides to ship a live singularity to CentCom without the corresponding bounty
cost = 1
unit_name = "singularity"
diff --git a/code/modules/cargo/exports/weapons.dm b/code/modules/cargo/exports/weapons.dm
index bad221c3ac..97dd9c10aa 100644
--- a/code/modules/cargo/exports/weapons.dm
+++ b/code/modules/cargo/exports/weapons.dm
@@ -3,6 +3,26 @@
/datum/export/weapon
include_subtypes = FALSE
+/datum/export/weapon/makeshift_shield
+ cost = 30
+ unit_name = "unknown shield"
+ export_types = list(/obj/item/shield/riot, /obj/item/shield/riot/roman, /obj/item/shield/riot/buckler, /obj/item/shield/makeshift)
+
+/datum/export/weapon/riot_shield
+ cost = 50
+ unit_name = "riot shield"
+ export_types = list(/obj/item/shield/riot, /obj/item/shield/riot/tower)
+
+/datum/export/weapon/riot_shield
+ cost = 70
+ unit_name = "flash shield"
+ export_types = list(/obj/item/assembly/flash/shield)
+
+/datum/export/weapon/tele_shield
+ cost = 100
+ unit_name = "tele shield"
+ export_types = list(/obj/item/shield/riot/tele, /obj/item/shield/energy)
+
/datum/export/weapon/baton
cost = 100
unit_name = "stun baton"
@@ -15,7 +35,6 @@
unit_name = "combat knife"
export_types = list(/obj/item/kitchen/knife/combat)
-
/datum/export/weapon/taser
cost = 200
unit_name = "advanced taser"
@@ -27,26 +46,25 @@
export_types = list(/obj/item/gun/energy/laser)
/datum/export/weapon/disabler
- cost = 100
+ cost = 50
unit_name = "disabler"
export_types = list(/obj/item/gun/energy/disabler)
/datum/export/weapon/energy_gun
- cost = 300
+ cost = 200
unit_name = "energy gun"
export_types = list(/obj/item/gun/energy/e_gun)
/datum/export/weapon/wt550
- cost = 300
+ cost = 130
unit_name = "WT-550 automatic rifle"
export_types = list(/obj/item/gun/ballistic/automatic/wt550)
/datum/export/weapon/shotgun
- cost = 300
+ cost = 200
unit_name = "combat shotgun"
export_types = list(/obj/item/gun/ballistic/shotgun/automatic/combat)
-
/datum/export/weapon/flashbang
cost = 5
unit_name = "flashbang grenade"
@@ -57,7 +75,6 @@
unit_name = "tear gas grenade"
export_types = list(/obj/item/grenade/chem_grenade/teargas)
-
/datum/export/weapon/flash
cost = 5
unit_name = "handheld flash"
@@ -69,3 +86,271 @@
unit_name = "pair"
message = "of handcuffs"
export_types = list(/obj/item/restraints/handcuffs)
+
+//////////////
+//RND Guns////
+//////////////
+
+/datum/export/weapon/lasercarbine
+ cost = 120
+ unit_name = "laser carbine"
+ export_types = list(/obj/item/gun/energy/laser/carbine)
+ include_subtypes = TRUE
+
+/datum/export/weapon/teslagun
+ cost = 130
+ unit_name = "tesla revolver"
+ export_types = list(/obj/item/gun/energy/tesla_revolver)
+
+/datum/export/weapon/aeg
+ cost = 200 //Endless power
+ unit_name = "advance engery gun"
+ export_types = list(/obj/item/gun/energy/e_gun/nuclear)
+
+/datum/export/weapon/deconer
+ cost = 600
+ unit_name = "deconer"
+ export_types = list(/obj/item/gun/energy/decloner)
+
+/datum/export/weapon/ntsniper
+ cost = 500
+ unit_name = "beam rifle"
+ export_types = list(/obj/item/gun/energy/beam_rifle)
+
+/datum/export/weapon/needle_gun
+ cost = 50
+ unit_name = "syringe revolver"
+ export_types = list(/obj/item/gun/syringe/rapidsyringe)
+
+/datum/export/weapon/temp_gun
+ cost = 175 //Its just smaller
+ unit_name = "small temperature gun"
+ k_elasticity = 1/5 //Its just a smaller temperature gun, easy to mass make
+ export_types = list(/obj/item/gun/energy/temperature)
+
+/datum/export/weapon/flowergun
+ cost = 100
+ unit_name = "floral somatoray"
+ export_types = list(/obj/item/gun/energy/floragun)
+
+/datum/export/weapon/xraygun
+ cost = 300 //Wall hacks
+ unit_name = "x ray gun"
+ export_types = list(/obj/item/gun/energy/xray)
+
+/datum/export/weapon/ioncarbine
+ cost = 200
+ k_elasticity = 1/5 //Its just a smaller temperature gun, easy to mass make
+ unit_name = "ion carbine"
+ export_types = list(/obj/item/gun/energy/ionrifle/carbine)
+
+/datum/export/weapon/largeebow
+ cost = 500
+ unit_name = "crossbow"
+ export_types = list(/obj/item/gun/energy/kinetic_accelerator/crossbow/large)
+
+/datum/export/weapon/largebomb
+ cost = 20
+ unit_name = "large grenade"
+ export_types = list(/obj/item/grenade/chem_grenade/large)
+
+/datum/export/weapon/gravworm
+ cost = 150
+ unit_name = "bluespace weapon"
+ export_types = list(/obj/item/gun/energy/wormhole_projector, /obj/item/gun/energy/gravity_gun)
+
+/datum/export/weapon/cryopryo
+ cost = 70
+ unit_name = "heat based grenade"
+ export_types = list(/obj/item/grenade/chem_grenade/pyro, /obj/item/grenade/chem_grenade/cryo)
+
+/datum/export/weapon/advgrenade
+ cost = 80
+ unit_name = "advanced grenade"
+ export_types = list(/obj/item/grenade/chem_grenade/adv_release)
+
+/////////////////
+//Ammo and Pins//
+/////////////////
+
+/datum/export/weapon/wtammo
+ cost = 10
+ unit_name = "WT-550 automatic rifle ammo"
+ export_types = list(/obj/item/ammo_box/magazine/wt550m9, /obj/item/ammo_box/magazine/wt550m9/wtrubber)
+
+/datum/export/weapon/wtammo/advanced
+ cost = 30
+ unit_name = "advanced WT-550 automatic rifle ammo"
+ export_types = list( /obj/item/ammo_box/magazine/wt550m9/wtap, /obj/item/ammo_box/magazine/wt550m9/wttx, /obj/item/ammo_box/magazine/wt550m9/wtic)
+
+/datum/export/weapon/mindshield
+ cost = 80
+ unit_name = "mindshield locked pin"
+ export_types = list(/obj/item/firing_pin/implant/mindshield)
+
+/datum/export/weapon/testrange
+ cost = 20
+ unit_name = "test range pin"
+ export_types = list(/obj/item/firing_pin/test_range)
+
+/datum/export/weapon/techslug
+ cost = 15
+ k_elasticity = 0
+ unit_name = "advanced shotgun shell"
+ export_types = list(/obj/item/ammo_casing/shotgun/dragonsbreath, /obj/item/ammo_casing/shotgun/meteorslug, /obj/item/ammo_casing/shotgun/pulseslug, /obj/item/ammo_casing/shotgun/frag12, /obj/item/ammo_casing/shotgun/ion, /obj/item/ammo_casing/shotgun/laserslug)
+
+/////////////////////////
+//The Traitor Sell Outs//
+/////////////////////////
+
+/datum/export/weapon/pistol
+ cost = 120
+ unit_name = "illegal firearm"
+ export_types = list(/obj/item/gun/ballistic/automatic/pistol)
+
+/datum/export/weapon/revolver
+ cost = 200
+ unit_name = "large handgun"
+ export_types = list(/obj/item/gun/ballistic/revolver/syndie)
+
+/datum/export/weapon/rocketlauncher
+ cost = 1000
+ unit_name = "rocketlauncher"
+ export_types = list(/obj/item/gun/ballistic/rocketlauncher)
+
+/datum/export/weapon/antitank
+ cost = 300
+ unit_name = "hand cannon"
+ export_types = list(/obj/item/gun/ballistic/automatic/pistol/antitank/syndicate)
+
+/datum/export/weapon/clownstuff
+ cost = 500
+ unit_name = "clown war tech"
+ export_types = list(/obj/item/pneumatic_cannon/pie/selfcharge, /obj/item/shield/energy/bananium, /obj/item/melee/transforming/energy/sword/bananium, )
+
+/datum/export/weapon/bulldog
+ cost = 400
+ unit_name = "drum loaded shotgun"
+ export_types = list(/obj/item/gun/ballistic/automatic/shotgun/bulldog)
+
+/datum/export/weapon/smg
+ cost = 350
+ unit_name = "automatic c-20r"
+ export_types = list(/obj/item/gun/ballistic/automatic/c20r)
+
+/datum/export/weapon/duelsaber
+ cost = 360 //Get it?
+ unit_name = "energy saber"
+ export_types = list(/obj/item/twohanded/dualsaber)
+
+/datum/export/weapon/esword
+ cost = 130
+ unit_name = "energy sword"
+ export_types = list(/obj/item/melee/transforming/energy/sword/cx/traitor, /obj/item/melee/transforming/energy/sword/saber)
+
+/datum/export/weapon/rapier
+ cost = 150
+ unit_name = "rapier"
+ export_types = list(/obj/item/storage/belt/sabre/rapier)
+
+/datum/export/weapon/flamer
+ cost = 20 //welder + some rods cheap
+ unit_name = "flamethrower"
+ export_types = list(/obj/item/flamethrower)
+
+/datum/export/weapon/gloves
+ cost = 90
+ unit_name = "star struck gloves"
+ export_types = list(/obj/item/clothing/gloves/rapid)
+
+/datum/export/weapon/l6
+ cost = 500
+ unit_name = "law 6 saw"
+ export_types = list(/obj/item/gun/ballistic/automatic/l6_saw)
+
+/datum/export/weapon/m90
+ cost = 400
+ unit_name = "assault class weapon"
+ export_types = list(/obj/item/gun/ballistic/automatic/m90)
+
+/datum/export/weapon/powerglove
+ cost = 100
+ unit_name = "hydraulic glove"
+ export_types = list(/obj/item/melee/powerfist)
+
+/datum/export/weapon/sniper
+ cost = 750
+ unit_name = ".50 sniper"
+ export_types = list(/obj/item/gun/ballistic/automatic/sniper_rifle/syndicate)
+
+/datum/export/weapon/ebow
+ cost = 600
+ unit_name = "mini crossbow"
+ export_types = list(/obj/item/gun/energy/kinetic_accelerator/crossbow)
+
+/datum/export/weapon/m10mm
+ cost = 10
+ unit_name = "10mm magazine"
+ export_types = list(/obj/item/ammo_box/magazine/m10mm)
+ include_subtypes = TRUE
+
+/datum/export/weapon/dj_a_bomb
+ cost = 100
+ unit_name = "40mm shell"
+ export_types = list(/obj/item/ammo_casing/a40mm)
+
+/datum/export/weapon/point50mags
+ cost = 50
+ unit_name = ".50 magazine"
+ export_types = list(/obj/item/ammo_box/magazine/sniper_rounds)
+ include_subtypes = TRUE
+
+/datum/export/weapon/smg_mag
+ cost = 45
+ unit_name = "smg magazine"
+ export_types = list(/obj/item/ammo_box/magazine/smgm45, /obj/item/ammo_box/magazine/m556)
+
+/datum/export/weapon/l6sawammo
+ cost = 60
+ unit_name = "law 6 saw ammo box"
+ export_types = list(/obj/item/ammo_box/magazine/mm195x129)
+ include_subtypes = TRUE
+
+/datum/export/weapon/rocket
+ cost = 120
+ unit_name = "rocket"
+ export_types = list(/obj/item/ammo_casing/caseless/rocket)
+ include_subtypes = TRUE
+
+/datum/export/weapon/ninemmammo
+ cost = 20
+ unit_name = "9mm ammo magazine"
+ export_types = list(/obj/item/ammo_box/magazine/pistolm9mm)
+
+/datum/export/weapon/fletcher_ammo
+ cost = 60
+ unit_name = "illegal ammo magazines"
+ export_types = list(/obj/item/ammo_box/magazine/flechette)
+ include_subtypes = TRUE
+
+/datum/export/weapon/dj_a_pizzabomb
+ cost = -6000
+ unit_name = "Repair Costs"
+ export_types = list(/obj/item/pizzabox/bomb, /obj/item/sbeacondrop/bomb)
+
+/datum/export/weapon/real_toolbox
+ cost = 600
+ unit_name = "golden toolbox"
+ export_types = list(/obj/item/storage/toolbox/gold_real)
+
+/datum/export/weapon/melee
+ cost = 30
+ unit_name = "unlisted weapon"
+ export_types = list(/obj/item/melee)
+ include_subtypes = TRUE
+
+/datum/export/weapon/gun
+ cost = 30
+ unit_name = "unlisted weapon"
+ export_types = list(/obj/item/gun)
+ include_subtypes = TRUE
\ No newline at end of file
diff --git a/code/modules/cargo/packs.dm b/code/modules/cargo/packs.dm
index 1087f1ebb5..4c9ddfe3bc 100644
--- a/code/modules/cargo/packs.dm
+++ b/code/modules/cargo/packs.dm
@@ -1,20 +1,20 @@
/datum/supply_pack
var/name = "Crate"
var/group = ""
- var/hidden = FALSE
- var/contraband = FALSE
+ var/hidden = FALSE //Aka emag only
+ var/contraband = FALSE //Hacking the console with a multitool
var/cost = 700 // Minimum cost, or infinite points are possible.
- var/access = FALSE
- var/access_any = FALSE
- var/list/contains = null
- var/crate_name = "crate"
+ var/access = FALSE //What access does the Crate itself need?
+ var/access_any = FALSE //Do we care about access?
+ var/list/contains = null //What items are in the crate
+ var/crate_name = "crate" //The crate that comes with each order
var/desc = ""//no desc by default
- var/crate_type = /obj/structure/closet/crate
+ var/crate_type = /obj/structure/closet/crate //what kind of crate - Locked crates needed for access locked crates
var/dangerous = FALSE // Should we message admins?
var/special = FALSE //Event/Station Goals/Admin enabled packs
var/special_enabled = FALSE
- var/DropPodOnly = FALSE//only usable by the Bluespace Drop Pod via the express cargo console
- var/admin_spawned = FALSE
+ var/DropPodOnly = FALSE //only usable by the Bluespace Drop Pod via the express cargo console
+ var/admin_spawned = FALSE //Can only an admin spawn this crate?
/datum/supply_pack/proc/generate(atom/A)
var/obj/structure/closet/crate/C = new crate_type(A)
@@ -36,2821 +36,3 @@
else
for(var/item in contains)
new item(C)
-
-// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Emergency ///////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/emergency
- group = "Emergency"
-
-/datum/supply_pack/emergency/vehicle
- name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN
- desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!"
- cost = 2000
- contraband = TRUE
- contains = list(/obj/vehicle/ridden/atv,
- /obj/item/key,
- /obj/item/clothing/suit/jacket/leather/overcoat,
- /obj/item/clothing/gloves/color/black,
- /obj/item/clothing/head/soft,
- /obj/item/clothing/mask/bandana/skull)//so you can properly #cargoniabikergang
- crate_name = "Biker Kit"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/emergency/equipment
- name = "Emergency Bot/Internals Crate"
- desc = "Explosions got you down? These supplies are guaranteed to patch up holes, in stations and people alike! Comes with two floorbots, two medbots, five oxygen masks and five small oxygen tanks."
- cost = 3500
- contains = list(/mob/living/simple_animal/bot/floorbot,
- /mob/living/simple_animal/bot/floorbot,
- /mob/living/simple_animal/bot/medbot,
- /mob/living/simple_animal/bot/medbot,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas)
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/radiatione_emergency
- name = "Emergenc Radiation Protection Crate"
- desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a few pill bottles that are able to handles radiation and the affects of the poisoning."
- cost = 2500
- contains = list(/obj/item/clothing/head/radiation,
- /obj/item/clothing/head/radiation,
- /obj/item/clothing/suit/radiation,
- /obj/item/clothing/suit/radiation,
- /obj/item/geiger_counter,
- /obj/item/geiger_counter,
- /obj/item/storage/pill_bottle/mutarad,
- /obj/item/storage/firstaid/radbgone)
- crate_name = "radiation protection crate"
- crate_type = /obj/structure/closet/crate/radiation
-
-/datum/supply_pack/emergency/rcds
- name = "Emergency RCDs"
- desc = "Bombs going off on station? SME blown and now you need to fix the hole it left behind? Well this crate has a pare of Rcds to be able to easily fix up any problem you may have!"
- cost = 1500
- contains = list(/obj/item/construction/rcd,
- /obj/item/construction/rcd)
- crate_name = "emergency rcds"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/soft_suit
- name = "Emergency Space Suit "
- desc = "Is there bombs going off left and right? Is there meteors shooting around the station? Well we have two fragile space suit for emergencys as well as air and masks."
- cost = 1000
- contains = list(/obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/fragile,
- /obj/item/clothing/suit/space/fragile,
- /obj/item/clothing/head/helmet/space/fragile,
- /obj/item/clothing/head/helmet/space/fragile)
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/firefighting
- name = "Firefighting Crate"
- desc = "Only you can prevent station fires. Partner up with two firefighter suits, gas masks, flashlights, large oxygen tanks, extinguishers, and hardhats!"
- cost = 1000
- contains = list(/obj/item/clothing/suit/fire/firefighter,
- /obj/item/clothing/suit/fire/firefighter,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/flashlight,
- /obj/item/flashlight,
- /obj/item/tank/internals/oxygen/red,
- /obj/item/tank/internals/oxygen/red,
- /obj/item/extinguisher/advanced,
- /obj/item/extinguisher/advanced,
- /obj/item/clothing/head/hardhat/red,
- /obj/item/clothing/head/hardhat/red)
- crate_name = "firefighting crate"
-
-/datum/supply_pack/emergency/atmostank
- name = "Firefighting Tank Backpack"
- desc = "Mow down fires with this high-capacity fire fighting tank backpack. Requires Atmospherics access to open."
- cost = 1000
- access = ACCESS_ATMOSPHERICS
- contains = list(/obj/item/watertank/atmos)
- crate_name = "firefighting backpack crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/emergency/internals
- name = "Internals Crate"
- desc = "Master your life energy and control your breathing with three breath masks, three emergency oxygen tanks and three large air tanks."//IS THAT A
- cost = 1000
- contains = list(/obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/breath,
- /obj/item/clothing/mask/breath,
- /obj/item/clothing/mask/breath,
- /obj/item/tank/internals/emergency_oxygen,
- /obj/item/tank/internals/emergency_oxygen,
- /obj/item/tank/internals/emergency_oxygen,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air,
- /obj/item/tank/internals/air)
- crate_name = "internals crate"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/metalfoam
- name = "Metal Foam Grenade Crate"
- desc = "Seal up those pesky hull breaches with 14 Metal Foam Grenades."
- cost = 2000
- contains = list(/obj/item/storage/box/metalfoam,
- /obj/item/storage/box/metalfoam)
- crate_name = "metal foam grenade crate"
-
-/datum/supply_pack/emergency/syndicate
- name = "NULL_ENTRY"
- desc = "(#@&^$THIS PACKAGE CONTAINS 30TC WORTH OF SOME RANDOM SYNDICATE GEAR WE HAD LYING AROUND THE WAREHOUSE. GIVE EM HELL, OPERATIVE@&!*() "
- hidden = TRUE
- cost = 20000
- contains = list()
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
- dangerous = TRUE
-
-/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
- var/crate_value = 30
- var/list/uplink_items = get_uplink_items(SSticker.mode)
- while(crate_value)
- var/category = pick(uplink_items)
- var/item = pick(uplink_items[category])
- var/datum/uplink_item/I = uplink_items[category][item]
- if(!I.surplus_nullcrates || prob(100 - I.surplus_nullcrates))
- continue
- if(crate_value < I.cost)
- continue
- crate_value -= I.cost
- new I.item(C)
-
-/datum/supply_pack/emergency/plasma_spacesuit
- name = "Plasmaman Space Envirosuits"
- desc = "Contains two space-worthy envirosuits for Plasmamen. Order now and we'll throw in two free helmets! Requires EVA access to open."
- cost = 4000
- access = ACCESS_EVA
- contains = list(/obj/item/clothing/suit/space/eva/plasmaman,
- /obj/item/clothing/suit/space/eva/plasmaman,
- /obj/item/clothing/head/helmet/space/plasmaman,
- /obj/item/clothing/head/helmet/space/plasmaman)
- crate_name = "plasmaman EVA crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/emergency/plasmaman
- name = "Plasmaman Supply Kit"
- desc = "Keep those Plasmamen alive with two sets of Plasmaman outfits. Each set contains a plasmaman jumpsuit, internals tank, and helmet."
- cost = 2000
- contains = list(/obj/item/clothing/under/plasmaman,
- /obj/item/clothing/under/plasmaman,
- /obj/item/tank/internals/plasmaman/belt/full,
- /obj/item/tank/internals/plasmaman/belt/full,
- /obj/item/clothing/head/helmet/space/plasmaman,
- /obj/item/clothing/head/helmet/space/plasmaman)
- crate_name = "plasmaman supply kit"
-
-/datum/supply_pack/emergency/radiation
- name = "Radiation Protection Crate"
- desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a bottle of vodka and some glasses too, considering the life-expectancy of people who order this."
- cost = 1000
- contains = list(/obj/item/clothing/head/radiation,
- /obj/item/clothing/head/radiation,
- /obj/item/clothing/suit/radiation,
- /obj/item/clothing/suit/radiation,
- /obj/item/geiger_counter,
- /obj/item/geiger_counter,
- /obj/item/reagent_containers/food/drinks/bottle/vodka,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
- crate_name = "radiation protection crate"
- crate_type = /obj/structure/closet/crate/radiation
-
-/datum/supply_pack/emergency/spacesuit
- name = "Space Suit Crate"
- desc = "Contains two aging suits from Space-Goodwill. Requires EVA access to open."
- cost = 3000
- access = ACCESS_EVA
- contains = list(/obj/item/clothing/suit/space,
- /obj/item/clothing/suit/space,
- /obj/item/clothing/head/helmet/space,
- /obj/item/clothing/head/helmet/space,
- /obj/item/clothing/mask/breath,
- /obj/item/clothing/mask/breath)
- crate_name = "space suit crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/emergency/spacejets
- name = "Spare EVA Jetpacks"
- desc = "Contains three EVA grade jectpaks. Requires EVA access to open."
- cost = 2000
- access = ACCESS_EVA
- contains = list(/obj/item/tank/jetpack/carbondioxide/eva,
- /obj/item/tank/jetpack/carbondioxide/eva,
- /obj/item/tank/jetpack/carbondioxide/eva)
- crate_name = "eva jetpacks crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/emergency/specialops
- name = "Special Ops Supplies"
- desc = "(*!&@#TOO CHEAP FOR THAT NULL_ENTRY, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN STILL HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$"
- hidden = TRUE
- cost = 2000
- contains = list(/obj/item/storage/box/emps,
- /obj/item/grenade/smokebomb,
- /obj/item/grenade/smokebomb,
- /obj/item/grenade/smokebomb,
- /obj/item/pen/sleepy,
- /obj/item/grenade/chem_grenade/incendiary)
- crate_name = "emergency crate"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/emergency/weedcontrol
- name = "Weed Control Crate"
- desc = "Keep those invasive species OUT. Contains a scythe, gasmask, two sprays of Plant-B-Gone, and two anti-weed chemical grenades. Warranty void if used on ambrosia. Requires Hydroponics access to open."
- cost = 1500
- access = ACCESS_HYDROPONICS
- contains = list(/obj/item/scythe,
- /obj/item/clothing/mask/gas,
- /obj/item/grenade/chem_grenade/antiweed,
- /obj/item/grenade/chem_grenade/antiweed,
- /obj/item/reagent_containers/spray/plantbgone,
- /obj/item/reagent_containers/spray/plantbgone)
- crate_name = "weed control crate"
- crate_type = /obj/structure/closet/crate/secure/hydroponics
-
-/datum/supply_pack/medical/anitvirus
- name = "Virus Containment Crate"
- desc = "Viro let out a death plague Mk II again? Someone didnt wash there hands? Old plagues born anew? Well this crate is for you! Hope you cure it before it brakes out of the station... This crate needs medical access to open and has two bio suits, a box of needles and beakers, five spaceacillin needles, and a medibot."
- cost = 3000
- access = ACCESS_MEDICAL
- contains = list(/mob/living/simple_animal/bot/medbot,
- /obj/item/clothing/head/bio_hood,
- /obj/item/clothing/head/bio_hood,
- /obj/item/clothing/suit/bio_suit,
- /obj/item/clothing/suit/bio_suit,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/reagent_containers/syringe/antiviral,
- /obj/item/storage/box/syringes,
- /obj/item/storage/box/beakers)
- crate_name = "virus containment unit crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Security ////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/security
- group = "Security"
- access = ACCESS_SECURITY
- crate_type = /obj/structure/closet/crate/secure/gear
-
-/datum/supply_pack/security/armor
- name = "Armor Crate"
- desc = "Three vests of well-rounded, decently-protective armor. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/clothing/suit/armor/vest,
- /obj/item/clothing/suit/armor/vest,
- /obj/item/clothing/suit/armor/vest)
- crate_name = "armor crate"
-
-/datum/supply_pack/security/disabler
- name = "Disabler Crate"
- desc = "Three stamina-draining disabler weapons. Requires Security access to open."
- cost = 1500
- contains = list(/obj/item/gun/energy/disabler,
- /obj/item/gun/energy/disabler,
- /obj/item/gun/energy/disabler)
- crate_name = "disabler crate"
-
-/datum/supply_pack/security/forensics
- name = "Forensics Crate"
- desc = "Stay hot on the criminal's heels with Nanotrasen's Detective Essentials(tm). Contains a forensics scanner, six evidence bags, camera, tape recorder, white crayon, and of course, a fedora. Requires Security access to open."
- cost = 2000
- contains = list(/obj/item/detective_scanner,
- /obj/item/storage/box/evidence,
- /obj/item/camera,
- /obj/item/taperecorder,
- /obj/item/toy/crayon/white,
- /obj/item/clothing/head/fedora/det_hat)
- crate_name = "forensics crate"
-
-/datum/supply_pack/security/helmets
- name = "Helmets Crate"
- desc = "Contains three standard-issue brain buckets. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/clothing/head/helmet/sec,
- /obj/item/clothing/head/helmet/sec,
- /obj/item/clothing/head/helmet/sec)
- crate_name = "helmet crate"
-
-/datum/supply_pack/security/laser
- name = "Lasers Crate"
- desc = "Contains three lethal, high-energy laser guns. Requires Security access to open."
- cost = 2000
- contains = list(/obj/item/gun/energy/laser,
- /obj/item/gun/energy/laser,
- /obj/item/gun/energy/laser)
- crate_name = "laser crate"
-
-/datum/supply_pack/security/russianclothing
- name = "Russian Surplus Clothing"
- desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!"
- contraband = TRUE
- cost = 5000 // Its basicly sec suits, good boots/gloves
- contains = list(/obj/item/clothing/suit/security/officer/russian,
- /obj/item/clothing/suit/security/officer/russian,
- /obj/item/clothing/shoes/combat,
- /obj/item/clothing/shoes/combat,
- /obj/item/clothing/head/ushanka,
- /obj/item/clothing/head/ushanka,
- /obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/gloves/combat,
- /obj/item/clothing/gloves/combat,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/mask/gas)
- crate_name = "surplus russian clothing"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/security/russianmosin
- name = "Russian Minutemen Gear"
- desc = "An old russian Minutemen crate, comes with a full russian outfit, a mosin and a stripper clip."
- contraband = TRUE
- access = FALSE
- cost = 5000 //
- contains = list(/obj/item/clothing/suit/security/officer/russian,
- /obj/item/clothing/shoes/combat,
- /obj/item/clothing/head/ushanka,
- /obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/gloves/combat,
- /obj/item/clothing/mask/gas,
- /obj/item/gun/ballistic/shotgun/boltaction,
- /obj/item/ammo_box/a762)
- crate_name = "surplus russian gear"
- crate_type = /obj/structure/closet/crate/internals
-
-/datum/supply_pack/security/sechardsuit
- name = "Sec Hardsuit"
- desc = "One Sec Hardsuit with a small air tank and mask."
- cost = 3000 // half of SWAT gear for have the armor and half the gear
- contains = list(/obj/item/clothing/suit/space/hardsuit/security,
- /obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas)
- crate_name = "sec hardsuit crate"
-
-/datum/supply_pack/security/securitybarriers
- name = "Security Barrier Grenades"
- desc = "Stem the tide with four Security Barrier grenades. Requires Security access to open."
- contains = list(/obj/item/grenade/barrier,
- /obj/item/grenade/barrier,
- /obj/item/grenade/barrier,
- /obj/item/grenade/barrier)
- cost = 2000
- crate_name = "security barriers crate"
-
-/datum/supply_pack/security/securityclothes
- name = "Security Clothing Crate"
- desc = "Contains appropriate outfits for the station's private security force. Contains outfits for the Warden, Head of Security, and two Security Officers. Each outfit comes with a rank-appropriate jumpsuit, suit, and beret. Requires Security access to open."
- cost = 3000
- contains = list(/obj/item/clothing/under/rank/security/navyblue,
- /obj/item/clothing/under/rank/security/navyblue,
- /obj/item/clothing/suit/security/officer,
- /obj/item/clothing/suit/security/officer,
- /obj/item/clothing/head/beret/sec/navyofficer,
- /obj/item/clothing/head/beret/sec/navyofficer,
- /obj/item/clothing/under/rank/warden/navyblue,
- /obj/item/clothing/suit/security/warden,
- /obj/item/clothing/head/beret/sec/navywarden,
- /obj/item/clothing/under/rank/head_of_security/navyblue,
- /obj/item/clothing/suit/security/hos,
- /obj/item/clothing/head/beret/sec/navyhos)
- crate_name = "security clothing crate"
-
-/datum/supply_pack/security/supplies
- name = "Security Supplies Crate"
- desc = "Contains seven flashbangs, seven teargas grenades, six flashes, and seven handcuffs. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/storage/box/flashbangs,
- /obj/item/storage/box/teargas,
- /obj/item/storage/box/flashes,
- /obj/item/storage/box/handcuffs)
- crate_name = "security supply crate"
-
-/datum/supply_pack/security/firingpins
- name = "Standard Firing Pins Crate"
- desc = "Upgrade your arsenal with 10 standard firing pins. Requires Security access to open."
- cost = 2000
- contains = list(/obj/item/storage/box/firingpins,
- /obj/item/storage/box/firingpins)
- crate_name = "firing pins crate"
-
-/datum/supply_pack/security/justiceinbound
- name = "Standard Justice Enforcer Crate"
- desc = "This is it. The Bee's Knees. The Creme of the Crop. The Pick of the Litter. The best of the best of the best. The Crown Jewel of Nanotrasen. The Alpha and the Omega of security headwear. Guaranteed to strike fear into the hearts of each and every criminal aboard the station. Also comes with a security gasmask. Requires Security access to open."
- cost = 6000 //justice comes at a price. An expensive, noisy price.
- contraband = TRUE
- contains = list(/obj/item/clothing/head/helmet/justice,
- /obj/item/clothing/mask/gas/sechailer)
- crate_name = "security clothing crate"
-
-/datum/supply_pack/security/baton
- name = "Stun Batons Crate"
- desc = "Arm the Civil Protection Forces with three stun batons. Batteries included. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/melee/baton/loaded,
- /obj/item/melee/baton/loaded,
- /obj/item/melee/baton/loaded)
- crate_name = "stun baton crate"
-
-/datum/supply_pack/security/taser
- name = "Taser Crate"
- desc = "From the depths of stunbased combat, this order rises above, supreme. Contains three hybrid tasers, capable of firing both electrodes and disabling shots. Requires Security access to open."
- cost = 3000
- contains = list(/obj/item/gun/energy/e_gun/advtaser,
- /obj/item/gun/energy/e_gun/advtaser,
- /obj/item/gun/energy/e_gun/advtaser)
- crate_name = "taser crate"
-
-/datum/supply_pack/security/wall_flash
- name = "Wall-Mounted Flash Crate"
- desc = "Contains four wall-mounted flashes. Requires Security access to open."
- cost = 1000
- contains = list(/obj/item/storage/box/wall_flash,
- /obj/item/storage/box/wall_flash,
- /obj/item/storage/box/wall_flash,
- /obj/item/storage/box/wall_flash)
- crate_name = "wall-mounted flash crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Armory //////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/security/armory
- group = "Armory"
- access = ACCESS_ARMORY
- crate_type = /obj/structure/closet/crate/secure/weapon
-
-/datum/supply_pack/security/armory/bulletarmor
- name = "Bulletproof Armor Crate"
- desc = "Contains three sets of bulletproof armor. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/suit/armor/bulletproof,
- /obj/item/clothing/suit/armor/bulletproof)
- crate_name = "bulletproof armor crate"
-
-/datum/supply_pack/security/armory/bullethelmets
- name = "Bulletproof Helmet Crate"
- desc = "Contains three sets of bulletproof helmets. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/head/helmet/alt,
- /obj/item/clothing/head/helmet/alt)
- crate_name = "bulletproof helmet crate"
-
-/datum/supply_pack/security/armory/chemimp
- name = "Chemical Implants Crate"
- desc = "Contains five Remote Chemical implants. Requires Armory access to open."
- cost = 2000
- contains = list(/obj/item/storage/box/chemimp)
- crate_name = "chemical implant crate"
-
-/datum/supply_pack/security/armory/combatknives
- name = "Combat Knives Crate"
- desc = "Contains three sharpened combat knives. Each knife guaranteed to fit snugly inside any Nanotrasen-standard boot. Requires Armory access to open."
- cost = 3000
- contains = list(/obj/item/kitchen/knife/combat,
- /obj/item/kitchen/knife/combat,
- /obj/item/kitchen/knife/combat)
- crate_name = "combat knife crate"
-
-/datum/supply_pack/security/armory/ballistic
- name = "Combat Shotguns Crate"
- desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, with three Shotgun Bandoliers, as well as seven buchshot and 12g shotgun slugs. Requires Armory access to open."
- cost = 8000
- contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat,
- /obj/item/gun/ballistic/shotgun/automatic/combat,
- /obj/item/gun/ballistic/shotgun/automatic/combat,
- /obj/item/storage/belt/bandolier,
- /obj/item/storage/belt/bandolier,
- /obj/item/storage/belt/bandolier,
- /obj/item/storage/box/lethalshot,
- /obj/item/storage/box/lethalslugs)
- crate_name = "combat shotguns crate"
-
-/datum/supply_pack/security/armory/dragnetgun
- name = "DRAGnet gun Crate"
- desc = "Contains two DRAGnet gun. A Dynamic Rapid-Apprehension of the Guilty net the revolution in law enforcement technology that YOU Want! Requires Armory access to open."
- cost = 3500
- contains = list(/obj/item/gun/energy/e_gun/dragnet,
- /obj/item/gun/energy/e_gun/dragnet)
- crate_name = "anti riot net guns crate"
-
-/datum/supply_pack/security/armory/energy
- name = "Energy Guns Crate"
- desc = "Contains three Energy Guns, capable of firing both nonlethal and lethal blasts of light. Requires Armory access to open."
- cost = 3500
- contains = list(/obj/item/gun/energy/e_gun,
- /obj/item/gun/energy/e_gun,
- /obj/item/gun/energy/e_gun)
- crate_name = "energy gun crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-/datum/supply_pack/security/armory/exileimp // Theres boxes in 2 lockers as well as gateway never realy being used sad
- name = "Exile Implants Crate"
- desc = "Contains five Exile implants. Requires Armory access to open."
- cost = 1000
- contains = list(/obj/item/storage/box/exileimp)
- crate_name = "exile implant crate"
-
-/datum/supply_pack/security/armory/mindshield
- name = "Mindshield Implants Crate"
- desc = "Prevent against radical thoughts with three Mindshield implants. Requires Armory access to open."
- cost = 4000
- contains = list(/obj/item/storage/lockbox/loyalty)
- crate_name = "mindshield implant crate"
-
-/datum/supply_pack/security/armory/trackingimp
- name = "Tracking Implants Crate"
- desc = "Contains four tracking implants. Requires Armory access to open."
- cost = 1000
- contains = list(/obj/item/storage/box/trackimp)
- crate_name = "tracking implant crate"
-
-/datum/supply_pack/security/armory/fire
- name = "Incendiary Weapons Crate"
- desc = "Burn, baby burn. Contains three incendiary grenades, seven incendiary slugs, three plasma canisters, and a flamethrower. Requires Brige access to open."
- cost = 1500
- access = ACCESS_HEADS
- contains = list(/obj/item/flamethrower/full,
- /obj/item/tank/internals/plasma,
- /obj/item/tank/internals/plasma,
- /obj/item/tank/internals/plasma,
- /obj/item/grenade/chem_grenade/incendiary,
- /obj/item/grenade/chem_grenade/incendiary,
- /obj/item/grenade/chem_grenade/incendiary,
- /obj/item/storage/box/fireshot)
- crate_name = "incendiary weapons crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
- dangerous = TRUE
-
-/datum/supply_pack/security/armory/miniguns
- name = "Personal Miniature Energy Guns"
- desc = "Contains three miniature energy guns. Each gun has a disabler and a lethal option. Requires Armory access to open."
- cost = 5000
- contains = list(/obj/item/gun/energy/e_gun/mini,
- /obj/item/gun/energy/e_gun/mini,
- /obj/item/gun/energy/e_gun/mini)
- crate_name = "personal energy guns crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-/datum/supply_pack/security/armory/laserarmor
- name = "Reflector Vest Crate"
- desc = "Contains two vests of highly reflective material. Each armor piece diffuses a laser's energy by over half, as well as offering a good chance to reflect the laser entirely. Requires Armory access to open."
- cost = 2000
- contains = list(/obj/item/clothing/suit/armor/laserproof,
- /obj/item/clothing/suit/armor/laserproof)
- crate_name = "reflector vest crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-/datum/supply_pack/security/armory/riotarmor
- name = "Riot Armor Crate"
- desc = "Contains three sets of heavy body armor. Advanced padding protects against close-ranged weaponry, making melee attacks feel only half as potent to the user. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/suit/armor/riot,
- /obj/item/clothing/suit/armor/riot,
- /obj/item/clothing/suit/armor/riot)
- crate_name = "riot armor crate"
-
-/datum/supply_pack/security/armory/riothelmets
- name = "Riot Helmets Crate"
- desc = "Contains three riot helmets. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/clothing/head/helmet/riot,
- /obj/item/clothing/head/helmet/riot,
- /obj/item/clothing/head/helmet/riot)
- crate_name = "riot helmets crate"
-
-/datum/supply_pack/security/armory/riotshields
- name = "Riot Shields Crate"
- desc = "For when the greytide gets really uppity. Contains three riot shields. Requires Armory access to open."
- cost = 2000
- contains = list(/obj/item/shield/riot,
- /obj/item/shield/riot,
- /obj/item/shield/riot)
- crate_name = "riot shields crate"
-
-/datum/supply_pack/security/armory/riotshotguns
- name = "Riot Shotgun Crate"
- desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open."
- cost = 6000
- contains = list(/obj/item/gun/ballistic/shotgun/riot,
- /obj/item/gun/ballistic/shotgun/riot,
- /obj/item/gun/ballistic/shotgun/riot,
- /obj/item/storage/box/rubbershot,
- /obj/item/storage/box/beanbag)
- crate_name = "riot shotgun crate"
-
-/datum/supply_pack/security/armory/swat
- name = "SWAT Crate"
- desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, mask, combat belt, and combat gloves. Requires Armory access to open."
- cost = 6000
- contains = list(/obj/item/clothing/head/helmet/swat/nanotrasen,
- /obj/item/clothing/head/helmet/swat/nanotrasen,
- /obj/item/clothing/suit/space/swat,
- /obj/item/clothing/suit/space/swat,
- /obj/item/clothing/mask/gas/sechailer/swat,
- /obj/item/clothing/mask/gas/sechailer/swat,
- /obj/item/storage/belt/military/assault,
- /obj/item/storage/belt/military/assault,
- /obj/item/clothing/gloves/combat,
- /obj/item/clothing/gloves/combat)
- crate_name = "swat crate"
-
-/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
- name = "SWAT tatical tasers Crate"
- desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
- cost = 8000
- contains = list(/obj/item/gun/energy/e_gun/stun,
- /obj/item/gun/energy/e_gun/stun)
- crate_name = "swat taser crate"
-
-/datum/supply_pack/security/armory/woodstock
- name = "Classic WoodStock Shotguns Crate"
- desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
- cost = 3500
- contains = list(/obj/item/gun/ballistic/shotgun,
- /obj/item/gun/ballistic/shotgun,
- /obj/item/gun/ballistic/shotgun)
- crate_name = "woodstock shotguns crate"
-
-/datum/supply_pack/security/armory/wt550
- name = "WT-550 Semi-Auto Rifle Crate"
- desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open."
- cost = 3500
- contains = list(/obj/item/gun/ballistic/automatic/wt550,
- /obj/item/gun/ballistic/automatic/wt550)
- crate_name = "auto rifle crate"
-
-/datum/supply_pack/security/armory/wt550ammo
- name = "WT-550 Semi-Auto SMG Ammo Crate"
- desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
- cost = 2500
- contains = list(/obj/item/ammo_box/magazine/wt550m9,
- /obj/item/ammo_box/magazine/wt550m9,
- /obj/item/ammo_box/magazine/wt550m9,
- /obj/item/ammo_box/magazine/wt550m9)
- crate_name = "auto rifle ammo crate"
-
-/datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stun crit someone
- name = "WT-550 Semi-Auto SMG Non-Lethal Ammo Crate"
- desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
- cost = 1500
- contains = list(/obj/item/ammo_box/magazine/wt550m9/wtrubber,
- /obj/item/ammo_box/magazine/wt550m9/wtrubber,
- /obj/item/ammo_box/magazine/wt550m9/wtrubber,
- /obj/item/ammo_box/magazine/wt550m9/wtrubber)
- crate_name = "auto rifle ammo crate"
-
-/datum/supply_pack/security/armory/wt550ammo_special
- name = "WT-550 Semi-Auto SMG Special Ammo Crate"
- desc = "Contains 2 20-round Armour Piercing and Incendiary magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
- cost = 4500
- contains = list(/obj/item/ammo_box/magazine/wt550m9/wtap,
- /obj/item/ammo_box/magazine/wt550m9/wtap,
- /obj/item/ammo_box/magazine/wt550m9/wtic,
- /obj/item/ammo_box/magazine/wt550m9/wtic)
- crate_name = "auto rifle ammo crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Engineering /////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/engineering
- group = "Engineering"
- crate_type = /obj/structure/closet/crate/engineering
-
-/datum/supply_pack/engineering/shieldgen
- name = "Anti-breach Shield Projector Crate"
- desc = "Hull breaches again? Say no more with the Nanotrasen Anti-Breach Shield Projector! Uses forcefield technology to keep the air in, and the space out. Contains two shield projectors."
- cost = 2500
- contains = list(/obj/machinery/shieldgen,
- /obj/machinery/shieldgen)
- crate_name = "anti-breach shield projector crate"
-
-/datum/supply_pack/engineering/conveyor
- name = "Conveyor Assembly Crate"
- desc = "Keep production moving along with six conveyor belts. Conveyor switch included. If you have any questions, check out the enclosed instruction book."
- cost = 750
- contains = list(/obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_construct,
- /obj/item/conveyor_switch_construct,
- /obj/item/paper/guides/conveyor)
- crate_name = "conveyor assembly crate"
-
-/datum/supply_pack/engineering/engiequipment
- name = "Engineering Gear Crate"
- desc = "Gear up with three toolbelts, high-visibility vests, welding helmets, hardhats, and two pairs of meson goggles!"
- cost = 1300
- contains = list(/obj/item/storage/belt/utility,
- /obj/item/storage/belt/utility,
- /obj/item/storage/belt/utility,
- /obj/item/clothing/suit/hazardvest,
- /obj/item/clothing/suit/hazardvest,
- /obj/item/clothing/suit/hazardvest,
- /obj/item/clothing/head/welding,
- /obj/item/clothing/head/welding,
- /obj/item/clothing/head/welding,
- /obj/item/clothing/head/hardhat,
- /obj/item/clothing/head/hardhat,
- /obj/item/clothing/head/hardhat,
- /obj/item/clothing/glasses/meson/engine,
- /obj/item/clothing/glasses/meson/engine)
- crate_name = "engineering gear crate"
-
-/datum/supply_pack/engineering/engihardsuit
- name = "Engineering Hardsuit"
- desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
- cost = 2500
- contains = list(/obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/hardsuit/engine)
- crate_name = "engineering hardsuit"
-
-/datum/supply_pack/engineering/atmoshardsuit
- name = "Atmospherics Hardsuit"
- desc = "Too many techs and not enough hardsuits? Time to buy some more! Comes with gas mask and air tank. Ask the CE to open."
- cost = 5000
- access = ACCESS_CE
- contains = list(/obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/hardsuit/engine/atmos)
- crate_name = "atmospherics hardsuit"
- crate_type = /obj/structure/closet/crate/secure/engineering
-
-/datum/supply_pack/engineering/industrialrcd
- name = "Industrial RCD"
- desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Dose not contain spare ammo for the industrial RCD or any other RCD modles."
- cost = 4500
- access = ACCESS_CE
- contains = list(/obj/item/construction/rcd/industrial)
- crate_name = "industrial rcd"
- crate_type = /obj/structure/closet/crate/secure/engineering
-
-/datum/supply_pack/engineering/powergamermitts
- name = "Insulated Gloves Crate"
- desc = "The backbone of modern society. Barely ever ordered for actual engineering. Contains three insulated gloves."
- cost = 2000 //Made of pure-grade bullshittinium
- contains = list(/obj/item/clothing/gloves/color/yellow,
- /obj/item/clothing/gloves/color/yellow,
- /obj/item/clothing/gloves/color/yellow)
- crate_name = "insulated gloves crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/obj/item/stock_parts/cell/inducer_supply
- maxcharge = 5000
- charge = 5000
-
-/datum/supply_pack/engineering/inducers
- name = "NT-75 Electromagnetic Power Inducers Crate"
- desc = "No rechargers? No problem, with the NT-75 EPI, you can recharge any standard cell-based equipment anytime, anywhere. Contains two Inducers."
- cost = 2000
- contains = list(/obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}, /obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}) //FALSE doesn't work in modified type paths apparently.
- crate_name = "inducer crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engineering/pacman
- name = "P.A.C.M.A.N Generator Crate"
- desc = "Engineers can't set up the engine? Not an issue for you, once you get your hands on this P.A.C.M.A.N. Generator! Takes in plasma and spits out sweet sweet energy."
- cost = 2500
- contains = list(/obj/machinery/power/port_gen/pacman)
- crate_name = "PACMAN generator crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engineering/power
- name = "Power Cell Crate"
- desc = "Looking for power overwhelming? Look no further. Contains three high-voltage power cells."
- cost = 1000
- contains = list(/obj/item/stock_parts/cell/high,
- /obj/item/stock_parts/cell/high,
- /obj/item/stock_parts/cell/high)
- crate_name = "power cell crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engineering/shuttle_engine
- name = "Shuttle Engine Crate"
- desc = "Through advanced bluespace-shenanigans, our engineers have managed to fit an entire shuttle engine into one tiny little crate. Requires CE access to open."
- cost = 5000
- access = ACCESS_CE
- contains = list(/obj/structure/shuttle/engine/propulsion/burst/cargo)
- crate_name = "shuttle engine crate"
- crate_type = /obj/structure/closet/crate/secure/engineering
- special = TRUE
-
-/datum/supply_pack/engineering/tools
- name = "Toolbox Crate"
- desc = "Any robust spaceman is never far from their trusty toolbox. Contains three electrical toolboxes and three mechanical toolboxes."
- contains = list(/obj/item/storage/toolbox/electrical,
- /obj/item/storage/toolbox/electrical,
- /obj/item/storage/toolbox/electrical,
- /obj/item/storage/toolbox/mechanical,
- /obj/item/storage/toolbox/mechanical,
- /obj/item/storage/toolbox/mechanical)
- cost = 1000
- crate_name = "toolbox crate"
-
-/datum/supply_pack/engineering/bsa
- name = "Bluespace Artillery Parts"
- desc = "The pride of Nanotrasen Naval Command. The legendary Bluespace Artillery Cannon is a devastating feat of human engineering and testament to wartime determination. Highly advanced research is required for proper construction. "
- cost = 15000
- special = TRUE
- contains = list(/obj/item/circuitboard/machine/bsa/front,
- /obj/item/circuitboard/machine/bsa/middle,
- /obj/item/circuitboard/machine/bsa/back,
- /obj/item/circuitboard/computer/bsa_control
- )
- crate_name= "bluespace artillery parts crate"
-
-/datum/supply_pack/engineering/dna_vault
- name = "DNA Vault Parts"
- desc = "Secure the longevity of the current state of humanity within this massive library of scientific knowledge, capable of granting superhuman powers and abilities. Highly advanced research is required for proper construction. Also contains five DNA probes."
- cost = 12000
- special = TRUE
- contains = list(
- /obj/item/circuitboard/machine/dna_vault,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe
- )
- crate_name= "dna vault parts crate"
-
-/datum/supply_pack/engineering/dna_probes
- name = "DNA Vault Samplers"
- desc = "Contains five DNA probes for use in the DNA vault."
- cost = 3000
- special = TRUE
- contains = list(/obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe,
- /obj/item/dna_probe
- )
- crate_name= "dna samplers crate"
-
-
-/datum/supply_pack/engineering/shield_sat
- name = "Shield Generator Satellite"
- desc = "Protect the very existence of this station with these Anti-Meteor defenses. Contains three Shield Generator Satellites."
- cost = 4000
- contains = list(
- /obj/machinery/satellite/meteor_shield,
- /obj/machinery/satellite/meteor_shield,
- /obj/machinery/satellite/meteor_shield
- )
- crate_name= "shield sat crate"
-
-/datum/supply_pack/engineering/shield_sat_control
- name = "Shield System Control Board"
- desc = "A control system for the Shield Generator Satellite system."
- cost = 4000
- contains = list(/obj/item/circuitboard/computer/sat_control)
- crate_name= "shield control board crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////// Engine Construction /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/engine
- group = "Engine Construction"
- crate_type = /obj/structure/closet/crate/engineering
-
-/datum/supply_pack/engine/am_jar
- name = "Antimatter Containment Jar Crate"
- desc = "Two Antimatter containment jars stuffed into a single crate."
- cost = 2000
- contains = list(/obj/item/am_containment,
- /obj/item/am_containment)
- crate_name = "antimatter jar crate"
-
-/datum/supply_pack/engine/am_core
- name = "Antimatter Control Crate"
- desc = "The brains of the Antimatter engine, this device is sure to teach the station's powergrid the true meaning of real power."
- cost = 5000
- contains = list(/obj/machinery/power/am_control_unit)
- crate_name = "antimatter control crate"
-
-/datum/supply_pack/engine/am_shielding
- name = "Antimatter Shielding Crate"
- desc = "Contains ten Antimatter shields, somehow crammed into a crate."
- cost = 2000
- contains = list(/obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container,
- /obj/item/am_shielding_container) //10 shields: 3x3 containment and a core
- crate_name = "antimatter shielding crate"
-
-/datum/supply_pack/engine/emitter
- name = "Emitter Crate"
- desc = "Useful for powering forcefield generators while destroying locked crates and intruders alike. Contains two high-powered energy emitters. Requires CE access to open."
- cost = 1500
- access = ACCESS_CE
- contains = list(/obj/machinery/power/emitter,
- /obj/machinery/power/emitter)
- crate_name = "emitter crate"
- crate_type = /obj/structure/closet/crate/secure/engineering
- dangerous = TRUE
-
-/datum/supply_pack/engine/field_gen
- name = "Field Generator Crate"
- desc = "Typically the only thing standing between the station and a messy death. Powered by emitters. Contains two field generators."
- cost = 1500
- contains = list(/obj/machinery/field/generator,
- /obj/machinery/field/generator)
- crate_name = "field generator crate"
-
-/datum/supply_pack/engine/grounding_rods
- name = "Grounding Rod Crate"
- desc = "Four grounding rods guaranteed to keep any uppity tesla's lightning under control."
- cost = 1700
- contains = list(/obj/machinery/power/grounding_rod,
- /obj/machinery/power/grounding_rod,
- /obj/machinery/power/grounding_rod,
- /obj/machinery/power/grounding_rod)
- crate_name = "grounding rod crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engine/mason
- name = "M.A.S.O.N RIG Crate"
- desc = "The rare M.A.S.O.N RIG. Requires CE access to open."
- cost = 15000
- access = ACCESS_CE
- contains = list(/obj/item/clothing/suit/space/hardsuit/ancient/mason)
- crate_name = "M.A.S.O.N Rig"
- crate_type = /obj/structure/closet/crate/secure/engineering
-
-/datum/supply_pack/engine/PA
- name = "Particle Accelerator Crate"
- desc = "A supermassive black hole or hyper-powered teslaball are the perfect way to spice up any party! This \"My First Apocalypse\" kit contains everything you need to build your own Particle Accelerator! Ages 10 and up."
- cost = 3000
- contains = list(/obj/structure/particle_accelerator/fuel_chamber,
- /obj/machinery/particle_accelerator/control_box,
- /obj/structure/particle_accelerator/particle_emitter/center,
- /obj/structure/particle_accelerator/particle_emitter/left,
- /obj/structure/particle_accelerator/particle_emitter/right,
- /obj/structure/particle_accelerator/power_box,
- /obj/structure/particle_accelerator/end_cap)
- crate_name = "particle accelerator crate"
-
-/datum/supply_pack/engine/collector
- name = "Radiation Collector Crate"
- desc = "Contains three radiation collectors. Useful for collecting energy off nearby Supermatter Crystals, Singularities or Teslas!"
- cost = 2500
- contains = list(/obj/machinery/power/rad_collector,
- /obj/machinery/power/rad_collector,
- /obj/machinery/power/rad_collector)
- crate_name = "collector crate"
-
-/datum/supply_pack/engine/sing_gen
- name = "Singularity Generator Crate"
- desc = "The key to unlocking the power of Lord Singuloth. Particle Accelerator not included."
- cost = 5000
- contains = list(/obj/machinery/the_singularitygen)
- crate_name = "singularity generator crate"
-
-/datum/supply_pack/engine/solar
- name = "Solar Panel Crate"
- desc = "Go green with this DIY advanced solar array. Contains twenty one solar assemblies, a solar-control circuit board, and tracker. If you have any questions, please check out the enclosed instruction book."
- cost = 2000
- contains = list(/obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/solar_assembly,
- /obj/item/circuitboard/computer/solar_control,
- /obj/item/electronics/tracker,
- /obj/item/paper/guides/jobs/engi/solars)
- crate_name = "solar panel crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engine/supermatter_shard
- name = "Supermatter Shard Crate"
- desc = "The power of the heavens condensed into a single crystal. Requires CE access to open."
- cost = 10000
- access = ACCESS_CE
- contains = list(/obj/machinery/power/supermatter_crystal/shard)
- crate_name = "supermatter shard crate"
- crate_type = /obj/structure/closet/crate/secure/engineering
- dangerous = TRUE
-
-/datum/supply_pack/engine/tesla_coils
- name = "Tesla Coil Crate"
- desc = "Whether it's high-voltage executions, creating research points, or just plain old power generation: This pack of four Tesla coils can do it all!"
- cost = 2500
- contains = list(/obj/machinery/power/tesla_coil,
- /obj/machinery/power/tesla_coil,
- /obj/machinery/power/tesla_coil,
- /obj/machinery/power/tesla_coil)
- crate_name = "tesla coil crate"
- crate_type = /obj/structure/closet/crate/engineering/electrical
-
-/datum/supply_pack/engine/tesla_gen
- name = "Tesla Generator Crate"
- desc = "The key to unlocking the power of the Tesla energy ball. Particle Accelerator not included."
- cost = 5000
- contains = list(/obj/machinery/the_singularitygen/tesla)
- crate_name = "tesla generator crate"
-
-//////////////////////////////////////////////////////////////////////////////
-/////////////////////// Canisters & Materials ////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/materials
- group = "Canisters & Materials"
-
-/datum/supply_pack/materials/cardboard50
- name = "50 Cardboard Sheets"
- desc = "Create a bunch of boxes."
- cost = 1000
- contains = list(/obj/item/stack/sheet/cardboard/fifty)
- crate_name = "cardboard sheets crate"
-
-/datum/supply_pack/materials/glass50
- name = "50 Glass Sheets"
- desc = "Let some nice light in with fifty glass sheets!"
- cost = 1000
- contains = list(/obj/item/stack/sheet/glass/fifty)
- crate_name = "glass sheets crate"
-
-/datum/supply_pack/materials/metal50
- name = "50 Metal Sheets"
- desc = "Any construction project begins with a good stack of fifty metal sheets!"
- cost = 1000
- contains = list(/obj/item/stack/sheet/metal/fifty)
- crate_name = "metal sheets crate"
-
-/datum/supply_pack/materials/plasteel20
- name = "20 Plasteel Sheets"
- desc = "Reinforce the station's integrity with twenty plasteel sheets!"
- cost = 7500
- contains = list(/obj/item/stack/sheet/plasteel/twenty)
- crate_name = "plasteel sheets crate"
-
-/datum/supply_pack/materials/plasteel50
- name = "50 Plasteel Sheets"
- desc = "For when you REALLY have to reinforce something."
- cost = 16500
- contains = list(/obj/item/stack/sheet/plasteel/fifty)
- crate_name = "plasteel sheets crate"
-
-/datum/supply_pack/materials/plastic50
- name = "50 Plastic Sheets"
- desc = "Build a limitless amount of toys with fifty plastic sheets!"
- cost = 1000
- contains = list(/obj/item/stack/sheet/plastic/fifty)
- crate_name = "plastic sheets crate"
-
-/datum/supply_pack/materials/sandstone30
- name = "30 Sandstone Blocks"
- desc = "Neither sandy nor stoney, these thirty blocks will still get the job done."
- cost = 1000
- contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty)
- crate_name = "sandstone blocks crate"
-
-/datum/supply_pack/materials/wood50
- name = "50 Wood Planks"
- desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!"
- cost = 2000
- contains = list(/obj/item/stack/sheet/mineral/wood/fifty)
- crate_name = "wood planks crate"
-
-/datum/supply_pack/materials/rcdammo
- name = "Spare RDC ammo"
- desc = "This crate contains sixteen RCD ammo packs, to help with any holes or projects people mite be working on."
- cost = 3750
- contains = list(/obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo,
- /obj/item/rcd_ammo)
- crate_name = "rcd ammo"
-
-/datum/supply_pack/materials/bz
- name = "BZ Canister Crate"
- desc = "Contains a canister of BZ. Requires Toxins access to open."
- cost = 7500 // Costs 3 credits more than what you can get for selling it.
- access = ACCESS_TOX_STORAGE
- contains = list(/obj/machinery/portable_atmospherics/canister/bz)
- crate_name = "BZ canister crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/materials/carbon_dio
- name = "Carbon Dioxide Canister"
- desc = "Contains a canister of Carbon Dioxide."
- cost = 3000
- contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide)
- crate_name = "carbon dioxide canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/nitrogen
- name = "Nitrogen Canister"
- desc = "Contains a canister of Nitrogen."
- cost = 2000
- contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen)
- crate_name = "nitrogen canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/nitrous_oxide_canister
- name = "Nitrous Oxide Canister"
- desc = "Contains a canister of Nitrous Oxide. Requires Atmospherics access to open."
- cost = 3000
- access = ACCESS_ATMOSPHERICS
- contains = list(/obj/machinery/portable_atmospherics/canister/nitrous_oxide)
- crate_name = "nitrous oxide canister crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/materials/oxygen
- name = "Oxygen Canister"
- desc = "Contains a canister of Oxygen. Canned in Druidia."
- cost = 1500
- contains = list(/obj/machinery/portable_atmospherics/canister/oxygen)
- crate_name = "oxygen canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/water_vapor
- name = "Water Vapor Canister"
- desc = "Contains a canister of Water Vapor. I swear to god if you open this in the halls..."
- cost = 2500
- contains = list(/obj/machinery/portable_atmospherics/canister/water_vapor)
- crate_name = "water vapor canister crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/fueltank
- name = "Fuel Tank Crate"
- desc = "Contains a welding fuel tank. Caution, highly flammable."
- cost = 800
- contains = list(/obj/structure/reagent_dispensers/fueltank)
- crate_name = "fuel tank crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/watertank
- name = "Water Tank Crate"
- desc = "Contains a tank of dihydrogen monoxide... sounds dangerous."
- cost = 600
- contains = list(/obj/structure/reagent_dispensers/watertank)
- crate_name = "water tank crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/foamtank
- name = "Firefighting Foam Tank Crate"
- desc = "Contains a tank of firefighting foam. Also known as \"plasmaman's bane\"."
- cost = 1500
- contains = list(/obj/structure/reagent_dispensers/foamtank)
- crate_name = "foam tank crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/materials/hightank
- name = "Large Water Tank Crate"
- desc = "Contains a high-capacity water tank. Useful for botany or other service jobs."
- cost = 1200
- contains = list(/obj/structure/reagent_dispensers/watertank/high)
- crate_name = "high-capacity water tank crate"
- crate_type = /obj/structure/closet/crate/large
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Medical /////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/medical
- group = "Medical"
- crate_type = /obj/structure/closet/crate/medical
-
-/datum/supply_pack/medical/firstaidbruises
- name = "Bruise Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing bruises and broken bones."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/brute,
- /obj/item/storage/firstaid/brute,
- /obj/item/storage/firstaid/brute)
- crate_name = "brute treatment kit crate"
-
-/datum/supply_pack/medical/firstaidburns
- name = "Burn Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing severe burns."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/fire,
- /obj/item/storage/firstaid/fire,
- /obj/item/storage/firstaid/fire)
- crate_name = "burn treatment kit crate"
-
-/datum/supply_pack/medical/bloodpacks
- name = "Blood Pack Variety Crate"
- desc = "Contains eight different blood packs for reintroducing blood to patients."
- cost = 3000
- contains = list(/obj/item/reagent_containers/blood,
- /obj/item/reagent_containers/blood,
- /obj/item/reagent_containers/blood/APlus,
- /obj/item/reagent_containers/blood/AMinus,
- /obj/item/reagent_containers/blood/BPlus,
- /obj/item/reagent_containers/blood/BMinus,
- /obj/item/reagent_containers/blood/OPlus,
- /obj/item/reagent_containers/blood/OMinus,
- /obj/item/reagent_containers/blood/lizard)
- crate_name = "blood freezer"
- crate_type = /obj/structure/closet/crate/freezer
-
-/datum/supply_pack/medical/defibs
- name = "Defibrillator Crate"
- desc = "Contains two defibrillators for bringing the recently deceased back to life."
- cost = 2500
- contains = list(/obj/item/defibrillator/loaded,
- /obj/item/defibrillator/loaded)
- crate_name = "defibrillator crate"
-
-/datum/supply_pack/medical/firstaid
- name = "First Aid Kit Crate"
- desc = "Contains four first aid kits for healing most types of wounds."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular,
- /obj/item/storage/firstaid/regular)
- crate_name = "first aid kit crate"
-
-/datum/supply_pack/medical/iv_drip
- name = "IV Drip Crate"
- desc = "Contains a single IV drip stand for intravenous delivery."
- cost = 700
- contains = list(/obj/machinery/iv_drip)
- crate_name = "iv drip crate"
-
-/datum/supply_pack/science/adv_surgery_tools
- name = "Med-Co Advanced surgery tools"
- desc = "A full set of Med-Co advanced surgery tools, this crate also comes with a spay of synth flesh as well as a can of . Requires Surgery access to open."
- cost = 5000
- access = ACCESS_SURGERY
- contains = list(/obj/item/storage/belt/medical/surgery_belt_adv,
- /obj/item/reagent_containers/medspray/synthflesh,
- /obj/item/reagent_containers/medspray/sterilizine)
- crate_name = "medco newest surgery tools"
- crate_type = /obj/structure/closet/crate/medical
-
-/datum/supply_pack/medical/medicalhardsuit
- name = "Medical Hardsuit"
- desc = "Got people being spaced left and right? Hole in the same room as the dead body of Hos or cap? Fear not, now you can buy one medical hardsuit with a mask and air tank to save your fellow crewmembers."
- cost = 2500
- contains = list(/obj/item/tank/internals/air,
- /obj/item/clothing/mask/gas,
- /obj/item/clothing/suit/space/hardsuit/medical)
- crate_name = "medical hardsuit"
-
-/datum/supply_pack/medical/supplies
- name = "Medical Supplies Crate"
- desc = "Contains seven beakers, syringes, and bodybags. Three morphine bottles, four insulin pills. Two charcoal bottles, epinephrine bottles, antitoxin bottles, and large beakers. Finally, a single roll of medical gauze, as well as a bottle of stimulant pills for long, hard work days. German doctor not included."
- cost = 2500
- contains = list(/obj/item/reagent_containers/glass/bottle/charcoal,
- /obj/item/reagent_containers/glass/bottle/charcoal,
- /obj/item/reagent_containers/glass/bottle/epinephrine,
- /obj/item/reagent_containers/glass/bottle/epinephrine,
- /obj/item/reagent_containers/glass/bottle/morphine,
- /obj/item/reagent_containers/glass/bottle/morphine,
- /obj/item/reagent_containers/glass/bottle/morphine,
- /obj/item/reagent_containers/glass/bottle/toxin,
- /obj/item/reagent_containers/glass/bottle/toxin,
- /obj/item/reagent_containers/glass/beaker/large,
- /obj/item/reagent_containers/glass/beaker/large,
- /obj/item/reagent_containers/pill/insulin,
- /obj/item/reagent_containers/pill/insulin,
- /obj/item/reagent_containers/pill/insulin,
- /obj/item/reagent_containers/pill/insulin,
- /obj/item/stack/medical/gauze,
- /obj/item/storage/box/beakers,
- /obj/item/storage/box/medsprays,
- /obj/item/storage/box/syringes,
- /obj/item/storage/box/bodybags,
- /obj/item/storage/pill_bottle/stimulant)
- crate_name = "medical supplies crate"
-
-/datum/supply_pack/medical/vending
- name = "Medical Vending Crate"
- desc = "Contains refills for medical vending machines."
- cost = 2000
- contains = list(/obj/item/vending_refill/medical,
- /obj/item/vending_refill/wallmed)
- crate_name = "medical vending crate"
-
-/datum/supply_pack/medical/sprays
- name = "Medical Sprays"
- desc = "Contains two cans of Styptic Spray, Silver Sulfadiazine Spray, Synthflesh Spray and Sterilizer Compound Spray."
- cost = 2500
- contains = list(/obj/item/reagent_containers/medspray/styptic,
- /obj/item/reagent_containers/medspray/styptic,
- /obj/item/reagent_containers/medspray/silver_sulf,
- /obj/item/reagent_containers/medspray/silver_sulf,
- /obj/item/reagent_containers/medspray/synthflesh,
- /obj/item/reagent_containers/medspray/synthflesh,
- /obj/item/reagent_containers/medspray/sterilizine,
- /obj/item/reagent_containers/medspray/sterilizine)
- crate_name = "medical supplies crate"
-
-/datum/supply_pack/medical/firstaidmixed
- name = "Mixed Medical Kits"
- desc = "Contains one of each medical kits for dealing with a variety of injured crewmembers."
- cost = 1500
- contains = list(/obj/item/storage/firstaid/toxin,
- /obj/item/storage/firstaid/o2,
- /obj/item/storage/firstaid/brute,
- /obj/item/storage/firstaid/fire,
- /obj/item/storage/firstaid/regular)
- crate_name = "medical supplies crate"
-
-/datum/supply_pack/medical/firstaidoxygen
- name = "Oxygen Deprivation Kit Crate"
- desc = "Contains three first aid kits focused on helping oxygen deprivation victims."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/o2,
- /obj/item/storage/firstaid/o2,
- /obj/item/storage/firstaid/o2)
- crate_name = "oxygen deprivation kit crate"
-
-/datum/supply_pack/medical/advrad
- name = "Radiation Treatment Crate Deluxe"
- desc = "A crate for when radiation is out of hand... Contains two rad-b-gone kits, one bottle of anti radiation deluxe pill bottle, as well as a radiation treatment deluxe pill bottle!"
- cost = 3500
- contains = list(/obj/item/storage/pill_bottle/antirad_plus,
- /obj/item/storage/pill_bottle/mutarad,
- /obj/item/storage/firstaid/radbgone,
- /obj/item/storage/firstaid/radbgone,
- /obj/item/geiger_counter,
- /obj/item/geiger_counter)
- crate_name = "radiation protection crate"
- crate_type = /obj/structure/closet/crate/radiation
-
-/datum/supply_pack/medical/surgery
- name = "Surgical Supplies Crate"
- desc = "Do you want to perform surgery, but don't have one of those fancy shmancy degrees? Just get started with this crate containing a medical duffelbag, Sterilizine spray and collapsible roller bed."
- cost = 1000
- contains = list(/obj/item/storage/backpack/duffelbag/med/surgery,
- /obj/item/reagent_containers/medspray/sterilizine,
- /obj/item/roller)
- crate_name = "surgical supplies crate"
-
-/datum/supply_pack/medical/firstaidtoxins
- name = "Toxin Treatment Kit Crate"
- desc = "Contains three first aid kits focused on healing damage dealt by heavy toxins."
- cost = 1000
- contains = list(/obj/item/storage/firstaid/toxin,
- /obj/item/storage/firstaid/toxin,
- /obj/item/storage/firstaid/toxin)
- crate_name = "toxin treatment kit crate"
-
-/datum/supply_pack/medical/virus
- name = "Virus Crate"
- desc = "Contains twelve different bottles, containing several viral samples for virology research. Also includes seven beakers and syringes. Balled-up jeans not included. Requires CMO access to open."
- cost = 2500
- access = ACCESS_CMO
- contains = list(/obj/item/reagent_containers/glass/bottle/flu_virion,
- /obj/item/reagent_containers/glass/bottle/cold,
- /obj/item/reagent_containers/glass/bottle/random_virus,
- /obj/item/reagent_containers/glass/bottle/random_virus,
- /obj/item/reagent_containers/glass/bottle/random_virus,
- /obj/item/reagent_containers/glass/bottle/random_virus,
- /obj/item/reagent_containers/glass/bottle/fake_gbs,
- /obj/item/reagent_containers/glass/bottle/magnitis,
- /obj/item/reagent_containers/glass/bottle/pierrot_throat,
- /obj/item/reagent_containers/glass/bottle/brainrot,
- /obj/item/reagent_containers/glass/bottle/anxiety,
- /obj/item/reagent_containers/glass/bottle/beesease,
- /obj/item/storage/box/syringes,
- /obj/item/storage/box/beakers,
- /obj/item/reagent_containers/glass/bottle/mutagen)
- crate_name = "virus crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
- dangerous = TRUE
-
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Science /////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/science
- group = "Science"
- crate_type = /obj/structure/closet/crate/science
-
-/datum/supply_pack/science/robotics/mecha_odysseus
- name = "Circuit Crate (Odysseus)"
- desc = "Ever wanted to build your own giant medical robot? Well, now you can! Contains the Odysseus main control board and Odysseus peripherals board. Requires Robotics access to open."
- cost = 2500
- access = ACCESS_ROBOTICS
- contains = list(/obj/item/circuitboard/mecha/odysseus/peripherals,
- /obj/item/circuitboard/mecha/odysseus/main)
- crate_name = "\improper Odysseus circuit crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/science/robotics/mecha_ripley
- name = "Circuit Crate (Ripley APLU)"
- desc = "Rip apart rocks and xenomorphs alike with the Ripley APLU. Contains the Main Ripley control board, as well as the Ripley Peripherals board. Requires Robotics access to open."
- cost = 3000
- access = ACCESS_ROBOTICS
- contains = list(/obj/item/book/manual/ripley_build_and_repair,
- /obj/item/circuitboard/mecha/ripley/main,
- /obj/item/circuitboard/mecha/ripley/peripherals)
- crate_name = "\improper APLU Ripley circuit crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/science/circuitry
- name = "Circuitry Starter Pack Crate"
- desc = "Journey into the mysterious world of Circuitry with this starter pack. Contains a circuit printer, analyzer, debugger and wirer. Power cells not included."
- cost = 1000
- contains = list(/obj/item/integrated_electronics/analyzer,
- /obj/item/integrated_circuit_printer,
- /obj/item/integrated_electronics/debugger,
- /obj/item/integrated_electronics/wirer)
- crate_name = "circuitry starter pack crate"
-
-/datum/supply_pack/science/plasma
- name = "Plasma Assembly Crate"
- desc = "Everything you need to burn something to the ground, this contains three plasma assembly sets. Each set contains a plasma tank, igniter, proximity sensor, and timer! Warranty void if exposed to high temperatures. Requires Toxins access to open."
- cost = 1000
- access = ACCESS_TOX_STORAGE
- contains = list(/obj/item/tank/internals/plasma,
- /obj/item/tank/internals/plasma,
- /obj/item/tank/internals/plasma,
- /obj/item/assembly/igniter,
- /obj/item/assembly/igniter,
- /obj/item/assembly/igniter,
- /obj/item/assembly/prox_sensor,
- /obj/item/assembly/prox_sensor,
- /obj/item/assembly/prox_sensor,
- /obj/item/assembly/timer,
- /obj/item/assembly/timer,
- /obj/item/assembly/timer)
- crate_name = "plasma assembly crate"
- crate_type = /obj/structure/closet/crate/secure/plasma
-
-/datum/supply_pack/science/robotics
- name = "Robotics Assembly Crate"
- desc = "The tools you need to replace those finicky humans with a loyal robot army! Contains three proximity sensors, two high-powered cells, six flashes, and an electrical toolbox. Requires Robotics access to open."
- cost = 1000
- access = ACCESS_ROBOTICS
- contains = list(/obj/item/assembly/prox_sensor,
- /obj/item/assembly/prox_sensor,
- /obj/item/assembly/prox_sensor,
- /obj/item/storage/toolbox/electrical,
- /obj/item/storage/box/flashes,
- /obj/item/stock_parts/cell/high,
- /obj/item/stock_parts/cell/high)
- crate_name = "robotics assembly crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/science/shieldwalls
- name = "Shield Generator Crate"
- desc = "These high powered Shield Wall Generators are guaranteed to keep any unwanted lifeforms on the outside, where they belong! Contains four shield wall generators. Requires Teleporter access to open."
- cost = 2000
- access = ACCESS_TELEPORTER
- contains = list(/obj/machinery/shieldwallgen,
- /obj/machinery/shieldwallgen,
- /obj/machinery/shieldwallgen,
- /obj/machinery/shieldwallgen)
- crate_name = "shield generators crate"
- crate_type = /obj/structure/closet/crate/secure/science
-
-/datum/supply_pack/science/tablets
- name = "Tablet Crate"
- desc = "What's a computer? Contains five cargo tablets."
- cost = 5000
- contains = list(/obj/item/modular_computer/tablet/preset/cargo,
- /obj/item/modular_computer/tablet/preset/cargo,
- /obj/item/modular_computer/tablet/preset/cargo,
- /obj/item/modular_computer/tablet/preset/cargo,
- /obj/item/modular_computer/tablet/preset/cargo)
- crate_name = "tablet crate"
-
-/datum/supply_pack/science/transfer_valves
- name = "Tank Transfer Valves Crate"
- desc = "The key ingredient for making a lot of people very angry very fast. Contains two tank transfer valves. Requires RD access to open."
- cost = 6000
- access = ACCESS_RD
- contains = list(/obj/item/transfer_valve,
- /obj/item/transfer_valve)
- crate_name = "tank transfer valves crate"
- crate_type = /obj/structure/closet/crate/secure/science
- dangerous = TRUE
-
-/datum/supply_pack/science/tech_slugs
- name = "Tech Slug Ammo Shells"
- desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all."
- cost = 1000
- contains = list(/obj/item/storage/box/techsslug,
- /obj/item/storage/box/techsslug)
- crate_name = "tech slug crate"
-
-
-//////////////////////////////////////////////////////////////////////////////
-/////////////////////////////// Service //////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/service
- group = "Service"
-
-/datum/supply_pack/service/advlighting
- name = "Advanced Lighting crate"
- desc = "Thanks to advanced lighting tech we here at the Lamp Factory have be able to produce more lamps and lamp items! This crate has three lamps, a box of lights and a state of the art rapid-light-device!"
- cost = 2500 //Fair
- contains = list(/obj/item/construction/rld,
- /obj/item/flashlight/lamp,
- /obj/item/flashlight/lamp,
- /obj/item/flashlight/lamp/green,
- /obj/item/storage/box/lights/mixed)
- crate_name = "advanced lighting crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/service/cargo_supples
- name = "Cargo Supplies Crate"
- desc = "Sold everything that wasn't bolted down? You can get right back to work with this crate containing stamps, an export scanner, destination tagger, hand labeler and some package wrapping."
- cost = 1000
- contains = list(/obj/item/stamp,
- /obj/item/stamp/denied,
- /obj/item/export_scanner,
- /obj/item/destTagger,
- /obj/item/hand_labeler,
- /obj/item/stack/packageWrap)
- crate_name = "cargo supplies crate"
-
-/datum/supply_pack/service/food_cart
- name = "Food Cart Crate"
- desc = "Want to sell food on the go? Cook lost their cart? Well we just so happen to have a few carts to spare!"
- cost = 1000
- contains = list(/obj/machinery/food_cart)
- crate_name = "food cart crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/noslipfloor
- name = "High-traction Floor Tiles"
- desc = "Make slipping a thing of the past with sixty industrial-grade anti-slip floortiles!"
- cost = 2000
- contains = list(/obj/item/stack/tile/noslip/thirty,
- /obj/item/stack/tile/noslip/thirty)
- crate_name = "high-traction floor tiles crate"
-
-/datum/supply_pack/service/icecream_cart
- name = "Ice Cream Cart Crate"
- desc = "Plasma fire a to hot for you, want a nice treat after a hard days work? Well now we have the cart for you! This Ice Cream Vat has everthing you need to make you and your friends so ice cream treats! This cart comes stocked with some ingredients for each type of scoopable icecream."
- cost = 2750 //Comes prestocked with basic ingredients
- contains = list(/obj/machinery/icecream_vat)
- crate_name = "ice cream vat crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/janitor
- name = "Janitorial Supplies Crate"
- desc = "Fight back against dirt and grime with Nanotrasen's Janitorial Essentials(tm)! Contains three buckets, caution signs, and cleaner grenades. Also has a single mop, spray cleaner, rag, NT soap and a trash bag."
- cost = 1000
- contains = list(/obj/item/reagent_containers/glass/bucket,
- /obj/item/reagent_containers/glass/bucket,
- /obj/item/reagent_containers/glass/bucket,
- /obj/item/mop,
- /obj/item/caution,
- /obj/item/caution,
- /obj/item/caution,
- /obj/item/storage/bag/trash,
- /obj/item/reagent_containers/spray/cleaner,
- /obj/item/reagent_containers/rag,
- /obj/item/grenade/chem_grenade/cleaner,
- /obj/item/grenade/chem_grenade/cleaner,
- /obj/item/grenade/chem_grenade/cleaner,
- /obj/item/soap/nanotrasen)
- crate_name = "janitorial supplies crate"
-
-/datum/supply_pack/service/janitor/janicart
- name = "Janitorial Cart and Galoshes Crate"
- desc = "The keystone to any successful janitor. As long as you have feet, this pair of galoshes will keep them firmly planted on the ground. Also contains a janitorial cart."
- cost = 2000
- contains = list(/obj/structure/janitorialcart,
- /obj/item/clothing/shoes/galoshes)
- crate_name = "janitorial cart crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/service/janitor/janitank
- name = "Janitor Backpack Crate"
- desc = "Call forth divine judgement upon dirt and grime with this high capacity janitor backpack. Contains 500 units of station-cleansing cleaner. Requires janitor access to open."
- cost = 1000
- access = ACCESS_JANITOR
- contains = list(/obj/item/watertank/janitor)
- crate_name = "janitor backpack crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/service/janitor/janpremium
- name = "Janitor Premium Supplies"
- desc = "Do to the union for better supplies, we have desided to make a deal for you, In this crate you can get a brand new chem, Drying Angent this stuff is the work of slimes or magic! This crate also contains a rag to test out the Drying Angent magic, three wet floor signs, and some spare bottles of ammonia."
- cost = 1750
- access = ACCESS_JANITOR
- contains = list(/obj/item/caution,
- /obj/item/caution,
- /obj/item/caution,
- /obj/item/reagent_containers/rag,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/spray/drying_agent)
- crate_name = "janitor backpack crate"
-
-/datum/supply_pack/service/janitor/janpimp
- name = "Custodial Cruiser"
- desc = "Clown steal your ride? Assistant lock it in the dorms? Order a new one and get back to cleaning in style!"
- cost = 3000
- access = ACCESS_JANITOR
- contains = list(/obj/vehicle/ridden/janicart,
- /obj/item/key/janitor)
- crate_name = "janitor ride crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/service/mule
- name = "MULEbot Crate"
- desc = "Pink-haired Quartermaster not doing her job? Replace her with this tireless worker, today!"
- cost = 2000
- contains = list(/mob/living/simple_animal/bot/mulebot)
- crate_name = "\improper MULEbot Crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/service/party
- name = "Party Equipment"
- desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, and a bottle of patron, goldschlager, and shaker!"
- cost = 2000
- contains = list(/obj/item/storage/box/drinkingglasses,
- /obj/item/reagent_containers/food/drinks/shaker,
- /obj/item/reagent_containers/food/drinks/bottle/patron,
- /obj/item/reagent_containers/food/drinks/bottle/goldschlager,
- /obj/item/reagent_containers/food/drinks/ale,
- /obj/item/reagent_containers/food/drinks/ale,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/reagent_containers/food/drinks/beer,
- /obj/item/flashlight/glowstick,
- /obj/item/flashlight/glowstick/red,
- /obj/item/flashlight/glowstick/blue,
- /obj/item/flashlight/glowstick/cyan,
- /obj/item/flashlight/glowstick/orange,
- /obj/item/flashlight/glowstick/yellow,
- /obj/item/flashlight/glowstick/pink)
- crate_name = "party equipment crate"
-
-/datum/supply_pack/service/carpet
- name = "Premium Carpet Crate"
- desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains the classics."
- cost = 1000
- contains = list(/obj/item/stack/tile/carpet/fifty,
- /obj/item/stack/tile/carpet/fifty,
- /obj/item/stack/tile/carpet/black/fifty,
- /obj/item/stack/tile/carpet/black/fifty)
- crate_name = "premium carpet crate"
-
-/datum/supply_pack/service/carpet2
- name = "Premium Carpet Crate #2"
- desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains red, and monochrome"
- cost = 1000
- contains = list(/obj/item/stack/tile/carpet/blackred/fifty,
- /obj/item/stack/tile/carpet/blackred/fifty,
- /obj/item/stack/tile/carpet/monochrome/fifty,
- /obj/item/stack/tile/carpet/monochrome/fifty)
- crate_name = "premium carpet crate #2"
-
-/datum/supply_pack/service/lightbulbs
- name = "Replacement Lights"
- desc = "May the light of Aether shine upon this station! Or at least, the light of forty two light tubes and twenty one light bulbs as well as a light replacer."
- cost = 1200
- contains = list(/obj/item/storage/box/lights/mixed,
- /obj/item/storage/box/lights/mixed,
- /obj/item/storage/box/lights/mixed,
- /obj/item/lightreplacer)
- crate_name = "replacement lights"
-
-/datum/supply_pack/service/minerkit
- name = "Shaft Miner Starter Kit"
- desc = "All the miners died too fast? Assistant wants to get a taste of life off-station? Either way, this kit is the best way to turn a regular crewman into an ore-producing, monster-slaying machine. Contains meson goggles, a pickaxe, advanced mining scanner, cargo headset, ore bag, gasmask, and explorer suit. Requires QM access to open."
- cost = 2500
- access = ACCESS_QM
- contains = list(/obj/item/pickaxe/mini,
- /obj/item/clothing/glasses/meson,
- /obj/item/t_scanner/adv_mining_scanner/lesser,
- /obj/item/radio/headset/headset_cargo/mining,
- /obj/item/storage/bag/ore,
- /obj/item/clothing/suit/hooded/explorer/standard,
- /obj/item/clothing/mask/gas/explorer)
- crate_name = "shaft miner starter kit"
- crate_type = /obj/structure/closet/crate/secure
-
-//////////////////////////////////////////////////////////////////////////////
-/////////////////////////// Vending Restocks /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/service/vending/bartending
- name = "Bartending Supply Crate"
- desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
- cost = 2000
- contains = list(/obj/item/vending_refill/boozeomat,
- /obj/item/vending_refill/coffee,
- /obj/item/book/granter/action/drink_fling)
- crate_name = "bartending supply crate"
-
-/datum/supply_pack/service/vending/cigarette
- name = "Cigarette Supply Crate"
- desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill."
- cost = 1500
- contains = list(/obj/item/vending_refill/cigarette)
- crate_name = "cigarette supply crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/vending/games
- name = "Games Supply Crate"
- desc = "Get your game on with this game vending machine refill."
- cost = 1000
- contains = list(/obj/item/vending_refill/games)
- crate_name = "games supply crate"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/service/vending/snack
- name = "Snack Supply Crate"
- desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!"
- cost = 1500
- contains = list(/obj/item/vending_refill/snack)
- crate_name = "snacks supply crate"
-
-/datum/supply_pack/service/vending/cola
- name = "Softdrinks Supply Crate"
- desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!"
- cost = 1500
- contains = list(/obj/item/vending_refill/cola)
- crate_name = "soft drinks supply crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Organic /////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/organic
- group = "Food & Hydroponics"
- crate_type = /obj/structure/closet/crate/freezer
-
-/datum/supply_pack/organic/hydroponics/beekeeping_suits
- name = "Beekeeper Suit Crate"
- desc = "Bee business booming? Better be benevolent and boost botany by bestowing bi-Beekeeper-suits! Contains two beekeeper suits and matching headwear."
- cost = 1000
- contains = list(/obj/item/clothing/head/beekeeper_head,
- /obj/item/clothing/suit/beekeeper_suit,
- /obj/item/clothing/head/beekeeper_head,
- /obj/item/clothing/suit/beekeeper_suit)
- crate_name = "beekeeper suits"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/hydroponics/beekeeping_fullkit
- name = "Beekeeping Starter Crate"
- desc = "BEES BEES BEES. Contains three honey frames, a beekeeper suit and helmet, flyswatter, bee house, and, of course, a pure-bred Nanotrasen-Standardized Queen Bee!"
- cost = 1500
- contains = list(/obj/structure/beebox/unwrenched,
- /obj/item/honey_frame,
- /obj/item/honey_frame,
- /obj/item/honey_frame,
- /obj/item/queen_bee/bought,
- /obj/item/clothing/head/beekeeper_head,
- /obj/item/clothing/suit/beekeeper_suit,
- /obj/item/melee/flyswatter)
- crate_name = "beekeeping starter crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/candy
- name = "Candy Crate"
- desc = "For people that have a insatiable sweet tooth! Has ten candies to be eaten up.."
- cost = 2500
- var/num_contained = 10 //number of items picked to be contained in a randomised crate
- contains = list(/obj/item/reagent_containers/food/snacks/candy,
- /obj/item/reagent_containers/food/snacks/lollipop,
- /obj/item/reagent_containers/food/snacks/gumball,
- /obj/item/reagent_containers/food/snacks/chocolateegg,
- /obj/item/reagent_containers/food/snacks/donut,
- /obj/item/reagent_containers/food/snacks/cookie,
- /obj/item/reagent_containers/food/snacks/sugarcookie,
- /obj/item/reagent_containers/food/snacks/chococornet,
- /obj/item/reagent_containers/food/snacks/mint,
- /obj/item/reagent_containers/food/snacks/spiderlollipop,
- /obj/item/reagent_containers/food/snacks/chococoin,
- /obj/item/reagent_containers/food/snacks/fudgedice,
- /obj/item/reagent_containers/food/snacks/chocoorange,
- /obj/item/reagent_containers/food/snacks/honeybar,
- /obj/item/reagent_containers/food/snacks/tinychocolate,
- /obj/item/reagent_containers/food/snacks/spacetwinkie,
- /obj/item/reagent_containers/food/snacks/syndicake,
- /obj/item/reagent_containers/food/snacks/cheesiehonkers,
- /obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull,
- /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin,
- /obj/item/reagent_containers/food/snacks/candy_corn,
- /obj/item/reagent_containers/food/snacks/candiedapple,
- /obj/item/reagent_containers/food/snacks/chocolatebar,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/storage/fancy/heart_box,
- /obj/item/storage/fancy/donut_box)
- crate_name = "candy crate"
-
-/datum/supply_pack/organic/cutlery
- name = "Kitchen Cutlery Deluxe Set"
- desc = "Need to slice and dice away those ''Tomatos'' well we got what you need! From a nice set of knifes, forks, plates, glasses, and a whetstone for when you got some grizzle that is a bit harder to slice then normal."
- cost = 10000
- contraband = TRUE
- contains = list(/obj/item/sharpener,
- /obj/item/kitchen/fork,
- /obj/item/kitchen/fork,
- /obj/item/kitchen/knife,
- /obj/item/kitchen/knife,
- /obj/item/kitchen/knife,
- /obj/item/kitchen/knife,
- /obj/item/kitchen/knife/butcher,
- /obj/item/kitchen/knife/butcher,
- /obj/item/kitchen/rollingpin, //Deluxe for a reason
- /obj/item/trash/plate,
- /obj/item/trash/plate,
- /obj/item/trash/plate,
- /obj/item/trash/plate,
- /obj/item/reagent_containers/food/drinks/drinkingglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
- /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
- crate_name = "kitchen cutlery deluxe set"
-
-/datum/supply_pack/organic/food
- name = "Food Crate"
- desc = "Get things cooking with this crate full of useful ingredients! Contains a two dozen eggs, three bananas, and two bags of flour and rice, two cartons of milk, soymilk, as well as salt and pepper shakers, a enzyme and sugar bottle, and three slabs of monkeymeat."
- cost = 1000
- contains = list(/obj/item/reagent_containers/food/condiment/flour,
- /obj/item/reagent_containers/food/condiment/flour,
- /obj/item/reagent_containers/food/condiment/rice,
- /obj/item/reagent_containers/food/condiment/rice,
- /obj/item/reagent_containers/food/condiment/milk,
- /obj/item/reagent_containers/food/condiment/milk,
- /obj/item/reagent_containers/food/condiment/soymilk,
- /obj/item/reagent_containers/food/condiment/saltshaker,
- /obj/item/reagent_containers/food/condiment/peppermill,
- /obj/item/storage/fancy/egg_box,
- /obj/item/storage/fancy/egg_box,
- /obj/item/reagent_containers/food/condiment/enzyme,
- /obj/item/reagent_containers/food/condiment/sugar,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
- /obj/item/reagent_containers/food/snacks/grown/banana,
- /obj/item/reagent_containers/food/snacks/grown/banana,
- /obj/item/reagent_containers/food/snacks/grown/banana)
- crate_name = "food crate"
-
-/datum/supply_pack/organic/cream_piee
- name = "High-yield Clown-grade Cream Pie Crate"
- desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results."
- cost = 6000
- contains = list(/obj/item/storage/backpack/duffelbag/clown/cream_pie)
- crate_name = "party equipment crate"
- contraband = TRUE
- access = ACCESS_THEATRE
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/organic/hunting
- name = "Huntting gear"
- desc = "Even in space, we can fine prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a huntting shotgun. "
- cost = 3500
- contraband = TRUE
- contains = list(/obj/item/clothing/head/flatcap,
- /obj/item/clothing/suit/hooded/wintercoat/captain,
- /obj/item/reagent_containers/food/drinks/bottle/cognac,
- /obj/item/storage/fancy/cigarettes/cigars/havana,
- /obj/item/clothing/gloves/color/white,
- /obj/item/clothing/under/rank/curator,
- /obj/item/gun/ballistic/shotgun/lethal)
- access = ACCESS_ARMORY
- crate_name = "sporting crate"
- crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:(
-
-/datum/supply_pack/organic/hydroponics
- name = "Hydroponics Crate"
- desc = "Supplies for growing a great garden! Contains two bottles of ammonia, two Plant-B-Gone spray bottles, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron."
- cost = 1500
- contains = list(/obj/item/reagent_containers/spray/plantbgone,
- /obj/item/reagent_containers/spray/plantbgone,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/reagent_containers/glass/bottle/ammonia,
- /obj/item/hatchet,
- /obj/item/cultivator,
- /obj/item/plant_analyzer,
- /obj/item/clothing/gloves/botanic_leather,
- /obj/item/clothing/suit/apron)
- crate_name = "hydroponics crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/hydroponics/hydrotank
- name = "Hydroponics Backpack Crate"
- desc = "Bring on the flood with this high-capacity backpack crate. Contains 500 units of life-giving H2O. Requires hydroponics access to open."
- cost = 1000
- access = ACCESS_HYDROPONICS
- contains = list(/obj/item/watertank)
- crate_name = "hydroponics backpack crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/organic/mre
- name = "MRE supply kit (emergency rations)"
- desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
- cost = 2000
- contains = list(/obj/item/storage/box/mre/menu1/safe,
- /obj/item/storage/box/mre/menu1/safe,
- /obj/item/storage/box/mre/menu2/safe,
- /obj/item/storage/box/mre/menu2/safe,
- /obj/item/storage/box/mre/menu3,
- /obj/item/storage/box/mre/menu4/safe)
- crate_name = "MRE crate (emergency rations)"
-
-/datum/supply_pack/organic/pizza
- name = "Pizza Crate"
- desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!"
- cost = 6000 // Best prices this side of the galaxy.
- contains = list(/obj/item/pizzabox/margherita,
- /obj/item/pizzabox/mushroom,
- /obj/item/pizzabox/meat,
- /obj/item/pizzabox/vegetable,
- /obj/item/pizzabox/pineapple)
- crate_name = "pizza crate"
- var/static/anomalous_box_provided = FALSE
-
-/datum/supply_pack/organic/pizza/fill(obj/structure/closet/crate/C)
- . = ..()
- if(!anomalous_box_provided)
- for(var/obj/item/pizzabox/P in C)
- if(prob(1)) //1% chance for each box, so 4% total chance per order
- var/obj/item/pizzabox/infinite/fourfiveeight = new(C)
- fourfiveeight.boxtag = P.boxtag
- qdel(P)
- anomalous_box_provided = TRUE
- log_game("An anomalous pizza box was provided in a pizza crate at during cargo delivery")
- if(prob(50))
- addtimer(CALLBACK(src, .proc/anomalous_pizza_report), rand(300, 1800))
- else
- message_admins("An anomalous pizza box was silently created with no command report in a pizza crate delivery.")
- break
-
-/datum/supply_pack/organic/pizza/proc/anomalous_pizza_report()
- print_command_report("[station_name()], our anomalous materials divison has reported a missing object that is highly likely to have been sent to your station during a routine cargo \
- delivery. Please search all crates and manifests provided with the delivery and return the object if is located. The object resembles a standard \[DATA EXPUNGED\] and is to be \
- considered \[REDACTED\] and returned at your leisure. Note that objects the anomaly produces are specifically attuned exactly to the individual opening the anomaly; regardless \
- of species, the individual will find the object edible and it will taste great according to their personal definitions, which vary significantly based on person and species.")
-
-/datum/supply_pack/organic/potted_plants
- name = "Potted Plants Crate"
- desc = "Spruce up the station with these lovely plants! Contains a random assortment of five potted plants from Nanotrasen's potted plant research division. Warranty void if thrown."
- cost = 700
- contains = list(/obj/item/twohanded/required/kirbyplants/random,
- /obj/item/twohanded/required/kirbyplants/random,
- /obj/item/twohanded/required/kirbyplants/random,
- /obj/item/twohanded/required/kirbyplants/random,
- /obj/item/twohanded/required/kirbyplants/random)
- crate_name = "potted plants crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/seeds
- name = "Seeds Crate"
- desc = "Big things have small beginnings. Contains thirteen different seeds."
- cost = 1000
- contains = list(/obj/item/seeds/chili,
- /obj/item/seeds/berry,
- /obj/item/seeds/corn,
- /obj/item/seeds/eggplant,
- /obj/item/seeds/tomato,
- /obj/item/seeds/soya,
- /obj/item/seeds/wheat,
- /obj/item/seeds/wheat/rice,
- /obj/item/seeds/carrot,
- /obj/item/seeds/sunflower,
- /obj/item/seeds/chanter,
- /obj/item/seeds/potato,
- /obj/item/seeds/sugarcane)
- crate_name = "seeds crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-/datum/supply_pack/organic/vday
- name = "Surplus Valentine Crate"
- desc = "Turns out we got warehouses of this love-y dove-y crap. Were sending out small barged buddle of Valentine gear. This crate has two boxes of chocolate, three poppy flowers, five candy hearts, and three cards."
- cost = 3000
- contraband = TRUE
- contains = list(/obj/item/storage/fancy/heart_box,
- /obj/item/storage/fancy/heart_box,
- /obj/item/reagent_containers/food/snacks/grown/poppy,
- /obj/item/reagent_containers/food/snacks/grown/poppy,
- /obj/item/reagent_containers/food/snacks/grown/poppy,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/reagent_containers/food/snacks/candyheart,
- /obj/item/valentine,
- /obj/item/valentine,
- /obj/item/valentine)
- crate_name = "valentine crate"
- crate_type = /obj/structure/closet/crate/secure
-
-/datum/supply_pack/organic/exoticseeds
- name = "Exotic Seeds Crate"
- desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
- cost = 1500
- contains = list(/obj/item/seeds/nettle,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/replicapod,
- /obj/item/seeds/plump,
- /obj/item/seeds/liberty,
- /obj/item/seeds/amanita,
- /obj/item/seeds/reishi,
- /obj/item/seeds/banana,
- /obj/item/seeds/eggplant/eggy,
- /obj/item/seeds/random,
- /obj/item/seeds/random)
- crate_name = "exotic seeds crate"
- crate_type = /obj/structure/closet/crate/hydroponics
-
-//////////////////////////////////////////////////////////////////////////////
-////////////////////////////// Livestock /////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/critter
- group = "Livestock"
- crate_type = /obj/structure/closet/crate/critter
-
-/datum/supply_pack/critter/butterfly
- name = "Butterflies Crate"
- desc = "Not a very dangerous insect, but they do give off a better image than, say, flies or cockroaches."//is that a motherfucking worm reference
- contraband = TRUE
- cost = 5000
- contains = list(/mob/living/simple_animal/butterfly)
- crate_name = "entomology samples crate"
-
-/datum/supply_pack/critter/butterfly/generate()
- . = ..()
- for(var/i in 1 to 49)
- new /mob/living/simple_animal/butterfly(.)
-
-/datum/supply_pack/critter/cat
- name = "Cat Crate"
- desc = "The cat goes meow! Comes with a collar and a nice cat toy! Cheeseburger not included."//i can't believe im making this reference
- cost = 5000 //Cats are worth as much as corgis.
- contains = list(/mob/living/simple_animal/pet/cat,
- /obj/item/clothing/neck/petcollar,
- /obj/item/toy/cattoy)
- crate_name = "cat crate"
-
-/datum/supply_pack/critter/cat/generate()
- . = ..()
- if(prob(50))
- var/mob/living/simple_animal/pet/cat/C = locate() in .
- qdel(C)
- new /mob/living/simple_animal/pet/cat/Proc(.)
-
-/datum/supply_pack/critter/chick
- name = "Chicken Crate"
- desc = "The chicken goes bwaak!"
- cost = 2000
- contains = list( /mob/living/simple_animal/chick)
- crate_name = "chicken crate"
-
-/datum/supply_pack/critter/crab
- name = "Crab Rocket"
- desc = "CRAAAAAAB ROCKET. CRAB ROCKET. CRAB ROCKET. CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB ROCKET. CRAFT. ROCKET. BUY. CRAFT ROCKET. CRAB ROOOCKET. CRAB ROOOOCKET. CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB ROOOOOOOOOOOOOOOOOOOOOOCK EEEEEEEEEEEEEEEEEEEEEEEEE EEEETTTTTTTTTTTTAAAAAAAAA AAAHHHHHHHHHHHHH. CRAB ROCKET. CRAAAB ROCKEEEEEEEEEGGGGHHHHTT CRAB CRAB CRAABROCKET CRAB ROCKEEEET."//fun fact: i actually spent like 10 minutes and transcribed the entire video.
- cost = 5000
- contains = list(/mob/living/simple_animal/crab)
- crate_name = "look sir free crabs"
- DropPodOnly = TRUE
-
-/datum/supply_pack/critter/crab/generate()
- . = ..()
- for(var/i in 1 to 49)
- new /mob/living/simple_animal/crab(.)
-
-/datum/supply_pack/critter/corgi
- name = "Corgi Crate"
- desc = "Considered the optimal dog breed by thousands of research scientists, this Corgi is but one dog from the millions of Ian's noble bloodline. Comes with a cute collar!"
- cost = 5000
- contains = list(/mob/living/simple_animal/pet/dog/corgi,
- /obj/item/clothing/neck/petcollar)
- crate_name = "corgi crate"
-
-/datum/supply_pack/critter/corgi/generate()
- . = ..()
- if(prob(50))
- var/mob/living/simple_animal/pet/dog/corgi/D = locate() in .
- if(D.gender == FEMALE)
- qdel(D)
- new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
-
-/datum/supply_pack/critter/corgis/exotic
- name = "Exotic Corgi Crate"
- desc = "Corgis fit for a king, these corgis come in a unique color to signify their superiority. Comes with a cute collar!"
- cost = 5500
- contains = list(/mob/living/simple_animal/pet/dog/corgi/exoticcorgi,
- /obj/item/clothing/neck/petcollar)
- crate_name = "exotic corgi crate"
-
-/datum/supply_pack/critter/cow
- name = "Cow Crate"
- desc = "The cow goes moo!"
- cost = 3000
- contains = list(/mob/living/simple_animal/cow)
- crate_name = "cow crate"
-
-/datum/supply_pack/critter/fox
- name = "Fox Crate"
- desc = "The fox goes...? Comes with a collar!"//what does the fox say
- cost = 5000
- contains = list(/mob/living/simple_animal/pet/fox,
- /obj/item/clothing/neck/petcollar)
- crate_name = "fox crate"
-
-/datum/supply_pack/critter/goat
- name = "Goat Crate"
- desc = "The goat goes baa! Warranty void if used as a replacement for Pete."
- cost = 2500
- contains = list(/mob/living/simple_animal/hostile/retaliate/goat)
- crate_name = "goat crate"
-
-/datum/supply_pack/critter/monkey
- name = "Monkey Cube Crate"
- desc = "Stop monkeying around! Contains seven monkey cubes. Just add water!"
- cost = 2000
- contains = list (/obj/item/storage/box/monkeycubes)
- crate_name = "monkey cube crate"
-
-/datum/supply_pack/critter/pug
- name = "Pug Crate"
- desc = "Like a normal dog, but... squished. Comes with a nice collar!"
- cost = 5000
- contains = list(/mob/living/simple_animal/pet/dog/pug,
- /obj/item/clothing/neck/petcollar)
- crate_name = "pug crate"
-
-/datum/supply_pack/organic/critter/kiwi
- name = "Space kiwi Crate"
- cost = 2000
- contains = list( /mob/living/simple_animal/kiwi)
- crate_name = "space kiwi crate"
-
-/datum/supply_pack/critter/snake
- name = "Snake Crate"
- desc = "Tired of these MOTHER FUCKING snakes on this MOTHER FUCKING space station? Then this isn't the crate for you. Contains three poisonous snakes."
- cost = 3000
- contains = list(/mob/living/simple_animal/hostile/retaliate/poison/snake,
- /mob/living/simple_animal/hostile/retaliate/poison/snake,
- /mob/living/simple_animal/hostile/retaliate/poison/snake)
- crate_name = "snake crate"
-
-/datum/supply_pack/critter/secbat
- name = "Security Bat Crate"
- desc = "Contains five security bats, perfect to Bat-up any security officer."
- cost = 2500
- contains = list(/mob/living/simple_animal/hostile/retaliate/bat/secbat,
- /mob/living/simple_animal/hostile/retaliate/bat/secbat,
- /mob/living/simple_animal/hostile/retaliate/bat/secbat,
- /mob/living/simple_animal/hostile/retaliate/bat/secbat,
- /mob/living/simple_animal/hostile/retaliate/bat/secbat)
- crate_name = "security bat crate"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Costumes & Toys /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/costumes_toys
- group = "Costumes & Toys"
-
-/datum/supply_pack/costumes_toys/randomised
- name = "Collectable Hats Crate"
- desc = "Flaunt your status with three unique, highly-collectable hats!"
- cost = 20000
- var/num_contained = 3 //number of items picked to be contained in a randomised crate
- contains = list(/obj/item/clothing/head/collectable/chef,
- /obj/item/clothing/head/collectable/paper,
- /obj/item/clothing/head/collectable/tophat,
- /obj/item/clothing/head/collectable/captain,
- /obj/item/clothing/head/collectable/beret,
- /obj/item/clothing/head/collectable/welding,
- /obj/item/clothing/head/collectable/flatcap,
- /obj/item/clothing/head/collectable/pirate,
- /obj/item/clothing/head/collectable/kitty,
- /obj/item/clothing/head/collectable/rabbitears,
- /obj/item/clothing/head/collectable/wizard,
- /obj/item/clothing/head/collectable/hardhat,
- /obj/item/clothing/head/collectable/HoS,
- /obj/item/clothing/head/collectable/HoP,
- /obj/item/clothing/head/collectable/thunderdome,
- /obj/item/clothing/head/collectable/swat,
- /obj/item/clothing/head/collectable/slime,
- /obj/item/clothing/head/collectable/police,
- /obj/item/clothing/head/collectable/slime,
- /obj/item/clothing/head/collectable/xenom,
- /obj/item/clothing/head/collectable/petehat)
- crate_name = "collectable hats crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/contraband
- name = "Contraband Crate"
- desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, dank, even some sponsored items...you know, the good stuff. Just keep it away from the cops, kay?"
- contraband = TRUE
- cost = 3000
- num_contained = 5 //SOME
- contains = list(/obj/item/poster/random_contraband,
- /obj/item/poster/random_contraband,
- /obj/item/reagent_containers/food/snacks/grown/cannabis,
- /obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow,
- /obj/item/reagent_containers/food/snacks/grown/cannabis/white,
- /obj/item/storage/pill_bottle/zoom,
- /obj/item/storage/pill_bottle/happy,
- /obj/item/storage/pill_bottle/lsd,
- /obj/item/storage/pill_bottle/aranesp,
- /obj/item/storage/pill_bottle/stimulant,
- /obj/item/toy/cards/deck/syndicate,
- /obj/item/reagent_containers/food/drinks/bottle/absinthe,
- /obj/item/clothing/under/syndicate/tacticool,
- /obj/item/storage/fancy/cigarettes/cigpack_syndicate,
- /obj/item/storage/fancy/cigarettes/cigpack_shadyjims,
- /obj/item/clothing/mask/gas/syndicate,
- /obj/item/clothing/neck/necklace/dope,
- /obj/item/vending_refill/donksoft,
- /obj/item/circuitboard/computer/arcade/amputation)
- crate_name = "crate"
-
-/datum/supply_pack/costumes_toys/foamforce
- name = "Foam Force Crate"
- desc = "Break out the big guns with eight Foam Force shotguns!"
- cost = 1000
- contains = list(/obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy,
- /obj/item/gun/ballistic/shotgun/toy)
- crate_name = "foam force crate"
-
-/datum/supply_pack/costumes_toys/foamforce/bonus
- name = "Foam Force Pistols Crate"
- desc = "Psst.. hey bud... remember those old foam force pistols that got discontinued for being too cool? Well I got two of those right here with your name on em. I'll even throw in a spare mag for each, waddya say?"
- contraband = TRUE
- cost = 4000
- contains = list(/obj/item/gun/ballistic/automatic/toy/pistol,
- /obj/item/gun/ballistic/automatic/toy/pistol,
- /obj/item/ammo_box/magazine/toy/pistol,
- /obj/item/ammo_box/magazine/toy/pistol)
- crate_name = "foam force crate"
-
-/datum/supply_pack/costumes_toys/formalwear
- name = "Formalwear Crate"
- desc = "You're gonna like the way you look, I guaranteed it. Contains an asston of fancy clothing."
- cost = 3000 //Lots of very expensive items. You gotta pay up to look good!
- contains = list(/obj/item/clothing/under/blacktango,
- /obj/item/clothing/under/assistantformal,
- /obj/item/clothing/under/assistantformal,
- /obj/item/clothing/under/lawyer/bluesuit,
- /obj/item/clothing/suit/toggle/lawyer,
- /obj/item/clothing/under/lawyer/purpsuit,
- /obj/item/clothing/suit/toggle/lawyer/purple,
- /obj/item/clothing/under/lawyer/blacksuit,
- /obj/item/clothing/suit/toggle/lawyer/black,
- /obj/item/clothing/accessory/waistcoat,
- /obj/item/clothing/neck/tie/blue,
- /obj/item/clothing/neck/tie/red,
- /obj/item/clothing/neck/tie/black,
- /obj/item/clothing/head/bowler,
- /obj/item/clothing/head/fedora,
- /obj/item/clothing/head/flatcap,
- /obj/item/clothing/head/beret,
- /obj/item/clothing/head/that,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/shoes/laceup,
- /obj/item/clothing/under/suit_jacket/charcoal,
- /obj/item/clothing/under/suit_jacket/navy,
- /obj/item/clothing/under/suit_jacket/burgundy,
- /obj/item/clothing/under/suit_jacket/checkered,
- /obj/item/clothing/under/suit_jacket/tan,
- /obj/item/lipstick/random)
- crate_name = "formalwear crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/clownpin
- name = "Hilarious Firing Pin Crate"
- desc = "I uh... I'm not really sure what this does. Wanna buy it?"
- cost = 5000
- contraband = TRUE
- contains = list(/obj/item/firing_pin/clown)
- crate_name = "toy crate" // It's /technically/ a toy. For the clown, at least.
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/lasertag
- name = "Laser Tag Crate"
- desc = "Foam Force is for boys. Laser Tag is for men. Contains three sets of red suits, blue suits, matching helmets, and matching laser tag guns."
- cost = 1500
- contains = list(/obj/item/gun/energy/laser/redtag,
- /obj/item/gun/energy/laser/redtag,
- /obj/item/gun/energy/laser/redtag,
- /obj/item/gun/energy/laser/bluetag,
- /obj/item/gun/energy/laser/bluetag,
- /obj/item/gun/energy/laser/bluetag,
- /obj/item/clothing/suit/redtag,
- /obj/item/clothing/suit/redtag,
- /obj/item/clothing/suit/redtag,
- /obj/item/clothing/suit/bluetag,
- /obj/item/clothing/suit/bluetag,
- /obj/item/clothing/suit/bluetag,
- /obj/item/clothing/head/helmet/redtaghelm,
- /obj/item/clothing/head/helmet/redtaghelm,
- /obj/item/clothing/head/helmet/redtaghelm,
- /obj/item/clothing/head/helmet/bluetaghelm,
- /obj/item/clothing/head/helmet/bluetaghelm,
- /obj/item/clothing/head/helmet/bluetaghelm)
- crate_name = "laser tag crate"
-
-/datum/supply_pack/costumes_toys/lasertag/pins
- name = "Laser Tag Firing Pins Crate"
- desc = "Three laser tag firing pins used in laser-tag units to ensure users are wearing their vests."
- cost = 3000
- contraband = TRUE
- contains = list(/obj/item/storage/box/lasertagpins)
- crate_name = "laser tag crate"
-
-/datum/supply_pack/costumes_toys/costume_original
- name = "Original Costume Crate"
- desc = "Reenact Shakespearean plays with this assortment of outfits. Contains eight different costumes!"
- cost = 1000
- contains = list(/obj/item/clothing/head/snowman,
- /obj/item/clothing/suit/snowman,
- /obj/item/clothing/head/chicken,
- /obj/item/clothing/suit/chickensuit,
- /obj/item/clothing/mask/gas/monkeymask,
- /obj/item/clothing/suit/monkeysuit,
- /obj/item/clothing/head/cardborg,
- /obj/item/clothing/suit/cardborg,
- /obj/item/clothing/head/xenos,
- /obj/item/clothing/suit/xenos,
- /obj/item/clothing/suit/hooded/ian_costume,
- /obj/item/clothing/suit/hooded/carp_costume,
- /obj/item/clothing/suit/hooded/bee_costume)
- crate_name = "original costume crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/costume
- name = "Standard Costume Crate"
- desc = "Supply the station's entertainers with the equipment of their trade with these Nanotrasen-approved costumes! Contains a full clown and mime outfit, along with a bike horn and a bottle of nothing."
- cost = 1000
- access = ACCESS_THEATRE
- contains = list(/obj/item/storage/backpack/clown,
- /obj/item/clothing/shoes/clown_shoes,
- /obj/item/clothing/mask/gas/clown_hat,
- /obj/item/clothing/under/rank/clown,
- /obj/item/bikehorn,
- /obj/item/clothing/under/rank/mime,
- /obj/item/clothing/shoes/sneakers/black,
- /obj/item/clothing/gloves/color/white,
- /obj/item/clothing/mask/gas/mime,
- /obj/item/clothing/head/beret,
- /obj/item/clothing/suit/suspenders,
- /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing,
- /obj/item/storage/backpack/mime)
- crate_name = "standard costume crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/toys
- name = "Toy Crate"
- desc = "Who cares about pride and accomplishment? Skip the gaming and get straight to the sweet rewards with this product! Contains five random toys. Warranty void if used to prank research directors."
- cost = 1500 // or play the arcade machines ya lazy bum
- num_contained = 5
- contains = list(/obj/item/storage/box/snappops,
- /obj/item/toy/talking/AI,
- /obj/item/toy/talking/codex_gigas,
- /obj/item/clothing/under/syndicate/tacticool,
- /obj/item/toy/sword ,
- /obj/item/toy/gun,
- /obj/item/gun/ballistic/shotgun/toy/crossbow,
- /obj/item/storage/box/fakesyndiesuit,
- /obj/item/storage/crayons,
- /obj/item/toy/spinningtoy,
- /obj/item/toy/prize/ripley,
- /obj/item/toy/prize/fireripley,
- /obj/item/toy/prize/deathripley,
- /obj/item/toy/prize/gygax,
- /obj/item/toy/prize/durand,
- /obj/item/toy/prize/honk,
- /obj/item/toy/prize/marauder,
- /obj/item/toy/prize/seraph,
- /obj/item/toy/prize/mauler,
- /obj/item/toy/prize/odysseus,
- /obj/item/toy/prize/phazon,
- /obj/item/toy/prize/reticence,
- /obj/item/toy/cards/deck,
- /obj/item/toy/nuke,
- /obj/item/toy/minimeteor,
- /obj/item/toy/redbutton,
- /obj/item/toy/talking/owl,
- /obj/item/toy/talking/griffin,
- /obj/item/coin/antagtoken,
- /obj/item/stack/tile/fakespace/loaded,
- /obj/item/stack/tile/fakepit/loaded,
- /obj/item/toy/toy_xeno,
- /obj/item/storage/box/actionfigure,
- /obj/item/restraints/handcuffs/fake,
- /obj/item/grenade/chem_grenade/glitter/pink,
- /obj/item/grenade/chem_grenade/glitter/blue,
- /obj/item/grenade/chem_grenade/glitter/white,
- /obj/item/toy/eightball,
- /obj/item/toy/windupToolbox,
- /obj/item/toy/clockwork_watch,
- /obj/item/toy/toy_dagger,
- /obj/item/extendohand/acme,
- /obj/item/hot_potato/harmless/toy,
- /obj/item/card/emagfake,
- /obj/item/clothing/shoes/wheelys,
- /obj/item/clothing/shoes/kindleKicks,
- /obj/item/storage/belt/military/snack,
- /obj/item/toy/eightball,
- /obj/item/vending_refill/donksoft)
- crate_name = "toy crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/plush
- name = "Plush Crate"
- desc = "Plush tide station wide. Contains 5 random plushies for you to love. Warranty void if your love violates the terms of use."
- cost = 1500 // or play the arcade machines ya lazy bum
- num_contained = 5
- contains = list(/obj/item/toy/plush/random,
- /obj/item/toy/plush/random,
- /obj/item/toy/plush/random,
- /obj/item/toy/plush/random,
- /obj/item/toy/plush/random) //I'm lazy
- crate_name = "plushie crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/wizard
- name = "Wizard Costume Crate"
- desc = "Pretend to join the Wizard Federation with this full wizard outfit! Nanotrasen would like to remind its employees that actually joining the Wizard Federation is subject to termination of job and life."
- cost = 2000
- contains = list(/obj/item/staff,
- /obj/item/clothing/suit/wizrobe/fake,
- /obj/item/clothing/shoes/sandal,
- /obj/item/clothing/head/wizard/fake)
- crate_name = "wizard costume crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C)
- var/list/L = contains.Copy()
- for(var/i in 1 to num_contained)
- var/item = pick_n_take(L)
- new item(C)
-
-/datum/supply_pack/costumes_toys/wardrobes/autodrobe
- name = "Autodrobe Supply Crate"
- desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill."
- cost = 1500
- contains = list(/obj/item/vending_refill/autodrobe)
- crate_name = "autodrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/cargo
- name = "Cargo Wardrobe Supply Crate"
- desc = "This crate contains a refill for the CargoDrobe."
- cost = 750
- contains = list(/obj/item/vending_refill/wardrobe/cargo_wardrobe)
- crate_name = "cargo department supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/engineering
- name = "Engineering Wardrobe Supply Crate"
- desc = "This crate contains refills for the EngiDrobe and AtmosDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/engi_wardrobe,
- /obj/item/vending_refill/wardrobe/atmos_wardrobe)
- crate_name = "engineering department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/general
- name = "General Wardrobes Supply Crate"
- desc = "This crate contains refills for the CuraDrobe, BarDrobe, ChefDrobe, JaniDrobe, ChapDrobe."
- cost = 3750
- contains = list(/obj/item/vending_refill/wardrobe/curator_wardrobe,
- /obj/item/vending_refill/wardrobe/bar_wardrobe,
- /obj/item/vending_refill/wardrobe/chef_wardrobe,
- /obj/item/vending_refill/wardrobe/jani_wardrobe,
- /obj/item/vending_refill/wardrobe/chap_wardrobe)
- crate_name = "general wardrobes vendor refills"
-
-/datum/supply_pack/costumes_toys/wardrobes/hydroponics
- name = "Hydrobe Supply Crate"
- desc = "This crate contains a refill for the Hydrobe."
- cost = 750
- contains = list(/obj/item/vending_refill/wardrobe/hydro_wardrobe)
- crate_name = "hydrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/medical
- name = "Medical Wardrobe Supply Crate"
- desc = "This crate contains refills for the MediDrobe, ChemDrobe, GeneDrobe, and ViroDrobe."
- cost = 3000
- contains = list(/obj/item/vending_refill/wardrobe/medi_wardrobe,
- /obj/item/vending_refill/wardrobe/chem_wardrobe,
- /obj/item/vending_refill/wardrobe/gene_wardrobe,
- /obj/item/vending_refill/wardrobe/viro_wardrobe)
- crate_name = "medical department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/science
- name = "Science Wardrobe Supply Crate"
- desc = "This crate contains refills for the SciDrobe and RoboDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/robo_wardrobe,
- /obj/item/vending_refill/wardrobe/science_wardrobe)
- crate_name = "science department wardrobe supply crate"
-
-/datum/supply_pack/costumes_toys/wardrobes/security
- name = "Security Wardrobe Supply Crate"
- desc = "This crate contains refills for the SecDrobe and LawDrobe."
- cost = 1500
- contains = list(/obj/item/vending_refill/wardrobe/sec_wardrobe,
- /obj/item/vending_refill/wardrobe/law_wardrobe)
- crate_name = "security department supply crate"
-
-/datum/supply_pack/costumes_toys/kinkmate
- name = "Kinkmate construction kit"
- cost = 2000
- contraband = TRUE
- contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate)
- crate_name = "Kinkmate construction kit"
-
-//////////////////////////////////////////////////////////////////////////////
-//////////////////////////// Miscellaneous ///////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////
-
-/datum/supply_pack/misc
- group = "Miscellaneous Supplies"
-
-/datum/supply_pack/misc/artsupply
- name = "Art Supplies"
- desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!"
- cost = 800
- contains = list(/obj/structure/easel,
- /obj/structure/easel,
- /obj/item/canvas/nineteenXnineteen,
- /obj/item/canvas/nineteenXnineteen,
- /obj/item/canvas/twentythreeXnineteen,
- /obj/item/canvas/twentythreeXnineteen,
- /obj/item/canvas/twentythreeXtwentythree,
- /obj/item/canvas/twentythreeXtwentythree,
- /obj/item/storage/crayons,
- /obj/item/storage/crayons,
- /obj/item/toy/crayon/rainbow,
- /obj/item/toy/crayon/white,
- /obj/item/toy/crayon/white)
- crate_name = "art supply crate"
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/misc/captain_pen
- name = "Captain Pen"
- desc = "A spare Captain fountain pen."
- access = ACCESS_CAPTAIN
- cost = 10000
- contains = list(/obj/item/pen/fountain/captain)
- crate_name = "captain pen"
- crate_type = /obj/structure/closet/crate/secure/weapon //It is a combat pen
-
-/datum/supply_pack/misc/bicycle
- name = "Bicycle"
- desc = "Nanotrasen reminds all employees to never toy with powers outside their control."
- cost = 1000000
- contains = list(/obj/vehicle/ridden/bicycle)
- crate_name = "Bicycle Crate"
- crate_type = /obj/structure/closet/crate/large
-
-/datum/supply_pack/misc/bigband
- name = "Big Band Instrument Collection"
- desc = "Get your sad station movin' and groovin' with this fine collection! Contains nine different instruments!"
- cost = 5000
- crate_name = "Big band musical instruments collection"
- contains = list(/obj/item/instrument/violin,
- /obj/item/instrument/guitar,
- /obj/item/instrument/glockenspiel,
- /obj/item/instrument/accordion,
- /obj/item/instrument/saxophone,
- /obj/item/instrument/trombone,
- /obj/item/instrument/recorder,
- /obj/item/instrument/harmonica,
- /obj/structure/piano/unanchored)
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/misc/book_crate
- name = "Book Crate"
- desc = "Surplus from the Nanotrasen Archives, these five books are sure to be good reads."
- cost = 1500
- contains = list(/obj/item/book/codex_gigas,
- /obj/item/book/manual/random/,
- /obj/item/book/manual/random/,
- /obj/item/book/manual/random/,
- /obj/item/book/random/triple)
- crate_type = /obj/structure/closet/crate/wooden
-
-/datum/supply_pack/misc/paper
- name = "Bureaucracy Crate"
- desc = "High stacks of papers on your desk Are a big problem - make it Pea-sized with these bureaucratic supplies! Contains five pens, some camera film, hand labeler supplies, a paper bin, three folders, two clipboards and two stamps as well as a briefcase."//that was too forced
- cost = 1500
- contains = list(/obj/structure/filingcabinet/chestdrawer/wheeled,
- /obj/item/camera_film,
- /obj/item/hand_labeler,
- /obj/item/hand_labeler_refill,
- /obj/item/hand_labeler_refill,
- /obj/item/paper_bin,
- /obj/item/pen/fourcolor,
- /obj/item/pen/fourcolor,
- /obj/item/pen,
- /obj/item/pen/blue,
- /obj/item/pen/red,
- /obj/item/folder/blue,
- /obj/item/folder/red,
- /obj/item/folder/yellow,
- /obj/item/clipboard,
- /obj/item/clipboard,
- /obj/item/stamp,
- /obj/item/stamp/denied,
- /obj/item/storage/briefcase)
- crate_name = "bureaucracy crate"
-
-/datum/supply_pack/misc/fountainpens
- name = "Calligraphy Crate"
- desc = "Sign death warrants in style with these seven executive fountain pens."
- cost = 700
- contains = list(/obj/item/storage/box/fountainpens,
- /obj/item/paper_bin)
- crate_type = /obj/structure/closet/crate/wooden
- crate_name = "calligraphy crate"
-
-/datum/supply_pack/misc/wrapping_paper
- name = "Festive Wrapping Paper Crate"
- desc = "Want to mail your loved ones gift-wrapped chocolates, stuffed animals, the Clown's severed head? You can do all that, with this crate full of wrapping paper."
- cost = 1000
- contains = list(/obj/item/stack/wrapping_paper)
- crate_type = /obj/structure/closet/crate/wooden
- crate_name = "festive wrapping paper crate"
-
-/datum/supply_pack/misc/paper_work
- name = "Freelance Paper work"
- desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (10) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up.
- cost = 700 // Net of 0 credits
- contains = list(/obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/folder/paperwork,
- /obj/item/pen/fountain,
- /obj/item/pen/fountain,
- /obj/item/pen/fountain,
- /obj/item/pen/fountain,
- /obj/item/pen/fountain)
- crate_name = "Paperwork"
-
-/datum/supply_pack/misc/funeral
- name = "Funeral Supply crate"
- desc = "At the end of the day, someone's gonna want someone dead. Give them a proper send-off with these funeral supplies! Contains a coffin with burial garmets and flowers."
- cost = 600
- contains = list(/obj/item/clothing/under/burial,
- /obj/item/reagent_containers/food/snacks/grown/harebell,
- /obj/item/reagent_containers/food/snacks/grown/poppy/geranium
- )
- crate_name = "coffin"
- crate_type = /obj/structure/closet/crate/coffin
-
-/datum/supply_pack/misc/jukebox
- name = "Jukebox"
- cost = 35000
- contains = list(/obj/machinery/jukebox)
- crate_name = "Jukebox"
-
-/datum/supply_pack/misc/lewd
- name = "Lewd Crate" // OwO
- desc = "Psss want to have a good time with your sluts? Well I got what you want maid clothing, dildos, collars and more!"
- cost = 5000
- contraband = TRUE
- contains = list(/obj/item/dildo/custom,
- /obj/item/dildo/custom,
- /obj/item/vending_refill/kink,
- /obj/item/vending_refill/kink,
- /obj/item/clothing/under/maid,
- /obj/item/clothing/under/maid,
- /obj/item/electropack/shockcollar,
- /obj/item/electropack/shockcollar,
- /obj/item/restraints/handcuffs/fake/kinky,
- /obj/item/restraints/handcuffs/fake/kinky,
- /obj/item/clothing/head/kitty/genuine, // Why its illegal
- /obj/item/clothing/head/kitty/genuine,
- /obj/item/storage/pill_bottle/penis_enlargement,
- /obj/structure/reagent_dispensers/keg/aphro)
- crate_name = "lewd kit"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/misc/lewdkeg
- name = "Lewd Deluxe Keg"
- desc = "That other stuff not getting you ready? Well I have a Chemslut making tons of the good stuff."
- cost = 7000 //It can be a weapon
- contraband = TRUE
- contains = list(/obj/structure/reagent_dispensers/keg/aphro/strong)
- crate_name = "deluxe keg"
- crate_type = /obj/structure/closet/crate
-
-/datum/supply_pack/misc/religious_supplies
- name = "Religious Supplies Crate"
- desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets."
- cost = 4000 // it costs so much because the Space Church is ran by Space Jews
- contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater,
- /obj/item/reagent_containers/food/drinks/bottle/holywater,
- /obj/item/storage/book/bible/booze,
- /obj/item/storage/book/bible/booze,
- /obj/item/clothing/suit/hooded/chaplain_hoodie,
- /obj/item/clothing/suit/hooded/chaplain_hoodie
- )
- crate_name = "religious supplies crate"
-
-/datum/supply_pack/misc/randomised/promiscuous
- name = "Promiscuous Organs"
- desc = "Do YOU want to have more genital? Well we have just the thing for you~. This crate has two autosurgeon, that will let you have a new sex, organ to impress that hot stud and or chick."
- cost = 4000 //Only get 2!
- contraband = TRUE
- var/num_contained = 2
- contains = list(/obj/item/autosurgeon/penis,
- /obj/item/autosurgeon/testicles,
- /obj/item/autosurgeon/vagina,
- /obj/item/autosurgeon/breasts,
- /obj/item/autosurgeon/womb)
- crate_name = "promiscuous organs"
-
-/datum/supply_pack/misc/toner
- name = "Toner Crate"
- desc = "Spent too much ink printing butt pictures? Fret not, with these six toner refills, you'll be printing butts 'till the cows come home!'"
- cost = 1000
- contains = list(/obj/item/toner,
- /obj/item/toner,
- /obj/item/toner,
- /obj/item/toner,
- /obj/item/toner,
- /obj/item/toner)
- crate_name = "toner crate"
diff --git a/code/modules/cargo/packs/armory.dm b/code/modules/cargo/packs/armory.dm
new file mode 100644
index 0000000000..ee983784fe
--- /dev/null
+++ b/code/modules/cargo/packs/armory.dm
@@ -0,0 +1,244 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Armory //////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/security/armory
+ group = "Armory"
+ access = ACCESS_ARMORY
+ crate_type = /obj/structure/closet/crate/secure/weapon
+
+/datum/supply_pack/security/armory/bulletarmor
+ name = "Bulletproof Armor Crate"
+ desc = "Contains three sets of bulletproof armor. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
+ cost = 1250
+ contains = list(/obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/suit/armor/bulletproof)
+ crate_name = "bulletproof armor crate"
+
+/datum/supply_pack/security/armory/bullethelmets
+ name = "Bulletproof Helmet Crate"
+ desc = "Contains three sets of bulletproof helmets. Guaranteed to reduce a bullet's stopping power by over half. Requires Armory access to open."
+ cost = 1250
+ contains = list(/obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/head/helmet/alt)
+ crate_name = "bulletproof helmet crate"
+
+/datum/supply_pack/security/armory/chemimp
+ name = "Chemical Implants Crate"
+ desc = "Contains five Remote Chemical implants. Requires Armory access to open."
+ cost = 1700
+ contains = list(/obj/item/storage/box/chemimp)
+ crate_name = "chemical implant crate"
+
+/datum/supply_pack/security/armory/combatknives
+ name = "Combat Knives Crate"
+ desc = "Contains three sharpened combat knives. Each knife guaranteed to fit snugly inside any Nanotrasen-standard boot. Requires Armory access to open."
+ cost = 3200
+ contains = list(/obj/item/kitchen/knife/combat,
+ /obj/item/kitchen/knife/combat,
+ /obj/item/kitchen/knife/combat)
+ crate_name = "combat knife crate"
+
+/datum/supply_pack/security/armory/ballistic
+ name = "Combat Shotguns Crate"
+ desc = "For when the enemy absolutely needs to be replaced with lead. Contains three Aussec-designed Combat Shotguns, with three Shotgun Bandoliers, as well as seven buchshot and 12g shotgun slugs. Requires Armory access to open."
+ cost = 8000
+ contains = list(/obj/item/gun/ballistic/shotgun/automatic/combat,
+ /obj/item/gun/ballistic/shotgun/automatic/combat,
+ /obj/item/gun/ballistic/shotgun/automatic/combat,
+ /obj/item/storage/belt/bandolier,
+ /obj/item/storage/belt/bandolier,
+ /obj/item/storage/belt/bandolier,
+ /obj/item/storage/box/lethalshot,
+ /obj/item/storage/box/lethalslugs)
+ crate_name = "combat shotguns crate"
+
+/datum/supply_pack/security/armory/dragnetgun
+ name = "DRAGnet gun Crate"
+ desc = "Contains two DRAGnet gun. A Dynamic Rapid-Apprehension of the Guilty net the revolution in law enforcement technology that YOU Want! Requires Armory access to open."
+ cost = 3250
+ contains = list(/obj/item/gun/energy/e_gun/dragnet,
+ /obj/item/gun/energy/e_gun/dragnet)
+ crate_name = "anti riot net guns crate"
+
+/datum/supply_pack/security/armory/energy
+ name = "Energy Guns Crate"
+ desc = "Contains three Energy Guns, capable of firing both nonlethal and lethal blasts of light. Requires Armory access to open."
+ cost = 3250
+ contains = list(/obj/item/gun/energy/e_gun,
+ /obj/item/gun/energy/e_gun,
+ /obj/item/gun/energy/e_gun)
+ crate_name = "energy gun crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/security/armory/exileimp // Theres boxes in 2 lockers as well as gateway never realy being used sad
+ name = "Exile Implants Crate"
+ desc = "Contains five Exile implants. Requires Armory access to open."
+ cost = 1050 //stops endless points
+ contains = list(/obj/item/storage/box/exileimp)
+ crate_name = "exile implant crate"
+
+/datum/supply_pack/security/armory/mindshield
+ name = "Mindshield Implants Crate"
+ desc = "Prevent against radical thoughts with three Mindshield implants. Requires Armory access to open."
+ cost = 4000
+ contains = list(/obj/item/storage/lockbox/loyalty)
+ crate_name = "mindshield implant crate"
+
+/datum/supply_pack/security/armory/trackingimp
+ name = "Tracking Implants Crate"
+ desc = "Contains four tracking implants. Requires Armory access to open."
+ cost = 1050
+ contains = list(/obj/item/storage/box/trackimp)
+ crate_name = "tracking implant crate"
+
+/datum/supply_pack/security/armory/fire
+ name = "Incendiary Weapons Crate"
+ desc = "Burn, baby burn. Contains three incendiary grenades, seven incendiary slugs, three plasma canisters, and a flamethrower. Requires Brige access to open."
+ cost = 1750
+ access = ACCESS_HEADS
+ contains = list(/obj/item/flamethrower/full,
+ /obj/item/tank/internals/plasma,
+ /obj/item/tank/internals/plasma,
+ /obj/item/tank/internals/plasma,
+ /obj/item/grenade/chem_grenade/incendiary,
+ /obj/item/grenade/chem_grenade/incendiary,
+ /obj/item/grenade/chem_grenade/incendiary,
+ /obj/item/storage/box/fireshot)
+ crate_name = "incendiary weapons crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+ dangerous = TRUE
+
+/datum/supply_pack/security/armory/miniguns
+ name = "Personal Miniature Energy Guns"
+ desc = "Contains three miniature energy guns. Each gun has a disabler and a lethal option. Requires Armory access to open."
+ cost = 3000
+ contains = list(/obj/item/gun/energy/e_gun/mini,
+ /obj/item/gun/energy/e_gun/mini,
+ /obj/item/gun/energy/e_gun/mini)
+ crate_name = "personal energy guns crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/security/armory/laserarmor
+ name = "Reflector Vest Crate"
+ desc = "Contains two vests of highly reflective material. Each armor piece diffuses a laser's energy by over half, as well as offering a good chance to reflect the laser entirely. Requires Armory access to open."
+ cost = 2000
+ contains = list(/obj/item/clothing/suit/armor/laserproof,
+ /obj/item/clothing/suit/armor/laserproof)
+ crate_name = "reflector vest crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/security/armory/riotarmor
+ name = "Riot Armor Crate"
+ desc = "Contains three sets of heavy body armor. Advanced padding protects against close-ranged weaponry, making melee attacks feel only half as potent to the user. Requires Armory access to open."
+ cost = 1750
+ contains = list(/obj/item/clothing/suit/armor/riot,
+ /obj/item/clothing/suit/armor/riot,
+ /obj/item/clothing/suit/armor/riot)
+ crate_name = "riot armor crate"
+
+/datum/supply_pack/security/armory/riothelmets
+ name = "Riot Helmets Crate"
+ desc = "Contains three riot helmets. Requires Armory access to open."
+ cost = 1750
+ contains = list(/obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/head/helmet/riot,
+ /obj/item/clothing/head/helmet/riot)
+ crate_name = "riot helmets crate"
+
+/datum/supply_pack/security/armory/riotshields
+ name = "Riot Shields Crate"
+ desc = "For when the greytide gets really uppity. Contains three riot shields. Requires Armory access to open."
+ cost = 2200
+ contains = list(/obj/item/shield/riot,
+ /obj/item/shield/riot,
+ /obj/item/shield/riot)
+ crate_name = "riot shields crate"
+
+/datum/supply_pack/security/armory/riotshotguns
+ name = "Riot Shotgun Crate"
+ desc = "For when the greytide gets really uppity. Contains three riot shotguns, seven rubber shot and beanbag shells. Requires Armory access to open."
+ cost = 6500
+ contains = list(/obj/item/gun/ballistic/shotgun/riot,
+ /obj/item/gun/ballistic/shotgun/riot,
+ /obj/item/gun/ballistic/shotgun/riot,
+ /obj/item/storage/box/rubbershot,
+ /obj/item/storage/box/beanbag)
+ crate_name = "riot shotgun crate"
+
+/datum/supply_pack/security/armory/swat
+ name = "SWAT Crate"
+ desc = "Contains two fullbody sets of tough, fireproof, pressurized suits designed in a joint effort by IS-ERI and Nanotrasen. Each set contains a suit, helmet, mask, combat belt, and combat gloves. Requires Armory access to open."
+ cost = 6000
+ contains = list(/obj/item/clothing/head/helmet/swat/nanotrasen,
+ /obj/item/clothing/head/helmet/swat/nanotrasen,
+ /obj/item/clothing/suit/space/swat,
+ /obj/item/clothing/suit/space/swat,
+ /obj/item/clothing/mask/gas/sechailer/swat,
+ /obj/item/clothing/mask/gas/sechailer/swat,
+ /obj/item/storage/belt/military/assault,
+ /obj/item/storage/belt/military/assault,
+ /obj/item/clothing/gloves/combat,
+ /obj/item/clothing/gloves/combat)
+ crate_name = "swat crate"
+
+/datum/supply_pack/security/armory/swattasers //Lesser AEG tbh
+ name = "SWAT tatical tasers Crate"
+ desc = "Contains two tactical energy gun, these guns are able to tase, disable and lethal as well as hold a seclight. Requires Armory access to open."
+ cost = 7000
+ contains = list(/obj/item/gun/energy/e_gun/stun,
+ /obj/item/gun/energy/e_gun/stun)
+ crate_name = "swat taser crate"
+
+/datum/supply_pack/security/armory/woodstock
+ name = "Classic WoodStock Shotguns Crate"
+ desc = "Contains three rustic, pumpaction shotguns. Requires Armory access to open."
+ cost = 3000
+ contains = list(/obj/item/gun/ballistic/shotgun,
+ /obj/item/gun/ballistic/shotgun,
+ /obj/item/gun/ballistic/shotgun)
+ crate_name = "woodstock shotguns crate"
+
+/datum/supply_pack/security/armory/wt550
+ name = "WT-550 Semi-Auto Rifle Crate"
+ desc = "Contains two high-powered, semiautomatic rifles chambered in 4.6x30mm. Requires Armory access to open."
+ cost = 2550
+ contains = list(/obj/item/gun/ballistic/automatic/wt550,
+ /obj/item/gun/ballistic/automatic/wt550)
+ crate_name = "auto rifle crate"
+
+/datum/supply_pack/security/armory/wt550ammo
+ name = "WT-550 Semi-Auto SMG Ammo Crate"
+ desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
+ cost = 1750
+ contains = list(/obj/item/ammo_box/magazine/wt550m9,
+ /obj/item/ammo_box/magazine/wt550m9,
+ /obj/item/ammo_box/magazine/wt550m9,
+ /obj/item/ammo_box/magazine/wt550m9)
+ crate_name = "auto rifle ammo crate"
+
+/datum/supply_pack/security/armory/wt550ammo_nonlethal // Takes around 12 shots to stun crit someone
+ name = "WT-550 Semi-Auto SMG Non-Lethal Ammo Crate"
+ desc = "Contains four 20-round magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
+ cost = 1000
+ contains = list(/obj/item/ammo_box/magazine/wt550m9/wtrubber,
+ /obj/item/ammo_box/magazine/wt550m9/wtrubber,
+ /obj/item/ammo_box/magazine/wt550m9/wtrubber,
+ /obj/item/ammo_box/magazine/wt550m9/wtrubber)
+ crate_name = "auto rifle ammo crate"
+
+/datum/supply_pack/security/armory/wt550ammo_special
+ name = "WT-550 Semi-Auto SMG Special Ammo Crate"
+ desc = "Contains 2 20-round Armour Piercing and Incendiary magazines for the WT-550 Semi-Auto SMG. Each magazine is designed to facilitate rapid tactical reloads. Requires Armory access to open."
+ cost = 3000
+ contains = list(/obj/item/ammo_box/magazine/wt550m9/wtap,
+ /obj/item/ammo_box/magazine/wt550m9/wtap,
+ /obj/item/ammo_box/magazine/wt550m9/wtic,
+ /obj/item/ammo_box/magazine/wt550m9/wtic)
+ crate_name = "auto rifle ammo crate"
diff --git a/code/modules/cargo/packs/costumes_toys.dm b/code/modules/cargo/packs/costumes_toys.dm
new file mode 100644
index 0000000000..40d21e4505
--- /dev/null
+++ b/code/modules/cargo/packs/costumes_toys.dm
@@ -0,0 +1,369 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Costumes & Toys /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/costumes_toys
+ group = "Costumes & Toys"
+
+/datum/supply_pack/costumes_toys/randomised
+ name = "Collectable Hats Crate"
+ desc = "Flaunt your status with three unique, highly-collectable hats!"
+ cost = 20000
+ var/num_contained = 3 //number of items picked to be contained in a randomised crate
+ contains = list(/obj/item/clothing/head/collectable/chef,
+ /obj/item/clothing/head/collectable/paper,
+ /obj/item/clothing/head/collectable/tophat,
+ /obj/item/clothing/head/collectable/captain,
+ /obj/item/clothing/head/collectable/beret,
+ /obj/item/clothing/head/collectable/welding,
+ /obj/item/clothing/head/collectable/flatcap,
+ /obj/item/clothing/head/collectable/pirate,
+ /obj/item/clothing/head/collectable/kitty,
+ /obj/item/clothing/head/collectable/rabbitears,
+ /obj/item/clothing/head/collectable/wizard,
+ /obj/item/clothing/head/collectable/hardhat,
+ /obj/item/clothing/head/collectable/HoS,
+ /obj/item/clothing/head/collectable/HoP,
+ /obj/item/clothing/head/collectable/thunderdome,
+ /obj/item/clothing/head/collectable/swat,
+ /obj/item/clothing/head/collectable/slime,
+ /obj/item/clothing/head/collectable/police,
+ /obj/item/clothing/head/collectable/slime,
+ /obj/item/clothing/head/collectable/xenom,
+ /obj/item/clothing/head/collectable/petehat)
+ crate_name = "collectable hats crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/randomised/contraband
+ name = "Contraband Crate"
+ desc = "Psst.. bud... want some contraband? I can get you a poster, some nice cigs, dank, even some sponsored items...you know, the good stuff. Just keep it away from the cops, kay?"
+ contraband = TRUE
+ cost = 3000
+ num_contained = 5 //SOME
+ contains = list(/obj/item/poster/random_contraband,
+ /obj/item/poster/random_contraband,
+ /obj/item/reagent_containers/food/snacks/grown/cannabis,
+ /obj/item/reagent_containers/food/snacks/grown/cannabis/rainbow,
+ /obj/item/reagent_containers/food/snacks/grown/cannabis/white,
+ /obj/item/storage/pill_bottle/zoom,
+ /obj/item/storage/pill_bottle/happy,
+ /obj/item/storage/pill_bottle/lsd,
+ /obj/item/storage/pill_bottle/aranesp,
+ /obj/item/storage/pill_bottle/stimulant,
+ /obj/item/toy/cards/deck/syndicate,
+ /obj/item/reagent_containers/food/drinks/bottle/absinthe,
+ /obj/item/clothing/under/syndicate/tacticool,
+ /obj/item/clothing/under/syndicate,
+ /obj/item/suppressor,
+ /obj/item/storage/fancy/cigarettes/cigpack_syndicate,
+ /obj/item/storage/fancy/cigarettes/cigpack_shadyjims,
+ /obj/item/clothing/mask/gas/syndicate,
+ /obj/item/clothing/neck/necklace/dope,
+ /obj/item/vending_refill/donksoft,
+ /obj/item/circuitboard/computer/arcade/amputation)
+ crate_name = "crate"
+
+/datum/supply_pack/costumes_toys/foamforce
+ name = "Foam Force Crate"
+ desc = "Break out the big guns with eight Foam Force shotguns!"
+ cost = 1000
+ contains = list(/obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy,
+ /obj/item/gun/ballistic/shotgun/toy)
+ crate_name = "foam force crate"
+
+/datum/supply_pack/costumes_toys/foamforce/bonus
+ name = "Foam Force Pistols Crate"
+ desc = "Psst.. hey bud... remember those old foam force pistols that got discontinued for being too cool? Well I got two of those right here with your name on em. I'll even throw in a spare mag for each, waddya say?"
+ contraband = TRUE
+ cost = 4000
+ contains = list(/obj/item/gun/ballistic/automatic/toy/pistol,
+ /obj/item/gun/ballistic/automatic/toy/pistol,
+ /obj/item/ammo_box/magazine/toy/pistol,
+ /obj/item/ammo_box/magazine/toy/pistol)
+ crate_name = "foam force crate"
+
+/datum/supply_pack/costumes_toys/formalwear
+ name = "Formalwear Crate"
+ desc = "You're gonna like the way you look, I guaranteed it. Contains an asston of fancy clothing."
+ cost = 4750 //Lots of fancy clothing that can be sold back!
+ contains = list(/obj/item/clothing/under/blacktango,
+ /obj/item/clothing/under/assistantformal,
+ /obj/item/clothing/under/assistantformal,
+ /obj/item/clothing/under/lawyer/bluesuit,
+ /obj/item/clothing/suit/toggle/lawyer,
+ /obj/item/clothing/under/lawyer/purpsuit,
+ /obj/item/clothing/suit/toggle/lawyer/purple,
+ /obj/item/clothing/under/lawyer/blacksuit,
+ /obj/item/clothing/suit/toggle/lawyer/black,
+ /obj/item/clothing/accessory/waistcoat,
+ /obj/item/clothing/neck/tie/blue,
+ /obj/item/clothing/neck/tie/red,
+ /obj/item/clothing/neck/tie/black,
+ /obj/item/clothing/head/bowler,
+ /obj/item/clothing/head/fedora,
+ /obj/item/clothing/head/flatcap,
+ /obj/item/clothing/head/beret,
+ /obj/item/clothing/head/that,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/shoes/laceup,
+ /obj/item/clothing/under/suit_jacket/charcoal,
+ /obj/item/clothing/under/suit_jacket/navy,
+ /obj/item/clothing/under/suit_jacket/burgundy,
+ /obj/item/clothing/under/suit_jacket/checkered,
+ /obj/item/clothing/under/suit_jacket/tan,
+ /obj/item/lipstick/random)
+ crate_name = "formalwear crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/clownpin
+ name = "Hilarious Firing Pin Crate"
+ desc = "I uh... I'm not really sure what this does. Wanna buy it?"
+ cost = 5000
+ contraband = TRUE
+ contains = list(/obj/item/firing_pin/clown)
+ crate_name = "toy crate" // It's /technically/ a toy. For the clown, at least.
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/lasertag
+ name = "Laser Tag Crate"
+ desc = "Foam Force is for boys. Laser Tag is for men. Contains three sets of red suits, blue suits, matching helmets, and matching laser tag guns."
+ cost = 3500
+ contains = list(/obj/item/gun/energy/laser/redtag,
+ /obj/item/gun/energy/laser/redtag,
+ /obj/item/gun/energy/laser/redtag,
+ /obj/item/gun/energy/laser/bluetag,
+ /obj/item/gun/energy/laser/bluetag,
+ /obj/item/gun/energy/laser/bluetag,
+ /obj/item/clothing/suit/redtag,
+ /obj/item/clothing/suit/redtag,
+ /obj/item/clothing/suit/redtag,
+ /obj/item/clothing/suit/bluetag,
+ /obj/item/clothing/suit/bluetag,
+ /obj/item/clothing/suit/bluetag,
+ /obj/item/clothing/head/helmet/redtaghelm,
+ /obj/item/clothing/head/helmet/redtaghelm,
+ /obj/item/clothing/head/helmet/redtaghelm,
+ /obj/item/clothing/head/helmet/bluetaghelm,
+ /obj/item/clothing/head/helmet/bluetaghelm,
+ /obj/item/clothing/head/helmet/bluetaghelm)
+ crate_name = "laser tag crate"
+
+/datum/supply_pack/costumes_toys/lasertag/pins
+ name = "Laser Tag Firing Pins Crate"
+ desc = "Three laser tag firing pins used in laser-tag units to ensure users are wearing their vests."
+ cost = 3000
+ contraband = TRUE
+ contains = list(/obj/item/storage/box/lasertagpins)
+ crate_name = "laser tag crate"
+
+/datum/supply_pack/costumes_toys/costume_original
+ name = "Original Costume Crate"
+ desc = "Reenact Shakespearean plays with this assortment of outfits. Contains eight different costumes!"
+ cost = 1750
+ contains = list(/obj/item/clothing/head/snowman,
+ /obj/item/clothing/suit/snowman,
+ /obj/item/clothing/head/chicken,
+ /obj/item/clothing/suit/chickensuit,
+ /obj/item/clothing/mask/gas/monkeymask,
+ /obj/item/clothing/suit/monkeysuit,
+ /obj/item/clothing/head/cardborg,
+ /obj/item/clothing/suit/cardborg,
+ /obj/item/clothing/head/xenos,
+ /obj/item/clothing/suit/xenos,
+ /obj/item/clothing/suit/hooded/ian_costume,
+ /obj/item/clothing/suit/hooded/carp_costume,
+ /obj/item/clothing/suit/hooded/bee_costume)
+ crate_name = "original costume crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/costume
+ name = "Standard Costume Crate"
+ desc = "Supply the station's entertainers with the equipment of their trade with these Nanotrasen-approved costumes! Contains a full clown and mime outfit, along with a bike horn and a bottle of nothing."
+ cost = 1300
+ access = ACCESS_THEATRE
+ contains = list(/obj/item/storage/backpack/clown,
+ /obj/item/clothing/shoes/clown_shoes,
+ /obj/item/clothing/mask/gas/clown_hat,
+ /obj/item/clothing/under/rank/clown,
+ /obj/item/bikehorn,
+ /obj/item/clothing/under/rank/mime,
+ /obj/item/clothing/shoes/sneakers/black,
+ /obj/item/clothing/gloves/color/white,
+ /obj/item/clothing/mask/gas/mime,
+ /obj/item/clothing/head/beret,
+ /obj/item/clothing/suit/suspenders,
+ /obj/item/reagent_containers/food/drinks/bottle/bottleofnothing,
+ /obj/item/storage/backpack/mime)
+ crate_name = "standard costume crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/randomised/toys
+ name = "Toy Crate"
+ desc = "Who cares about pride and accomplishment? Skip the gaming and get straight to the sweet rewards with this product! Contains five random toys. Warranty void if used to prank research directors."
+ cost = 1500 // or play the arcade machines ya lazy bum
+ num_contained = 5
+ contains = list(/obj/item/storage/box/snappops,
+ /obj/item/toy/talking/AI,
+ /obj/item/toy/talking/codex_gigas,
+ /obj/item/clothing/under/syndicate/tacticool,
+ /obj/item/toy/sword ,
+ /obj/item/toy/gun,
+ /obj/item/gun/ballistic/shotgun/toy/crossbow,
+ /obj/item/storage/box/fakesyndiesuit,
+ /obj/item/storage/crayons,
+ /obj/item/toy/spinningtoy,
+ /obj/item/toy/prize/ripley,
+ /obj/item/toy/prize/fireripley,
+ /obj/item/toy/prize/deathripley,
+ /obj/item/toy/prize/gygax,
+ /obj/item/toy/prize/durand,
+ /obj/item/toy/prize/honk,
+ /obj/item/toy/prize/marauder,
+ /obj/item/toy/prize/seraph,
+ /obj/item/toy/prize/mauler,
+ /obj/item/toy/prize/odysseus,
+ /obj/item/toy/prize/phazon,
+ /obj/item/toy/prize/reticence,
+ /obj/item/toy/cards/deck,
+ /obj/item/toy/nuke,
+ /obj/item/toy/minimeteor,
+ /obj/item/toy/redbutton,
+ /obj/item/toy/talking/owl,
+ /obj/item/toy/talking/griffin,
+ /obj/item/coin/antagtoken,
+ /obj/item/stack/tile/fakespace/loaded,
+ /obj/item/stack/tile/fakepit/loaded,
+ /obj/item/toy/toy_xeno,
+ /obj/item/storage/box/actionfigure,
+ /obj/item/restraints/handcuffs/fake,
+ /obj/item/grenade/chem_grenade/glitter/pink,
+ /obj/item/grenade/chem_grenade/glitter/blue,
+ /obj/item/grenade/chem_grenade/glitter/white,
+ /obj/item/toy/eightball,
+ /obj/item/toy/windupToolbox,
+ /obj/item/toy/clockwork_watch,
+ /obj/item/toy/toy_dagger,
+ /obj/item/extendohand/acme,
+ /obj/item/hot_potato/harmless/toy,
+ /obj/item/card/emagfake,
+ /obj/item/clothing/shoes/wheelys,
+ /obj/item/clothing/shoes/kindleKicks,
+ /obj/item/storage/belt/military/snack,
+ /obj/item/toy/eightball,
+ /obj/item/vending_refill/donksoft)
+ crate_name = "toy crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/randomised/plush
+ name = "Plush Crate"
+ desc = "Plush tide station wide. Contains 5 random plushies for you to love. Warranty void if your love violates the terms of use."
+ cost = 1500 // or play the arcade machines ya lazy bum
+ num_contained = 5
+ contains = list(/obj/item/toy/plush/random,
+ /obj/item/toy/plush/random,
+ /obj/item/toy/plush/random,
+ /obj/item/toy/plush/random,
+ /obj/item/toy/plush/random) //I'm lazy
+ crate_name = "plushie crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/wizard
+ name = "Wizard Costume Crate"
+ desc = "Pretend to join the Wizard Federation with this full wizard outfit! Nanotrasen would like to remind its employees that actually joining the Wizard Federation is subject to termination of job and life."
+ cost = 2000
+ contains = list(/obj/item/staff,
+ /obj/item/clothing/suit/wizrobe/fake,
+ /obj/item/clothing/shoes/sandal,
+ /obj/item/clothing/head/wizard/fake)
+ crate_name = "wizard costume crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/costumes_toys/randomised/fill(obj/structure/closet/crate/C)
+ var/list/L = contains.Copy()
+ for(var/i in 1 to num_contained)
+ var/item = pick_n_take(L)
+ new item(C)
+
+/datum/supply_pack/costumes_toys/wardrobes/autodrobe
+ name = "Autodrobe Supply Crate"
+ desc = "Autodrobe missing your favorite dress? Solve that issue today with this autodrobe refill."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/autodrobe)
+ crate_name = "autodrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/cargo
+ name = "Cargo Wardrobe Supply Crate"
+ desc = "This crate contains a refill for the CargoDrobe."
+ cost = 750
+ contains = list(/obj/item/vending_refill/wardrobe/cargo_wardrobe)
+ crate_name = "cargo department supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/engineering
+ name = "Engineering Wardrobe Supply Crate"
+ desc = "This crate contains refills for the EngiDrobe and AtmosDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/engi_wardrobe,
+ /obj/item/vending_refill/wardrobe/atmos_wardrobe)
+ crate_name = "engineering department wardrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/general
+ name = "General Wardrobes Supply Crate"
+ desc = "This crate contains refills for the CuraDrobe, BarDrobe, ChefDrobe, JaniDrobe, ChapDrobe."
+ cost = 3750
+ contains = list(/obj/item/vending_refill/wardrobe/curator_wardrobe,
+ /obj/item/vending_refill/wardrobe/bar_wardrobe,
+ /obj/item/vending_refill/wardrobe/chef_wardrobe,
+ /obj/item/vending_refill/wardrobe/jani_wardrobe,
+ /obj/item/vending_refill/wardrobe/chap_wardrobe)
+ crate_name = "general wardrobes vendor refills"
+
+/datum/supply_pack/costumes_toys/wardrobes/hydroponics
+ name = "Hydrobe Supply Crate"
+ desc = "This crate contains a refill for the Hydrobe."
+ cost = 750
+ contains = list(/obj/item/vending_refill/wardrobe/hydro_wardrobe)
+ crate_name = "hydrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/medical
+ name = "Medical Wardrobe Supply Crate"
+ desc = "This crate contains refills for the MediDrobe, ChemDrobe, GeneDrobe, and ViroDrobe."
+ cost = 3000
+ contains = list(/obj/item/vending_refill/wardrobe/medi_wardrobe,
+ /obj/item/vending_refill/wardrobe/chem_wardrobe,
+ /obj/item/vending_refill/wardrobe/gene_wardrobe,
+ /obj/item/vending_refill/wardrobe/viro_wardrobe)
+ crate_name = "medical department wardrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/science
+ name = "Science Wardrobe Supply Crate"
+ desc = "This crate contains refills for the SciDrobe and RoboDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/robo_wardrobe,
+ /obj/item/vending_refill/wardrobe/science_wardrobe)
+ crate_name = "science department wardrobe supply crate"
+
+/datum/supply_pack/costumes_toys/wardrobes/security
+ name = "Security Wardrobe Supply Crate"
+ desc = "This crate contains refills for the SecDrobe and LawDrobe."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/wardrobe/sec_wardrobe,
+ /obj/item/vending_refill/wardrobe/law_wardrobe)
+ crate_name = "security department supply crate"
+
+/datum/supply_pack/costumes_toys/kinkmate
+ name = "Kinkmate construction kit"
+ cost = 2000
+ contraband = TRUE
+ contains = list(/obj/item/vending_refill/kink, /obj/item/circuitboard/machine/kinkmate)
+ crate_name = "Kinkmate construction kit"
diff --git a/code/modules/cargo/packs/emergency.dm b/code/modules/cargo/packs/emergency.dm
new file mode 100644
index 0000000000..1987369d20
--- /dev/null
+++ b/code/modules/cargo/packs/emergency.dm
@@ -0,0 +1,275 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Emergency ///////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/emergency
+ group = "Emergency"
+
+/datum/supply_pack/emergency/vehicle
+ name = "Biker Gang Kit" //TUNNEL SNAKES OWN THIS TOWN
+ desc = "TUNNEL SNAKES OWN THIS TOWN. Contains an unbranded All Terrain Vehicle, and a complete gang outfit -- consists of black gloves, a menacing skull bandanna, and a SWEET leather overcoat!"
+ cost = 2500
+ contraband = TRUE
+ contains = list(/obj/vehicle/ridden/atv,
+ /obj/item/key,
+ /obj/item/clothing/suit/jacket/leather/overcoat,
+ /obj/item/clothing/gloves/color/black,
+ /obj/item/clothing/head/soft,
+ /obj/item/clothing/mask/bandana/skull)//so you can properly #cargoniabikergang
+ crate_name = "Biker Kit"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/emergency/equipment
+ name = "Emergency Bot/Internals Crate"
+ desc = "Explosions got you down? These supplies are guaranteed to patch up holes, in stations and people alike! Comes with two floorbots, two medbots, five oxygen masks and five small oxygen tanks."
+ cost = 2750
+ contains = list(/mob/living/simple_animal/bot/floorbot,
+ /mob/living/simple_animal/bot/floorbot,
+ /mob/living/simple_animal/bot/medbot,
+ /mob/living/simple_animal/bot/medbot,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas)
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/radiatione_emergency
+ name = "Emergenc Radiation Protection Crate"
+ desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a few pill bottles that are able to handles radiation and the affects of the poisoning."
+ cost = 2500
+ contains = list(/obj/item/clothing/head/radiation,
+ /obj/item/clothing/head/radiation,
+ /obj/item/clothing/suit/radiation,
+ /obj/item/clothing/suit/radiation,
+ /obj/item/geiger_counter,
+ /obj/item/geiger_counter,
+ /obj/item/storage/pill_bottle/mutarad,
+ /obj/item/storage/firstaid/radbgone)
+ crate_name = "radiation protection crate"
+ crate_type = /obj/structure/closet/crate/radiation
+
+/datum/supply_pack/emergency/rcds
+ name = "Emergency RCDs"
+ desc = "Bombs going off on station? SME blown and now you need to fix the hole it left behind? Well this crate has a pare of Rcds to be able to easily fix up any problem you may have!"
+ cost = 1500
+ contains = list(/obj/item/construction/rcd,
+ /obj/item/construction/rcd)
+ crate_name = "emergency rcds"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/soft_suit
+ name = "Emergency Space Suit "
+ desc = "Is there bombs going off left and right? Is there meteors shooting around the station? Well we have two fragile space suit for emergencys as well as air and masks."
+ cost = 1200
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/fragile,
+ /obj/item/clothing/suit/space/fragile,
+ /obj/item/clothing/head/helmet/space/fragile,
+ /obj/item/clothing/head/helmet/space/fragile)
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/firefighting
+ name = "Firefighting Crate"
+ desc = "Only you can prevent station fires. Partner up with two firefighter suits, gas masks, flashlights, large oxygen tanks, extinguishers, and hardhats!"
+ cost = 1200
+ contains = list(/obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/suit/fire/firefighter,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/flashlight,
+ /obj/item/flashlight,
+ /obj/item/tank/internals/oxygen/red,
+ /obj/item/tank/internals/oxygen/red,
+ /obj/item/extinguisher/advanced,
+ /obj/item/extinguisher/advanced,
+ /obj/item/clothing/head/hardhat/red,
+ /obj/item/clothing/head/hardhat/red)
+ crate_name = "firefighting crate"
+
+/datum/supply_pack/emergency/atmostank
+ name = "Firefighting Tank Backpack"
+ desc = "Mow down fires with this high-capacity fire fighting tank backpack. Requires Atmospherics access to open."
+ cost = 1000
+ access = ACCESS_ATMOSPHERICS
+ contains = list(/obj/item/watertank/atmos)
+ crate_name = "firefighting backpack crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/emergency/internals
+ name = "Internals Crate"
+ desc = "Master your life energy and control your breathing with three breath masks, three emergency oxygen tanks and three large air tanks."//IS THAT A
+ cost = 1000
+ contains = list(/obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/breath,
+ /obj/item/clothing/mask/breath,
+ /obj/item/clothing/mask/breath,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/emergency_oxygen,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air,
+ /obj/item/tank/internals/air)
+ crate_name = "internals crate"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/metalfoam
+ name = "Metal Foam Grenade Crate"
+ desc = "Seal up those pesky hull breaches with 14 Metal Foam Grenades."
+ cost = 1500
+ contains = list(/obj/item/storage/box/metalfoam,
+ /obj/item/storage/box/metalfoam)
+ crate_name = "metal foam grenade crate"
+
+/datum/supply_pack/emergency/syndicate
+ name = "NULL_ENTRY"
+ desc = "(#@&^$THIS PACKAGE CONTAINS 30TC WORTH OF SOME RANDOM SYNDICATE GEAR WE HAD LYING AROUND THE WAREHOUSE. GIVE EM HELL, OPERATIVE@&!*() "
+ hidden = TRUE
+ cost = 20000
+ contains = list()
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+ dangerous = TRUE
+
+/datum/supply_pack/emergency/syndicate/fill(obj/structure/closet/crate/C)
+ var/crate_value = 30
+ var/list/uplink_items = get_uplink_items(SSticker.mode)
+ while(crate_value)
+ var/category = pick(uplink_items)
+ var/item = pick(uplink_items[category])
+ var/datum/uplink_item/I = uplink_items[category][item]
+ if(!I.surplus_nullcrates || prob(100 - I.surplus_nullcrates))
+ continue
+ if(crate_value < I.cost)
+ continue
+ crate_value -= I.cost
+ new I.item(C)
+
+/datum/supply_pack/emergency/plasma_spacesuit
+ name = "Plasmaman Space Envirosuits"
+ desc = "Contains two space-worthy envirosuits for Plasmamen. Order now and we'll throw in two free helmets! Requires EVA access to open."
+ cost = 4000
+ access = ACCESS_EVA
+ contains = list(/obj/item/clothing/suit/space/eva/plasmaman,
+ /obj/item/clothing/suit/space/eva/plasmaman,
+ /obj/item/clothing/head/helmet/space/plasmaman,
+ /obj/item/clothing/head/helmet/space/plasmaman)
+ crate_name = "plasmaman EVA crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/emergency/plasmaman
+ name = "Plasmaman Supply Kit"
+ desc = "Keep those Plasmamen alive with two sets of Plasmaman outfits. Each set contains a plasmaman jumpsuit, internals tank, and helmet."
+ cost = 2000
+ contains = list(/obj/item/clothing/under/plasmaman,
+ /obj/item/clothing/under/plasmaman,
+ /obj/item/tank/internals/plasmaman/belt/full,
+ /obj/item/tank/internals/plasmaman/belt/full,
+ /obj/item/clothing/head/helmet/space/plasmaman,
+ /obj/item/clothing/head/helmet/space/plasmaman)
+ crate_name = "plasmaman supply kit"
+
+/datum/supply_pack/emergency/radiation
+ name = "Radiation Protection Crate"
+ desc = "Survive the Nuclear Apocalypse and Supermatter Engine alike with two sets of Radiation suits. Each set contains a helmet, suit, and Geiger counter. We'll even throw in a bottle of vodka and some glasses too, considering the life-expectancy of people who order this."
+ cost = 1300
+ contains = list(/obj/item/clothing/head/radiation,
+ /obj/item/clothing/head/radiation,
+ /obj/item/clothing/suit/radiation,
+ /obj/item/clothing/suit/radiation,
+ /obj/item/geiger_counter,
+ /obj/item/geiger_counter,
+ /obj/item/reagent_containers/food/drinks/bottle/vodka,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
+ crate_name = "radiation protection crate"
+ crate_type = /obj/structure/closet/crate/radiation
+
+/datum/supply_pack/emergency/spacesuit
+ name = "Space Suit Crate"
+ desc = "Contains two aging suits from Space-Goodwill. Requires EVA access to open."
+ cost = 3000
+ access = ACCESS_EVA
+ contains = list(/obj/item/clothing/suit/space,
+ /obj/item/clothing/suit/space,
+ /obj/item/clothing/head/helmet/space,
+ /obj/item/clothing/head/helmet/space,
+ /obj/item/clothing/mask/breath,
+ /obj/item/clothing/mask/breath)
+ crate_name = "space suit crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/emergency/spacejets
+ name = "Spare EVA Jetpacks"
+ desc = "Contains three EVA grade jectpaks. Requires EVA access to open."
+ cost = 2000
+ access = ACCESS_EVA
+ contains = list(/obj/item/tank/jetpack/carbondioxide/eva,
+ /obj/item/tank/jetpack/carbondioxide/eva,
+ /obj/item/tank/jetpack/carbondioxide/eva)
+ crate_name = "eva jetpacks crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/emergency/specialops
+ name = "Special Ops Supplies"
+ desc = "(*!&@#TOO CHEAP FOR THAT NULL_ENTRY, HUH OPERATIVE? WELL, THIS LITTLE ORDER CAN STILL HELP YOU OUT IN A PINCH. CONTAINS A BOX OF FIVE EMP GRENADES, THREE SMOKEBOMBS, AN INCENDIARY GRENADE, AND A \"SLEEPY PEN\" FULL OF NICE TOXINS!#@*$"
+ hidden = TRUE
+ cost = 2200
+ contains = list(/obj/item/storage/box/emps,
+ /obj/item/grenade/smokebomb,
+ /obj/item/grenade/smokebomb,
+ /obj/item/grenade/smokebomb,
+ /obj/item/pen/sleepy,
+ /obj/item/grenade/chem_grenade/incendiary)
+ crate_name = "emergency crate"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/emergency/weedcontrol
+ name = "Weed Control Crate"
+ desc = "Keep those invasive species OUT. Contains a scythe, gasmask, two sprays of Plant-B-Gone, and two anti-weed chemical grenades. Warranty void if used on ambrosia. Requires Hydroponics access to open."
+ cost = 1800
+ access = ACCESS_HYDROPONICS
+ contains = list(/obj/item/scythe,
+ /obj/item/clothing/mask/gas,
+ /obj/item/grenade/chem_grenade/antiweed,
+ /obj/item/grenade/chem_grenade/antiweed,
+ /obj/item/reagent_containers/spray/plantbgone,
+ /obj/item/reagent_containers/spray/plantbgone)
+ crate_name = "weed control crate"
+ crate_type = /obj/structure/closet/crate/secure/hydroponics
+
+/datum/supply_pack/medical/anitvirus
+ name = "Virus Containment Crate"
+ desc = "Viro let out a death plague Mk II again? Someone didnt wash there hands? Old plagues born anew? Well this crate is for you! Hope you cure it before it brakes out of the station... This crate needs medical access to open and has two bio suits, a box of needles and beakers, five spaceacillin needles, and a medibot."
+ cost = 3000
+ access = ACCESS_MEDICAL
+ contains = list(/mob/living/simple_animal/bot/medbot,
+ /obj/item/clothing/head/bio_hood,
+ /obj/item/clothing/head/bio_hood,
+ /obj/item/clothing/suit/bio_suit,
+ /obj/item/clothing/suit/bio_suit,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/reagent_containers/syringe/antiviral,
+ /obj/item/storage/box/syringes,
+ /obj/item/storage/box/beakers)
+ crate_name = "virus containment unit crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
diff --git a/code/modules/cargo/packs/engine.dm b/code/modules/cargo/packs/engine.dm
new file mode 100644
index 0000000000..a4438c7ef8
--- /dev/null
+++ b/code/modules/cargo/packs/engine.dm
@@ -0,0 +1,169 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////// Engine Construction /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/engine
+ group = "Engine Construction"
+ crate_type = /obj/structure/closet/crate/engineering
+
+/datum/supply_pack/engine/am_jar
+ name = "Antimatter Containment Jar Crate"
+ desc = "Two Antimatter containment jars stuffed into a single crate."
+ cost = 2300
+ contains = list(/obj/item/am_containment,
+ /obj/item/am_containment)
+ crate_name = "antimatter jar crate"
+
+/datum/supply_pack/engine/am_core
+ name = "Antimatter Control Crate"
+ desc = "The brains of the Antimatter engine, this device is sure to teach the station's powergrid the true meaning of real power."
+ cost = 5200
+ contains = list(/obj/machinery/power/am_control_unit)
+ crate_name = "antimatter control crate"
+
+/datum/supply_pack/engine/am_shielding
+ name = "Antimatter Shielding Crate"
+ desc = "Contains ten Antimatter shields, somehow crammed into a crate."
+ cost = 2500
+ contains = list(/obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container,
+ /obj/item/am_shielding_container) //10 shields: 3x3 containment and a core
+ crate_name = "antimatter shielding crate"
+
+/datum/supply_pack/engine/emitter
+ name = "Emitter Crate"
+ desc = "Useful for powering forcefield generators while destroying locked crates and intruders alike. Contains two high-powered energy emitters. Requires CE access to open."
+ cost = 1750
+ access = ACCESS_CE
+ contains = list(/obj/machinery/power/emitter,
+ /obj/machinery/power/emitter)
+ crate_name = "emitter crate"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+ dangerous = TRUE
+
+/datum/supply_pack/engine/field_gen
+ name = "Field Generator Crate"
+ desc = "Typically the only thing standing between the station and a messy death. Powered by emitters. Contains two field generators."
+ cost = 1750
+ contains = list(/obj/machinery/field/generator,
+ /obj/machinery/field/generator)
+ crate_name = "field generator crate"
+
+/datum/supply_pack/engine/grounding_rods
+ name = "Grounding Rod Crate"
+ desc = "Four grounding rods guaranteed to keep any uppity tesla's lightning under control."
+ cost = 2200
+ contains = list(/obj/machinery/power/grounding_rod,
+ /obj/machinery/power/grounding_rod,
+ /obj/machinery/power/grounding_rod,
+ /obj/machinery/power/grounding_rod)
+ crate_name = "grounding rod crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engine/mason
+ name = "M.A.S.O.N RIG Crate"
+ desc = "The rare M.A.S.O.N RIG. Requires CE access to open."
+ cost = 15000
+ access = ACCESS_CE
+ contains = list(/obj/item/clothing/suit/space/hardsuit/ancient/mason)
+ crate_name = "M.A.S.O.N Rig"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+
+/datum/supply_pack/engine/PA
+ name = "Particle Accelerator Crate"
+ desc = "A supermassive black hole or hyper-powered teslaball are the perfect way to spice up any party! This \"My First Apocalypse\" kit contains everything you need to build your own Particle Accelerator! Ages 10 and up."
+ cost = 3750
+ contains = list(/obj/structure/particle_accelerator/fuel_chamber,
+ /obj/machinery/particle_accelerator/control_box,
+ /obj/structure/particle_accelerator/particle_emitter/center,
+ /obj/structure/particle_accelerator/particle_emitter/left,
+ /obj/structure/particle_accelerator/particle_emitter/right,
+ /obj/structure/particle_accelerator/power_box,
+ /obj/structure/particle_accelerator/end_cap)
+ crate_name = "particle accelerator crate"
+
+/datum/supply_pack/engine/collector
+ name = "Radiation Collector Crate"
+ desc = "Contains three radiation collectors. Useful for collecting energy off nearby Supermatter Crystals, Singularities or Teslas!"
+ cost = 2750
+ contains = list(/obj/machinery/power/rad_collector,
+ /obj/machinery/power/rad_collector,
+ /obj/machinery/power/rad_collector)
+ crate_name = "collector crate"
+
+/datum/supply_pack/engine/sing_gen
+ name = "Singularity Generator Crate"
+ desc = "The key to unlocking the power of Lord Singuloth. Particle Accelerator not included."
+ cost = 6000
+ contains = list(/obj/machinery/the_singularitygen)
+ crate_name = "singularity generator crate"
+
+/datum/supply_pack/engine/solar
+ name = "Solar Panel Crate"
+ desc = "Go green with this DIY advanced solar array. Contains twenty one solar assemblies, a solar-control circuit board, and tracker. If you have any questions, please check out the enclosed instruction book."
+ cost = 2850
+ contains = list(/obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/solar_assembly,
+ /obj/item/circuitboard/computer/solar_control,
+ /obj/item/electronics/tracker,
+ /obj/item/paper/guides/jobs/engi/solars)
+ crate_name = "solar panel crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engine/supermatter_shard
+ name = "Supermatter Shard Crate"
+ desc = "The power of the heavens condensed into a single crystal. Requires CE access to open."
+ cost = 10000
+ access = ACCESS_CE
+ contains = list(/obj/machinery/power/supermatter_crystal/shard)
+ crate_name = "supermatter shard crate"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+ dangerous = TRUE
+
+/datum/supply_pack/engine/tesla_coils
+ name = "Tesla Coil Crate"
+ desc = "Whether it's high-voltage executions, creating research points, or just plain old power generation: This pack of four Tesla coils can do it all!"
+ cost = 3500
+ contains = list(/obj/machinery/power/tesla_coil,
+ /obj/machinery/power/tesla_coil,
+ /obj/machinery/power/tesla_coil,
+ /obj/machinery/power/tesla_coil)
+ crate_name = "tesla coil crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engine/tesla_gen
+ name = "Tesla Generator Crate"
+ desc = "The key to unlocking the power of the Tesla energy ball. Particle Accelerator not included."
+ cost = 7000
+ contains = list(/obj/machinery/the_singularitygen/tesla)
+ crate_name = "tesla generator crate"
diff --git a/code/modules/cargo/packs/engineering.dm b/code/modules/cargo/packs/engineering.dm
new file mode 100644
index 0000000000..19cb53489e
--- /dev/null
+++ b/code/modules/cargo/packs/engineering.dm
@@ -0,0 +1,229 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Engineering /////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/engineering
+ group = "Engineering"
+ crate_type = /obj/structure/closet/crate/engineering
+
+/datum/supply_pack/engineering/shieldgen
+ name = "Anti-breach Shield Projector Crate"
+ desc = "Hull breaches again? Say no more with the Nanotrasen Anti-Breach Shield Projector! Uses forcefield technology to keep the air in, and the space out. Contains two shield projectors."
+ cost = 2500
+ contains = list(/obj/machinery/shieldgen,
+ /obj/machinery/shieldgen)
+ crate_name = "anti-breach shield projector crate"
+
+/datum/supply_pack/engineering/conveyor
+ name = "Conveyor Assembly Crate"
+ desc = "Keep production moving along with six conveyor belts. Conveyor switch included. If you have any questions, check out the enclosed instruction book."
+ cost = 750
+ contains = list(/obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_construct,
+ /obj/item/conveyor_switch_construct,
+ /obj/item/paper/guides/conveyor)
+ crate_name = "conveyor assembly crate"
+
+/datum/supply_pack/engineering/engiequipment
+ name = "Engineering Gear Crate"
+ desc = "Gear up with three toolbelts, high-visibility vests, welding helmets, hardhats, and two pairs of meson goggles!"
+ cost = 1500
+ contains = list(/obj/item/storage/belt/utility,
+ /obj/item/storage/belt/utility,
+ /obj/item/storage/belt/utility,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/suit/hazardvest,
+ /obj/item/clothing/head/welding,
+ /obj/item/clothing/head/welding,
+ /obj/item/clothing/head/welding,
+ /obj/item/clothing/head/hardhat,
+ /obj/item/clothing/head/hardhat,
+ /obj/item/clothing/head/hardhat,
+ /obj/item/clothing/glasses/meson/engine,
+ /obj/item/clothing/glasses/meson/engine)
+ crate_name = "engineering gear crate"
+
+/datum/supply_pack/engineering/engihardsuit
+ name = "Engineering Hardsuit"
+ desc = "Poly 'Who stole all the hardsuits!' Well now you can get more hardsuits if needed! NOTE ONE HARDSUIT IS IN THIS CRATE, as well as one air tank and mask!"
+ cost = 2250
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/hardsuit/engine)
+ crate_name = "engineering hardsuit"
+
+/datum/supply_pack/engineering/atmoshardsuit
+ name = "Atmospherics Hardsuit"
+ desc = "Too many techs and not enough hardsuits? Time to buy some more! Comes with gas mask and air tank. Ask the CE to open."
+ cost = 5000
+ access = ACCESS_CE
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/hardsuit/engine/atmos)
+ crate_name = "atmospherics hardsuit"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+
+/datum/supply_pack/engineering/industrialrcd
+ name = "Industrial RCD"
+ desc = "A industrial RCD in case the station has gone through more then one meteor storm and the CE needs to bring out the somthing a bit more reliable. Dose not contain spare ammo for the industrial RCD or any other RCD modles."
+ cost = 4500
+ access = ACCESS_CE
+ contains = list(/obj/item/construction/rcd/industrial)
+ crate_name = "industrial rcd"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+
+/datum/supply_pack/engineering/powergamermitts
+ name = "Insulated Gloves Crate"
+ desc = "The backbone of modern society. Barely ever ordered for actual engineering. Contains three insulated gloves."
+ cost = 2300 //Made of pure-grade bullshittinium
+ contains = list(/obj/item/clothing/gloves/color/yellow,
+ /obj/item/clothing/gloves/color/yellow,
+ /obj/item/clothing/gloves/color/yellow)
+ crate_name = "insulated gloves crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/obj/item/stock_parts/cell/inducer_supply
+ maxcharge = 5000
+ charge = 5000
+
+/datum/supply_pack/engineering/inducers
+ name = "NT-75 Electromagnetic Power Inducers Crate"
+ desc = "No rechargers? No problem, with the NT-75 EPI, you can recharge any standard cell-based equipment anytime, anywhere. Contains two Inducers."
+ cost = 2300
+ contains = list(/obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}, /obj/item/inducer/sci {cell_type = /obj/item/stock_parts/cell/inducer_supply; opened = 0}) //FALSE doesn't work in modified type paths apparently.
+ crate_name = "inducer crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engineering/pacman
+ name = "P.A.C.M.A.N Generator Crate"
+ desc = "Engineers can't set up the engine? Not an issue for you, once you get your hands on this P.A.C.M.A.N. Generator! Takes in plasma and spits out sweet sweet energy."
+ cost = 2250
+ contains = list(/obj/machinery/power/port_gen/pacman)
+ crate_name = "PACMAN generator crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engineering/power
+ name = "Power Cell Crate"
+ desc = "Looking for power overwhelming? Look no further. Contains three high-voltage power cells."
+ cost = 1000
+ contains = list(/obj/item/stock_parts/cell/high,
+ /obj/item/stock_parts/cell/high,
+ /obj/item/stock_parts/cell/high)
+ crate_name = "power cell crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+
+/datum/supply_pack/engineering/siezedpower
+ name = "Siezed Power Cell Crate"
+ desc = "We took the means of power! Contains three high-voltage plus power cells."
+ cost = 1300
+ contraband = TRUE
+ contains = list(/obj/item/stock_parts/cell/high/plus,
+ /obj/item/stock_parts/cell/high/plus,
+ /obj/item/stock_parts/cell/high/plus)
+ crate_name = "siezed crate"
+ crate_type = /obj/structure/closet/crate/engineering/electrical
+
+/datum/supply_pack/engineering/shuttle_engine
+ name = "Shuttle Engine Crate"
+ desc = "Through advanced bluespace-shenanigans, our engineers have managed to fit an entire shuttle engine into one tiny little crate. Requires CE access to open."
+ cost = 5000
+ access = ACCESS_CE
+ contains = list(/obj/structure/shuttle/engine/propulsion/burst/cargo)
+ crate_name = "shuttle engine crate"
+ crate_type = /obj/structure/closet/crate/secure/engineering
+
+/datum/supply_pack/engineering/siezedproduction
+ name = "The Means of Production"
+ desc = "We will win for we have took over the production! S five metal sheets, five wire, three matter bins, one manipulater and one sheet of glass."
+ cost = 1500
+ contraband = TRUE
+ contains = list(/obj/item/stock_parts/cell/high/plus,
+ /obj/item/circuitboard/machine/autolathe,
+ /obj/item/stack/cable_coil/random/five,
+ /obj/item/stack/sheet/metal/five,
+ /obj/item/stock_parts/matter_bin,
+ /obj/item/stock_parts/matter_bin,
+ /obj/item/stock_parts/matter_bin,
+ /obj/item/stock_parts/manipulator,
+ /obj/item/stack/sheet/glass,)
+ crate_name = "siezed crate"
+
+/datum/supply_pack/engineering/tools
+ name = "Toolbox Crate"
+ desc = "Any robust spaceman is never far from their trusty toolbox. Contains three electrical toolboxes and three mechanical toolboxes."
+ contains = list(/obj/item/storage/toolbox/electrical,
+ /obj/item/storage/toolbox/electrical,
+ /obj/item/storage/toolbox/electrical,
+ /obj/item/storage/toolbox/mechanical,
+ /obj/item/storage/toolbox/mechanical,
+ /obj/item/storage/toolbox/mechanical)
+ cost = 1200
+ crate_name = "toolbox crate"
+
+/datum/supply_pack/engineering/bsa
+ name = "Bluespace Artillery Parts"
+ desc = "The pride of Nanotrasen Naval Command. The legendary Bluespace Artillery Cannon is a devastating feat of human engineering and testament to wartime determination. Highly advanced research is required for proper construction. "
+ cost = 15000
+ special = TRUE
+ contains = list(/obj/item/circuitboard/machine/bsa/front,
+ /obj/item/circuitboard/machine/bsa/middle,
+ /obj/item/circuitboard/machine/bsa/back,
+ /obj/item/circuitboard/computer/bsa_control
+ )
+ crate_name= "bluespace artillery parts crate"
+
+/datum/supply_pack/engineering/dna_vault
+ name = "DNA Vault Parts"
+ desc = "Secure the longevity of the current state of humanity within this massive library of scientific knowledge, capable of granting superhuman powers and abilities. Highly advanced research is required for proper construction. Also contains five DNA probes."
+ cost = 12000
+ special = TRUE
+ contains = list(
+ /obj/item/circuitboard/machine/dna_vault,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe
+ )
+ crate_name= "dna vault parts crate"
+
+/datum/supply_pack/engineering/dna_probes
+ name = "DNA Vault Samplers"
+ desc = "Contains five DNA probes for use in the DNA vault."
+ cost = 3000
+ special = TRUE
+ contains = list(/obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe,
+ /obj/item/dna_probe
+ )
+ crate_name= "dna samplers crate"
+
+/datum/supply_pack/engineering/shield_sat
+ name = "Shield Generator Satellite"
+ desc = "Protect the very existence of this station with these Anti-Meteor defenses. Contains three Shield Generator Satellites."
+ cost = 4000
+ contains = list(
+ /obj/machinery/satellite/meteor_shield,
+ /obj/machinery/satellite/meteor_shield,
+ /obj/machinery/satellite/meteor_shield
+ )
+ crate_name= "shield sat crate"
+
+/datum/supply_pack/engineering/shield_sat_control
+ name = "Shield System Control Board"
+ desc = "A control system for the Shield Generator Satellite system."
+ cost = 4000
+ contains = list(/obj/item/circuitboard/computer/sat_control)
+ crate_name= "shield control board crate"
diff --git a/code/modules/cargo/packs/livestock.dm b/code/modules/cargo/packs/livestock.dm
new file mode 100644
index 0000000000..8708562a06
--- /dev/null
+++ b/code/modules/cargo/packs/livestock.dm
@@ -0,0 +1,147 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+////////////////////////////// Livestock /////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/critter
+ group = "Livestock"
+ crate_type = /obj/structure/closet/crate/critter
+
+/datum/supply_pack/critter/butterfly
+ name = "Butterflies Crate"
+ desc = "Not a very dangerous insect, but they do give off a better image than, say, flies or cockroaches."//is that a motherfucking worm reference
+ contraband = TRUE
+ cost = 5000
+ contains = list(/mob/living/simple_animal/butterfly)
+ crate_name = "entomology samples crate"
+
+/datum/supply_pack/critter/butterfly/generate()
+ . = ..()
+ for(var/i in 1 to 49)
+ new /mob/living/simple_animal/butterfly(.)
+
+/datum/supply_pack/critter/cat
+ name = "Cat Crate"
+ desc = "The cat goes meow! Comes with a collar and a nice cat toy! Cheeseburger not included."//i can't believe im making this reference
+ cost = 5000 //Cats are worth as much as corgis.
+ contains = list(/mob/living/simple_animal/pet/cat,
+ /obj/item/clothing/neck/petcollar,
+ /obj/item/toy/cattoy)
+ crate_name = "cat crate"
+
+/datum/supply_pack/critter/cat/generate()
+ . = ..()
+ if(prob(50))
+ var/mob/living/simple_animal/pet/cat/C = locate() in .
+ qdel(C)
+ new /mob/living/simple_animal/pet/cat/Proc(.)
+
+/datum/supply_pack/critter/chick
+ name = "Chicken Crate"
+ desc = "The chicken goes bwaak!"
+ cost = 2000
+ contains = list( /mob/living/simple_animal/chick)
+ crate_name = "chicken crate"
+
+/datum/supply_pack/critter/crab
+ name = "Crab Rocket"
+ desc = "CRAAAAAAB ROCKET. CRAB ROCKET. CRAB ROCKET. CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB ROCKET. CRAFT. ROCKET. BUY. CRAFT ROCKET. CRAB ROOOCKET. CRAB ROOOOCKET. CRAB CRAB CRAB CRAB CRAB CRAB CRAB CRAB ROOOOOOOOOOOOOOOOOOOOOOCK EEEEEEEEEEEEEEEEEEEEEEEEE EEEETTTTTTTTTTTTAAAAAAAAA AAAHHHHHHHHHHHHH. CRAB ROCKET. CRAAAB ROCKEEEEEEEEEGGGGHHHHTT CRAB CRAB CRAABROCKET CRAB ROCKEEEET."//fun fact: i actually spent like 10 minutes and transcribed the entire video.
+ cost = 5000
+ contains = list(/mob/living/simple_animal/crab)
+ crate_name = "look sir free crabs"
+ DropPodOnly = TRUE
+
+/datum/supply_pack/critter/crab/generate()
+ . = ..()
+ for(var/i in 1 to 49)
+ new /mob/living/simple_animal/crab(.)
+
+/datum/supply_pack/critter/corgi
+ name = "Corgi Crate"
+ desc = "Considered the optimal dog breed by thousands of research scientists, this Corgi is but one dog from the millions of Ian's noble bloodline. Comes with a cute collar!"
+ cost = 5000
+ contains = list(/mob/living/simple_animal/pet/dog/corgi,
+ /obj/item/clothing/neck/petcollar)
+ crate_name = "corgi crate"
+
+/datum/supply_pack/critter/corgi/generate()
+ . = ..()
+ if(prob(50))
+ var/mob/living/simple_animal/pet/dog/corgi/D = locate() in .
+ if(D.gender == FEMALE)
+ qdel(D)
+ new /mob/living/simple_animal/pet/dog/corgi/Lisa(.)
+
+/datum/supply_pack/critter/corgis/exotic
+ name = "Exotic Corgi Crate"
+ desc = "Corgis fit for a king, these corgis come in a unique color to signify their superiority. Comes with a cute collar!"
+ cost = 5500
+ contains = list(/mob/living/simple_animal/pet/dog/corgi/exoticcorgi,
+ /obj/item/clothing/neck/petcollar)
+ crate_name = "exotic corgi crate"
+
+/datum/supply_pack/critter/cow
+ name = "Cow Crate"
+ desc = "The cow goes moo!"
+ cost = 3000
+ contains = list(/mob/living/simple_animal/cow)
+ crate_name = "cow crate"
+
+/datum/supply_pack/critter/fox
+ name = "Fox Crate"
+ desc = "The fox goes...? Comes with a collar!"//what does the fox say
+ cost = 5000
+ contains = list(/mob/living/simple_animal/pet/fox,
+ /obj/item/clothing/neck/petcollar)
+ crate_name = "fox crate"
+
+/datum/supply_pack/critter/goat
+ name = "Goat Crate"
+ desc = "The goat goes baa! Warranty void if used as a replacement for Pete."
+ cost = 2500
+ contains = list(/mob/living/simple_animal/hostile/retaliate/goat)
+ crate_name = "goat crate"
+
+/datum/supply_pack/critter/goose
+ name = "Goose Crate"
+ desc = "Angry and violent birds. Evil, evil creatures."
+ cost = 2500
+ contains = list(/mob/living/simple_animal/hostile/retaliate/goose)
+ crate_name = "goose crate"
+
+/datum/supply_pack/critter/pug
+ name = "Pug Crate"
+ desc = "Like a normal dog, but... squished. Comes with a nice collar!"
+ cost = 5000
+ contains = list(/mob/living/simple_animal/pet/dog/pug,
+ /obj/item/clothing/neck/petcollar)
+ crate_name = "pug crate"
+
+/datum/supply_pack/organic/critter/kiwi
+ name = "Space kiwi Crate"
+ cost = 2000
+ contains = list( /mob/living/simple_animal/kiwi)
+ crate_name = "space kiwi crate"
+
+/datum/supply_pack/critter/snake
+ name = "Snake Crate"
+ desc = "Tired of these MOTHER FUCKING snakes on this MOTHER FUCKING space station? Then this isn't the crate for you. Contains three poisonous snakes."
+ cost = 3000
+ contains = list(/mob/living/simple_animal/hostile/retaliate/poison/snake,
+ /mob/living/simple_animal/hostile/retaliate/poison/snake,
+ /mob/living/simple_animal/hostile/retaliate/poison/snake)
+ crate_name = "snake crate"
+
+/datum/supply_pack/critter/secbat
+ name = "Security Bat Crate"
+ desc = "Contains five security bats, perfect to Bat-up any security officer."
+ cost = 2500
+ contains = list(/mob/living/simple_animal/hostile/retaliate/bat/secbat,
+ /mob/living/simple_animal/hostile/retaliate/bat/secbat,
+ /mob/living/simple_animal/hostile/retaliate/bat/secbat,
+ /mob/living/simple_animal/hostile/retaliate/bat/secbat,
+ /mob/living/simple_animal/hostile/retaliate/bat/secbat)
+ crate_name = "security bat crate"
diff --git a/code/modules/cargo/packs/materials.dm b/code/modules/cargo/packs/materials.dm
new file mode 100644
index 0000000000..0f8ad2462a
--- /dev/null
+++ b/code/modules/cargo/packs/materials.dm
@@ -0,0 +1,170 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////// Canisters & Materials ////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/materials
+ group = "Canisters & Materials"
+
+/datum/supply_pack/materials/cardboard50
+ name = "50 Cardboard Sheets"
+ desc = "Create a bunch of boxes."
+ cost = 1000
+ contains = list(/obj/item/stack/sheet/cardboard/fifty)
+ crate_name = "cardboard sheets crate"
+
+/datum/supply_pack/materials/glass50
+ name = "50 Glass Sheets"
+ desc = "Let some nice light in with fifty glass sheets!"
+ cost = 850
+ contains = list(/obj/item/stack/sheet/glass/fifty)
+ crate_name = "glass sheets crate"
+
+/datum/supply_pack/materials/metal50
+ name = "50 Metal Sheets"
+ desc = "Any construction project begins with a good stack of fifty metal sheets!"
+ cost = 850
+ contains = list(/obj/item/stack/sheet/metal/fifty)
+ crate_name = "metal sheets crate"
+
+/datum/supply_pack/materials/plasteel20
+ name = "20 Plasteel Sheets"
+ desc = "Reinforce the station's integrity with twenty plasteel sheets!"
+ cost = 4700
+ contains = list(/obj/item/stack/sheet/plasteel/twenty)
+ crate_name = "plasteel sheets crate"
+
+/datum/supply_pack/materials/plasteel50
+ name = "50 Plasteel Sheets"
+ desc = "For when you REALLY have to reinforce something."
+ cost = 9050
+ contains = list(/obj/item/stack/sheet/plasteel/fifty)
+ crate_name = "plasteel sheets crate"
+
+/datum/supply_pack/materials/plastic50
+ name = "50 Plastic Sheets"
+ desc = "Build a limitless amount of toys with fifty plastic sheets!"
+ cost = 950
+ contains = list(/obj/item/stack/sheet/plastic/fifty)
+ crate_name = "plastic sheets crate"
+
+/datum/supply_pack/materials/sandstone30
+ name = "30 Sandstone Blocks"
+ desc = "Neither sandy nor stoney, these thirty blocks will still get the job done."
+ cost = 800
+ contains = list(/obj/item/stack/sheet/mineral/sandstone/thirty)
+ crate_name = "sandstone blocks crate"
+
+/datum/supply_pack/materials/wood50
+ name = "50 Wood Planks"
+ desc = "Turn cargo's boring metal groundwork into beautiful panelled flooring and much more with fifty wooden planks!"
+ cost = 1450
+ contains = list(/obj/item/stack/sheet/mineral/wood/fifty)
+ crate_name = "wood planks crate"
+
+/datum/supply_pack/materials/rcdammo
+ name = "Spare RDC ammo"
+ desc = "This crate contains sixteen RCD ammo packs, to help with any holes or projects people mite be working on."
+ cost = 3750
+ contains = list(/obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo,
+ /obj/item/rcd_ammo)
+ crate_name = "rcd ammo"
+
+/datum/supply_pack/materials/bz
+ name = "BZ Canister Crate"
+ desc = "Contains a canister of BZ. Requires Toxins access to open."
+ cost = 7500 // Costs 3 credits more than what you can get for selling it.
+ access = ACCESS_TOX_STORAGE
+ contains = list(/obj/machinery/portable_atmospherics/canister/bz)
+ crate_name = "BZ canister crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/materials/carbon_dio
+ name = "Carbon Dioxide Canister"
+ desc = "Contains a canister of Carbon Dioxide."
+ cost = 3000
+ contains = list(/obj/machinery/portable_atmospherics/canister/carbon_dioxide)
+ crate_name = "carbon dioxide canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/nitrogen
+ name = "Nitrogen Canister"
+ desc = "Contains a canister of Nitrogen."
+ cost = 2000
+ contains = list(/obj/machinery/portable_atmospherics/canister/nitrogen)
+ crate_name = "nitrogen canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/nitrous_oxide_canister
+ name = "Nitrous Oxide Canister"
+ desc = "Contains a canister of Nitrous Oxide. Requires Atmospherics access to open."
+ cost = 3000
+ access = ACCESS_ATMOSPHERICS
+ contains = list(/obj/machinery/portable_atmospherics/canister/nitrous_oxide)
+ crate_name = "nitrous oxide canister crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/materials/oxygen
+ name = "Oxygen Canister"
+ desc = "Contains a canister of Oxygen. Canned in Druidia."
+ cost = 1500
+ contains = list(/obj/machinery/portable_atmospherics/canister/oxygen)
+ crate_name = "oxygen canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/water_vapor
+ name = "Water Vapor Canister"
+ desc = "Contains a canister of Water Vapor. I swear to god if you open this in the halls..."
+ cost = 2500
+ contains = list(/obj/machinery/portable_atmospherics/canister/water_vapor)
+ crate_name = "water vapor canister crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/fueltank
+ name = "Fuel Tank Crate"
+ desc = "Contains a welding fuel tank. Caution, highly flammable."
+ cost = 800
+ contains = list(/obj/structure/reagent_dispensers/fueltank)
+ crate_name = "fuel tank crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/watertank
+ name = "Water Tank Crate"
+ desc = "Contains a tank of dihydrogen monoxide... sounds dangerous."
+ cost = 600
+ contains = list(/obj/structure/reagent_dispensers/watertank)
+ crate_name = "water tank crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/foamtank
+ name = "Firefighting Foam Tank Crate"
+ desc = "Contains a tank of firefighting foam. Also known as \"plasmaman's bane\"."
+ cost = 1500
+ contains = list(/obj/structure/reagent_dispensers/foamtank)
+ crate_name = "foam tank crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/materials/hightank
+ name = "Large Water Tank Crate"
+ desc = "Contains a high-capacity water tank. Useful for botany or other service jobs."
+ cost = 1200
+ contains = list(/obj/structure/reagent_dispensers/watertank/high)
+ crate_name = "high-capacity water tank crate"
+ crate_type = /obj/structure/closet/crate/large
diff --git a/code/modules/cargo/packs/medical.dm b/code/modules/cargo/packs/medical.dm
new file mode 100644
index 0000000000..656474cc1d
--- /dev/null
+++ b/code/modules/cargo/packs/medical.dm
@@ -0,0 +1,228 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Medical /////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/medical
+ group = "Medical"
+ crate_type = /obj/structure/closet/crate/medical
+
+/datum/supply_pack/medical/firstaidbruises
+ name = "Bruise Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing bruises and broken bones."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/brute,
+ /obj/item/storage/firstaid/brute,
+ /obj/item/storage/firstaid/brute)
+ crate_name = "brute treatment kit crate"
+
+/datum/supply_pack/medical/firstaidburns
+ name = "Burn Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing severe burns."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/fire,
+ /obj/item/storage/firstaid/fire,
+ /obj/item/storage/firstaid/fire)
+ crate_name = "burn treatment kit crate"
+
+/datum/supply_pack/medical/bloodpacks
+ name = "Blood Pack Variety Crate"
+ desc = "Contains ten different blood packs for reintroducing blood to patients."
+ cost = 3000
+ contains = list(/obj/item/reagent_containers/blood/random,
+ /obj/item/reagent_containers/blood/random,
+ /obj/item/reagent_containers/blood/APlus,
+ /obj/item/reagent_containers/blood/AMinus,
+ /obj/item/reagent_containers/blood/BPlus,
+ /obj/item/reagent_containers/blood/BMinus,
+ /obj/item/reagent_containers/blood/OPlus,
+ /obj/item/reagent_containers/blood/OMinus,
+ /obj/item/reagent_containers/blood/lizard,
+ /obj/item/reagent_containers/blood/jellyblood,
+ /obj/item/reagent_containers/blood/insect)
+ crate_name = "blood freezer"
+ crate_type = /obj/structure/closet/crate/freezer
+
+/datum/supply_pack/medical/bloodpackssynth
+ name = "Synthetics Blood Pack Crate"
+ desc = "Contains five synthetics blood packs for reintroducing blood to patients."
+ cost = 3000
+ contains = list(/obj/item/reagent_containers/blood/synthetics,
+ /obj/item/reagent_containers/blood/synthetics,
+ /obj/item/reagent_containers/blood/synthetics,
+ /obj/item/reagent_containers/blood/synthetics,
+ /obj/item/reagent_containers/blood/synthetics)
+ crate_name = "blood freezer"
+ crate_type = /obj/structure/closet/crate/freezer
+
+/datum/supply_pack/medical/defibs
+ name = "Defibrillator Crate"
+ desc = "Contains two defibrillators for bringing the recently deceased back to life."
+ cost = 2500
+ contains = list(/obj/item/defibrillator/loaded,
+ /obj/item/defibrillator/loaded)
+ crate_name = "defibrillator crate"
+
+/datum/supply_pack/medical/firstaid
+ name = "First Aid Kit Crate"
+ desc = "Contains four first aid kits for healing most types of wounds."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular,
+ /obj/item/storage/firstaid/regular)
+ crate_name = "first aid kit crate"
+
+/datum/supply_pack/medical/iv_drip
+ name = "IV Drip Crate"
+ desc = "Contains a single IV drip stand for intravenous delivery."
+ cost = 800
+ contains = list(/obj/machinery/iv_drip)
+ crate_name = "iv drip crate"
+
+/datum/supply_pack/science/adv_surgery_tools
+ name = "Med-Co Advanced surgery tools"
+ desc = "A full set of Med-Co advanced surgery tools, this crate also comes with a spay of synth flesh as well as a can of . Requires Surgery access to open."
+ cost = 5500
+ access = ACCESS_SURGERY
+ contains = list(/obj/item/storage/belt/medical/surgery_belt_adv,
+ /obj/item/reagent_containers/medspray/synthflesh,
+ /obj/item/reagent_containers/medspray/sterilizine)
+ crate_name = "medco newest surgery tools"
+ crate_type = /obj/structure/closet/crate/medical
+
+/datum/supply_pack/medical/medicalhardsuit
+ name = "Medical Hardsuit"
+ desc = "Got people being spaced left and right? Hole in the same room as the dead body of Hos or cap? Fear not, now you can buy one medical hardsuit with a mask and air tank to save your fellow crewmembers."
+ cost = 2750
+ contains = list(/obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/suit/space/hardsuit/medical)
+ crate_name = "medical hardsuit"
+
+/datum/supply_pack/medical/supplies
+ name = "Medical Supplies Crate"
+ desc = "Contains seven beakers, syringes, and bodybags. Three morphine bottles, four insulin pills. Two charcoal bottles, epinephrine bottles, antitoxin bottles, and large beakers. Finally, a single roll of medical gauze, as well as a bottle of stimulant pills for long, hard work days. German doctor not included."
+ cost = 2500
+ contains = list(/obj/item/reagent_containers/glass/bottle/charcoal,
+ /obj/item/reagent_containers/glass/bottle/charcoal,
+ /obj/item/reagent_containers/glass/bottle/epinephrine,
+ /obj/item/reagent_containers/glass/bottle/epinephrine,
+ /obj/item/reagent_containers/glass/bottle/morphine,
+ /obj/item/reagent_containers/glass/bottle/morphine,
+ /obj/item/reagent_containers/glass/bottle/morphine,
+ /obj/item/reagent_containers/glass/bottle/toxin,
+ /obj/item/reagent_containers/glass/bottle/toxin,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/reagent_containers/pill/insulin,
+ /obj/item/reagent_containers/pill/insulin,
+ /obj/item/reagent_containers/pill/insulin,
+ /obj/item/reagent_containers/pill/insulin,
+ /obj/item/stack/medical/gauze,
+ /obj/item/storage/box/beakers,
+ /obj/item/storage/box/medsprays,
+ /obj/item/storage/box/syringes,
+ /obj/item/storage/box/bodybags,
+ /obj/item/storage/pill_bottle/stimulant)
+ crate_name = "medical supplies crate"
+
+/datum/supply_pack/medical/vending
+ name = "Medical Vending Crate"
+ desc = "Contains refills for medical vending machines."
+ cost = 2000
+ contains = list(/obj/item/vending_refill/medical,
+ /obj/item/vending_refill/wallmed)
+ crate_name = "medical vending crate"
+
+/datum/supply_pack/medical/sprays
+ name = "Medical Sprays"
+ desc = "Contains two cans of Styptic Spray, Silver Sulfadiazine Spray, Synthflesh Spray and Sterilizer Compound Spray."
+ cost = 2250
+ contains = list(/obj/item/reagent_containers/medspray/styptic,
+ /obj/item/reagent_containers/medspray/styptic,
+ /obj/item/reagent_containers/medspray/silver_sulf,
+ /obj/item/reagent_containers/medspray/silver_sulf,
+ /obj/item/reagent_containers/medspray/synthflesh,
+ /obj/item/reagent_containers/medspray/synthflesh,
+ /obj/item/reagent_containers/medspray/sterilizine,
+ /obj/item/reagent_containers/medspray/sterilizine)
+ crate_name = "medical supplies crate"
+
+/datum/supply_pack/medical/firstaidmixed
+ name = "Mixed Medical Kits"
+ desc = "Contains one of each medical kits for dealing with a variety of injured crewmembers."
+ cost = 1250
+ contains = list(/obj/item/storage/firstaid/toxin,
+ /obj/item/storage/firstaid/o2,
+ /obj/item/storage/firstaid/brute,
+ /obj/item/storage/firstaid/fire,
+ /obj/item/storage/firstaid/regular)
+ crate_name = "medical supplies crate"
+
+/datum/supply_pack/medical/firstaidoxygen
+ name = "Oxygen Deprivation Kit Crate"
+ desc = "Contains three first aid kits focused on helping oxygen deprivation victims."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/o2,
+ /obj/item/storage/firstaid/o2,
+ /obj/item/storage/firstaid/o2)
+ crate_name = "oxygen deprivation kit crate"
+
+/datum/supply_pack/medical/advrad
+ name = "Radiation Treatment Crate Deluxe"
+ desc = "A crate for when radiation is out of hand... Contains two rad-b-gone kits, one bottle of anti radiation deluxe pill bottle, as well as a radiation treatment deluxe pill bottle!"
+ cost = 3500
+ contains = list(/obj/item/storage/pill_bottle/antirad_plus,
+ /obj/item/storage/pill_bottle/mutarad,
+ /obj/item/storage/firstaid/radbgone,
+ /obj/item/storage/firstaid/radbgone,
+ /obj/item/geiger_counter,
+ /obj/item/geiger_counter)
+ crate_name = "radiation protection crate"
+ crate_type = /obj/structure/closet/crate/radiation
+
+/datum/supply_pack/medical/surgery
+ name = "Surgical Supplies Crate"
+ desc = "Do you want to perform surgery, but don't have one of those fancy shmancy degrees? Just get started with this crate containing a medical duffelbag, Sterilizine spray and collapsible roller bed."
+ cost = 1300
+ contains = list(/obj/item/storage/backpack/duffelbag/med/surgery,
+ /obj/item/reagent_containers/medspray/sterilizine,
+ /obj/item/roller)
+ crate_name = "surgical supplies crate"
+
+/datum/supply_pack/medical/firstaidtoxins
+ name = "Toxin Treatment Kit Crate"
+ desc = "Contains three first aid kits focused on healing damage dealt by heavy toxins."
+ cost = 1000
+ contains = list(/obj/item/storage/firstaid/toxin,
+ /obj/item/storage/firstaid/toxin,
+ /obj/item/storage/firstaid/toxin)
+ crate_name = "toxin treatment kit crate"
+
+/datum/supply_pack/medical/virus
+ name = "Virus Crate"
+ desc = "Contains twelve different bottles, containing several viral samples for virology research. Also includes seven beakers and syringes. Balled-up jeans not included. Requires CMO access to open."
+ cost = 2500
+ access = ACCESS_CMO
+ contains = list(/obj/item/reagent_containers/glass/bottle/flu_virion,
+ /obj/item/reagent_containers/glass/bottle/cold,
+ /obj/item/reagent_containers/glass/bottle/random_virus,
+ /obj/item/reagent_containers/glass/bottle/random_virus,
+ /obj/item/reagent_containers/glass/bottle/random_virus,
+ /obj/item/reagent_containers/glass/bottle/random_virus,
+ /obj/item/reagent_containers/glass/bottle/fake_gbs,
+ /obj/item/reagent_containers/glass/bottle/magnitis,
+ /obj/item/reagent_containers/glass/bottle/pierrot_throat,
+ /obj/item/reagent_containers/glass/bottle/brainrot,
+ /obj/item/reagent_containers/glass/bottle/anxiety,
+ /obj/item/reagent_containers/glass/bottle/beesease,
+ /obj/item/storage/box/syringes,
+ /obj/item/storage/box/beakers,
+ /obj/item/reagent_containers/glass/bottle/mutagen)
+ crate_name = "virus crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+ dangerous = TRUE
diff --git a/code/modules/cargo/packs/misc.dm b/code/modules/cargo/packs/misc.dm
new file mode 100644
index 0000000000..c380d5411e
--- /dev/null
+++ b/code/modules/cargo/packs/misc.dm
@@ -0,0 +1,230 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Miscellaneous ///////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/misc
+ group = "Miscellaneous Supplies"
+
+/datum/supply_pack/misc/artsupply
+ name = "Art Supplies"
+ desc = "Make some happy little accidents with six canvasses, two easels, two boxes of crayons, and a rainbow crayon!"
+ cost = 800
+ contains = list(/obj/structure/easel,
+ /obj/structure/easel,
+ /obj/item/canvas/nineteenXnineteen,
+ /obj/item/canvas/nineteenXnineteen,
+ /obj/item/canvas/twentythreeXnineteen,
+ /obj/item/canvas/twentythreeXnineteen,
+ /obj/item/canvas/twentythreeXtwentythree,
+ /obj/item/canvas/twentythreeXtwentythree,
+ /obj/item/storage/crayons,
+ /obj/item/storage/crayons,
+ /obj/item/toy/crayon/rainbow,
+ /obj/item/toy/crayon/white,
+ /obj/item/toy/crayon/white)
+ crate_name = "art supply crate"
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/misc/captain_pen
+ name = "Captain Pen"
+ desc = "A spare Captain fountain pen."
+ access = ACCESS_CAPTAIN
+ cost = 10000
+ contains = list(/obj/item/pen/fountain/captain)
+ crate_name = "captain pen"
+ crate_type = /obj/structure/closet/crate/secure/weapon //It is a combat pen
+
+/datum/supply_pack/misc/bicycle
+ name = "Bicycle"
+ desc = "Nanotrasen reminds all employees to never toy with powers outside their control."
+ cost = 1000000
+ contains = list(/obj/vehicle/ridden/bicycle)
+ crate_name = "Bicycle Crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/misc/bigband
+ name = "Big Band Instrument Collection"
+ desc = "Get your sad station movin' and groovin' with this fine collection! Contains nine different instruments!"
+ cost = 5000
+ crate_name = "Big band musical instruments collection"
+ contains = list(/obj/item/instrument/violin,
+ /obj/item/instrument/guitar,
+ /obj/item/instrument/glockenspiel,
+ /obj/item/instrument/accordion,
+ /obj/item/instrument/saxophone,
+ /obj/item/instrument/trombone,
+ /obj/item/instrument/recorder,
+ /obj/item/instrument/harmonica,
+ /obj/structure/piano/unanchored)
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/misc/book_crate
+ name = "Book Crate"
+ desc = "Surplus from the Nanotrasen Archives, these five books are sure to be good reads."
+ cost = 1500
+ contains = list(/obj/item/book/codex_gigas,
+ /obj/item/book/manual/random/,
+ /obj/item/book/manual/random/,
+ /obj/item/book/manual/random/,
+ /obj/item/book/random/triple)
+ crate_type = /obj/structure/closet/crate/wooden
+
+/datum/supply_pack/misc/paper
+ name = "Bureaucracy Crate"
+ desc = "High stacks of papers on your desk Are a big problem - make it Pea-sized with these bureaucratic supplies! Contains five pens, some camera film, hand labeler supplies, a paper bin, three folders, two clipboards and two stamps as well as a briefcase."//that was too forced
+ cost = 1500
+ contains = list(/obj/structure/filingcabinet/chestdrawer/wheeled,
+ /obj/item/camera_film,
+ /obj/item/hand_labeler,
+ /obj/item/hand_labeler_refill,
+ /obj/item/hand_labeler_refill,
+ /obj/item/paper_bin,
+ /obj/item/pen/fourcolor,
+ /obj/item/pen/fourcolor,
+ /obj/item/pen,
+ /obj/item/pen/blue,
+ /obj/item/pen/red,
+ /obj/item/folder/blue,
+ /obj/item/folder/red,
+ /obj/item/folder/yellow,
+ /obj/item/clipboard,
+ /obj/item/clipboard,
+ /obj/item/stamp,
+ /obj/item/stamp/denied,
+ /obj/item/storage/briefcase)
+ crate_name = "bureaucracy crate"
+
+/datum/supply_pack/misc/fountainpens
+ name = "Calligraphy Crate"
+ desc = "Sign death warrants in style with these seven executive fountain pens."
+ cost = 730
+ contains = list(/obj/item/storage/box/fountainpens,
+ /obj/item/paper_bin)
+ crate_type = /obj/structure/closet/crate/wooden
+ crate_name = "calligraphy crate"
+
+/datum/supply_pack/misc/wrapping_paper
+ name = "Festive Wrapping Paper Crate"
+ desc = "Want to mail your loved ones gift-wrapped chocolates, stuffed animals, the Clown's severed head? You can do all that, with this crate full of wrapping paper."
+ cost = 1000
+ contains = list(/obj/item/stack/wrapping_paper)
+ crate_type = /obj/structure/closet/crate/wooden
+ crate_name = "festive wrapping paper crate"
+
+/datum/supply_pack/misc/paper_work
+ name = "Freelance Paper work"
+ desc = "The Nanotrasen Primary Bureaucratic Database Intelligence (PDBI) reports that the station has not completed its funding and grant paperwork this solar cycle. In order to gain further funding, your station is required to fill out (20) ten of these forms or no additional capital will be disbursed. We have sent you ten copies of the following form and we expect every one to be up to Nanotrasen Standards." // Disbursement. It's not a typo, look it up.
+ cost = 700 // Net of 0 credits but makes (120 x 20 = 2400)
+ contains = list(/obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/folder/paperwork,
+ /obj/item/pen/fountain
+ )
+ crate_name = "Paperwork"
+
+/datum/supply_pack/misc/funeral
+ name = "Funeral Supply crate"
+ desc = "At the end of the day, someone's gonna want someone dead. Give them a proper send-off with these funeral supplies! Contains a coffin with burial garmets and flowers."
+ cost = 800
+ contains = list(/obj/item/clothing/under/burial,
+ /obj/item/reagent_containers/food/snacks/grown/harebell,
+ /obj/item/reagent_containers/food/snacks/grown/poppy/geranium
+ )
+ crate_name = "coffin"
+ crate_type = /obj/structure/closet/crate/coffin
+
+/datum/supply_pack/misc/jukebox
+ name = "Jukebox"
+ cost = 10000
+ contains = list(/obj/machinery/jukebox)
+ crate_name = "Jukebox"
+
+/datum/supply_pack/misc/lewd
+ name = "Lewd Crate" // OwO
+ desc = "Psss want to have a good time with your sluts? Well I got what you want maid clothing, dildos, collars and more!"
+ cost = 5250
+ contraband = TRUE
+ contains = list(/obj/item/dildo/custom,
+ /obj/item/dildo/custom,
+ /obj/item/vending_refill/kink,
+ /obj/item/vending_refill/kink,
+ /obj/item/clothing/under/maid,
+ /obj/item/clothing/under/maid,
+ /obj/item/electropack/shockcollar,
+ /obj/item/electropack/shockcollar,
+ /obj/item/restraints/handcuffs/fake/kinky,
+ /obj/item/restraints/handcuffs/fake/kinky,
+ /obj/item/clothing/head/kitty/genuine, // Why its illegal
+ /obj/item/clothing/head/kitty/genuine,
+ /obj/item/storage/pill_bottle/penis_enlargement,
+ /obj/structure/reagent_dispensers/keg/aphro)
+ crate_name = "lewd kit"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/misc/lewdkeg
+ name = "Lewd Deluxe Keg"
+ desc = "That other stuff not getting you ready? Well I have a Chemslut making tons of the good stuff."
+ cost = 7500 //It can be a weapon
+ contraband = TRUE
+ contains = list(/obj/structure/reagent_dispensers/keg/aphro/strong)
+ crate_name = "deluxe keg"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/misc/religious_supplies
+ name = "Religious Supplies Crate"
+ desc = "Keep your local chaplain happy and well-supplied, lest they call down judgement upon your cargo bay. Contains two bottles of holywater, bibles, chaplain robes, and burial garmets."
+ cost = 4000 // it costs so much because the Space Church is ran by Space Jews
+ contains = list(/obj/item/reagent_containers/food/drinks/bottle/holywater,
+ /obj/item/reagent_containers/food/drinks/bottle/holywater,
+ /obj/item/storage/book/bible/booze,
+ /obj/item/storage/book/bible/booze,
+ /obj/item/clothing/suit/hooded/chaplain_hoodie,
+ /obj/item/clothing/suit/hooded/chaplain_hoodie
+ )
+ crate_name = "religious supplies crate"
+
+/datum/supply_pack/misc/randomised/promiscuous
+ name = "Promiscuous Organs"
+ desc = "Do YOU want to have more genital? Well we have just the thing for you~. This crate has two autosurgeon, that will let you have a new sex, organ to impress that hot stud and or chick."
+ cost = 4000 //Only get 2!
+ contraband = TRUE
+ var/num_contained = 2
+ contains = list(/obj/item/autosurgeon/penis,
+ /obj/item/autosurgeon/testicles,
+ /obj/item/autosurgeon/vagina,
+ /obj/item/autosurgeon/breasts,
+ /obj/item/autosurgeon/womb)
+ crate_name = "promiscuous organs"
+
+/datum/supply_pack/misc/toner
+ name = "Toner Crate"
+ desc = "Spent too much ink printing butt pictures? Fret not, with these six toner refills, you'll be printing butts 'till the cows come home!'"
+ cost = 1000
+ contains = list(/obj/item/toner,
+ /obj/item/toner,
+ /obj/item/toner,
+ /obj/item/toner,
+ /obj/item/toner,
+ /obj/item/toner)
+ crate_name = "toner crate"
diff --git a/code/modules/cargo/packs/organic.dm b/code/modules/cargo/packs/organic.dm
new file mode 100644
index 0000000000..2b5df207c3
--- /dev/null
+++ b/code/modules/cargo/packs/organic.dm
@@ -0,0 +1,290 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Organic /////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/organic
+ group = "Food & Hydroponics"
+ crate_type = /obj/structure/closet/crate/freezer
+
+/datum/supply_pack/organic/hydroponics/beekeeping_suits
+ name = "Beekeeper Suit Crate"
+ desc = "Bee business booming? Better be benevolent and boost botany by bestowing bi-Beekeeper-suits! Contains two beekeeper suits and matching headwear."
+ cost = 1300
+ contains = list(/obj/item/clothing/head/beekeeper_head,
+ /obj/item/clothing/suit/beekeeper_suit,
+ /obj/item/clothing/head/beekeeper_head,
+ /obj/item/clothing/suit/beekeeper_suit)
+ crate_name = "beekeeper suits"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/hydroponics/beekeeping_fullkit
+ name = "Beekeeping Starter Crate"
+ desc = "BEES BEES BEES. Contains three honey frames, a beekeeper suit and helmet, flyswatter, bee house, and, of course, a pure-bred Nanotrasen-Standardized Queen Bee!"
+ cost = 1800
+ contains = list(/obj/structure/beebox/unwrenched,
+ /obj/item/honey_frame,
+ /obj/item/honey_frame,
+ /obj/item/honey_frame,
+ /obj/item/queen_bee/bought,
+ /obj/item/clothing/head/beekeeper_head,
+ /obj/item/clothing/suit/beekeeper_suit,
+ /obj/item/melee/flyswatter)
+ crate_name = "beekeeping starter crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/candy/randomised
+ name = "Candy Crate"
+ desc = "For people that have a insatiable sweet tooth! Has ten candies to be eaten up.."
+ cost = 2500
+ var/num_contained = 10 //number of items picked to be contained in a randomised crate
+ contains = list(/obj/item/reagent_containers/food/snacks/candy,
+ /obj/item/reagent_containers/food/snacks/lollipop,
+ /obj/item/reagent_containers/food/snacks/gumball,
+ /obj/item/reagent_containers/food/snacks/chocolateegg,
+ /obj/item/reagent_containers/food/snacks/donut,
+ /obj/item/reagent_containers/food/snacks/cookie,
+ /obj/item/reagent_containers/food/snacks/sugarcookie,
+ /obj/item/reagent_containers/food/snacks/chococornet,
+ /obj/item/reagent_containers/food/snacks/mint,
+ /obj/item/reagent_containers/food/snacks/spiderlollipop,
+ /obj/item/reagent_containers/food/snacks/chococoin,
+ /obj/item/reagent_containers/food/snacks/fudgedice,
+ /obj/item/reagent_containers/food/snacks/chocoorange,
+ /obj/item/reagent_containers/food/snacks/honeybar,
+ /obj/item/reagent_containers/food/snacks/tinychocolate,
+ /obj/item/reagent_containers/food/snacks/spacetwinkie,
+ /obj/item/reagent_containers/food/snacks/syndicake,
+ /obj/item/reagent_containers/food/snacks/cheesiehonkers,
+ /obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull,
+ /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin,
+ /obj/item/reagent_containers/food/snacks/candy_corn,
+ /obj/item/reagent_containers/food/snacks/candiedapple,
+ /obj/item/reagent_containers/food/snacks/chocolatebar,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/storage/fancy/heart_box,
+ /obj/item/storage/fancy/donut_box)
+ crate_name = "candy crate"
+
+/datum/supply_pack/organic/cutlery
+ name = "Kitchen Cutlery Deluxe Set"
+ desc = "Need to slice and dice away those ''Tomatos'' well we got what you need! From a nice set of knifes, forks, plates, glasses, and a whetstone for when you got some grizzle that is a bit harder to slice then normal."
+ cost = 10000
+ contraband = TRUE
+ contains = list(/obj/item/sharpener,
+ /obj/item/kitchen/fork,
+ /obj/item/kitchen/fork,
+ /obj/item/kitchen/knife,
+ /obj/item/kitchen/knife,
+ /obj/item/kitchen/knife,
+ /obj/item/kitchen/knife,
+ /obj/item/kitchen/knife/butcher,
+ /obj/item/kitchen/knife/butcher,
+ /obj/item/kitchen/rollingpin, //Deluxe for a reason
+ /obj/item/trash/plate,
+ /obj/item/trash/plate,
+ /obj/item/trash/plate,
+ /obj/item/trash/plate,
+ /obj/item/reagent_containers/food/drinks/drinkingglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass,
+ /obj/item/reagent_containers/food/drinks/drinkingglass/shotglass)
+ crate_name = "kitchen cutlery deluxe set"
+
+/datum/supply_pack/organic/food
+ name = "Food Crate"
+ desc = "Get things cooking with this crate full of useful ingredients! Contains a two dozen eggs, three bananas, and two bags of flour and rice, two cartons of milk, soymilk, as well as salt and pepper shakers, a enzyme and sugar bottle, and three slabs of monkeymeat."
+ cost = 1000
+ contains = list(/obj/item/reagent_containers/food/condiment/flour,
+ /obj/item/reagent_containers/food/condiment/flour,
+ /obj/item/reagent_containers/food/condiment/rice,
+ /obj/item/reagent_containers/food/condiment/rice,
+ /obj/item/reagent_containers/food/condiment/milk,
+ /obj/item/reagent_containers/food/condiment/milk,
+ /obj/item/reagent_containers/food/condiment/soymilk,
+ /obj/item/reagent_containers/food/condiment/saltshaker,
+ /obj/item/reagent_containers/food/condiment/peppermill,
+ /obj/item/storage/fancy/egg_box,
+ /obj/item/storage/fancy/egg_box,
+ /obj/item/reagent_containers/food/condiment/enzyme,
+ /obj/item/reagent_containers/food/condiment/sugar,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/meat/slab/monkey,
+ /obj/item/reagent_containers/food/snacks/grown/banana,
+ /obj/item/reagent_containers/food/snacks/grown/banana,
+ /obj/item/reagent_containers/food/snacks/grown/banana)
+ crate_name = "food crate"
+
+/datum/supply_pack/organic/cream_piee
+ name = "High-yield Clown-grade Cream Pie Crate"
+ desc = "Designed by Aussec's Advanced Warfare Research Division, these high-yield, Clown-grade cream pies are powered by a synergy of performance and efficiency. Guaranteed to provide maximum results."
+ cost = 6000
+ contains = list(/obj/item/storage/backpack/duffelbag/clown/cream_pie)
+ crate_name = "party equipment crate"
+ contraband = TRUE
+ access = ACCESS_THEATRE
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/organic/hunting
+ name = "Huntting gear"
+ desc = "Even in space, we can fine prey to hunt, this crate contains everthing a fine hunter needs to have a sporting time. This crate needs armory access to open. A true huntter only needs a fine bottle of cognac, a nice coat, some good o' cigars, and of cource a huntting shotgun. "
+ cost = 3500
+ contraband = TRUE
+ contains = list(/obj/item/clothing/head/flatcap,
+ /obj/item/clothing/suit/hooded/wintercoat/captain,
+ /obj/item/reagent_containers/food/drinks/bottle/cognac,
+ /obj/item/storage/fancy/cigarettes/cigars/havana,
+ /obj/item/clothing/gloves/color/white,
+ /obj/item/clothing/under/rank/curator,
+ /obj/item/gun/ballistic/shotgun/lethal)
+ access = ACCESS_ARMORY
+ crate_name = "sporting crate"
+ crate_type = /obj/structure/closet/crate/secure // Would have liked a wooden crate but access >:(
+
+/datum/supply_pack/organic/hydroponics
+ name = "Hydroponics Crate"
+ desc = "Supplies for growing a great garden! Contains two bottles of ammonia, two Plant-B-Gone spray bottles, a hatchet, cultivator, plant analyzer, as well as a pair of leather gloves and a botanist's apron."
+ cost = 1750
+ contains = list(/obj/item/reagent_containers/spray/plantbgone,
+ /obj/item/reagent_containers/spray/plantbgone,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/hatchet,
+ /obj/item/cultivator,
+ /obj/item/plant_analyzer,
+ /obj/item/clothing/gloves/botanic_leather,
+ /obj/item/clothing/suit/apron)
+ crate_name = "hydroponics crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/hydroponics/hydrotank
+ name = "Hydroponics Backpack Crate"
+ desc = "Bring on the flood with this high-capacity backpack crate. Contains 500 units of life-giving H2O. Requires hydroponics access to open."
+ cost = 1200
+ access = ACCESS_HYDROPONICS
+ contains = list(/obj/item/watertank)
+ crate_name = "hydroponics backpack crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/organic/mre
+ name = "MRE supply kit (emergency rations)"
+ desc = "The lights are out. Oxygen's running low. You've run out of food except space weevils. Don't let this be you! Order our NT branded MRE kits today! This pack contains 5 MRE packs with a randomized menu and an oxygen tank."
+ cost = 2000
+ contains = list(/obj/item/storage/box/mre/menu1/safe,
+ /obj/item/storage/box/mre/menu1/safe,
+ /obj/item/storage/box/mre/menu2/safe,
+ /obj/item/storage/box/mre/menu2/safe,
+ /obj/item/storage/box/mre/menu3,
+ /obj/item/storage/box/mre/menu4/safe)
+ crate_name = "MRE crate (emergency rations)"
+
+/datum/supply_pack/organic/pizza
+ name = "Pizza Crate"
+ desc = "Best prices on this side of the galaxy. All deliveries are guaranteed to be 99% anomaly-free!"
+ cost = 6000 // Best prices this side of the galaxy.
+ contains = list(/obj/item/pizzabox/margherita,
+ /obj/item/pizzabox/mushroom,
+ /obj/item/pizzabox/meat,
+ /obj/item/pizzabox/vegetable,
+ /obj/item/pizzabox/pineapple)
+ crate_name = "pizza crate"
+ var/static/anomalous_box_provided = FALSE
+
+/datum/supply_pack/organic/pizza/fill(obj/structure/closet/crate/C)
+ . = ..()
+ if(!anomalous_box_provided)
+ for(var/obj/item/pizzabox/P in C)
+ if(prob(1)) //1% chance for each box, so 4% total chance per order
+ var/obj/item/pizzabox/infinite/fourfiveeight = new(C)
+ fourfiveeight.boxtag = P.boxtag
+ qdel(P)
+ anomalous_box_provided = TRUE
+ log_game("An anomalous pizza box was provided in a pizza crate at during cargo delivery")
+ if(prob(50))
+ addtimer(CALLBACK(src, .proc/anomalous_pizza_report), rand(300, 1800))
+ else
+ message_admins("An anomalous pizza box was silently created with no command report in a pizza crate delivery.")
+ break
+
+/datum/supply_pack/organic/pizza/proc/anomalous_pizza_report()
+ print_command_report("[station_name()], our anomalous materials divison has reported a missing object that is highly likely to have been sent to your station during a routine cargo \
+ delivery. Please search all crates and manifests provided with the delivery and return the object if is located. The object resembles a standard \[DATA EXPUNGED\] and is to be \
+ considered \[REDACTED\] and returned at your leisure. Note that objects the anomaly produces are specifically attuned exactly to the individual opening the anomaly; regardless \
+ of species, the individual will find the object edible and it will taste great according to their personal definitions, which vary significantly based on person and species.")
+
+/datum/supply_pack/organic/potted_plants
+ name = "Potted Plants Crate"
+ desc = "Spruce up the station with these lovely plants! Contains a random assortment of five potted plants from Nanotrasen's potted plant research division. Warranty void if thrown."
+ cost = 730
+ contains = list(/obj/item/twohanded/required/kirbyplants/random,
+ /obj/item/twohanded/required/kirbyplants/random,
+ /obj/item/twohanded/required/kirbyplants/random,
+ /obj/item/twohanded/required/kirbyplants/random,
+ /obj/item/twohanded/required/kirbyplants/random)
+ crate_name = "potted plants crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/seeds
+ name = "Seeds Crate"
+ desc = "Big things have small beginnings. Contains thirteen different seeds."
+ cost = 1250
+ contains = list(/obj/item/seeds/chili,
+ /obj/item/seeds/berry,
+ /obj/item/seeds/corn,
+ /obj/item/seeds/eggplant,
+ /obj/item/seeds/tomato,
+ /obj/item/seeds/soya,
+ /obj/item/seeds/wheat,
+ /obj/item/seeds/wheat/rice,
+ /obj/item/seeds/carrot,
+ /obj/item/seeds/sunflower,
+ /obj/item/seeds/chanter,
+ /obj/item/seeds/potato,
+ /obj/item/seeds/sugarcane)
+ crate_name = "seeds crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
+
+/datum/supply_pack/organic/vday
+ name = "Surplus Valentine Crate"
+ desc = "Turns out we got warehouses of this love-y dove-y crap. Were sending out small barged buddle of Valentine gear. This crate has two boxes of chocolate, three poppy flowers, five candy hearts, and three cards."
+ cost = 3000
+ contraband = TRUE
+ contains = list(/obj/item/storage/fancy/heart_box,
+ /obj/item/storage/fancy/heart_box,
+ /obj/item/reagent_containers/food/snacks/grown/poppy,
+ /obj/item/reagent_containers/food/snacks/grown/poppy,
+ /obj/item/reagent_containers/food/snacks/grown/poppy,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/reagent_containers/food/snacks/candyheart,
+ /obj/item/valentine,
+ /obj/item/valentine,
+ /obj/item/valentine)
+ crate_name = "valentine crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/organic/exoticseeds
+ name = "Exotic Seeds Crate"
+ desc = "Any entrepreneuring botanist's dream. Contains twelve different seeds, including three replica-pod seeds and two mystery seeds!"
+ cost = 1500
+ contains = list(/obj/item/seeds/nettle,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/replicapod,
+ /obj/item/seeds/plump,
+ /obj/item/seeds/liberty,
+ /obj/item/seeds/amanita,
+ /obj/item/seeds/reishi,
+ /obj/item/seeds/banana,
+ /obj/item/seeds/eggplant/eggy,
+ /obj/item/seeds/random,
+ /obj/item/seeds/random)
+ crate_name = "exotic seeds crate"
+ crate_type = /obj/structure/closet/crate/hydroponics
diff --git a/code/modules/cargo/packs/science.dm b/code/modules/cargo/packs/science.dm
new file mode 100644
index 0000000000..ace64b21fb
--- /dev/null
+++ b/code/modules/cargo/packs/science.dm
@@ -0,0 +1,216 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Science /////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/science
+ group = "Science"
+ crate_type = /obj/structure/closet/crate/science
+
+/* For later
+/datum/supply_pack/science/monkey
+ name = "Ape Cube Crate"
+ desc = "Pss what a new test subject with supper strangth, speed, and love for bananas all at the same time? Say no more... Contains a single ape cube. Dont add water!"
+ contraband = TRUE
+ cost = 2500
+ contains = list (/obj/item/reagent_containers/food/snacks/monkeycube/ape)
+ crate_name = "ape cube crate"
+*/
+
+/datum/supply_pack/science/aliens
+ name = "Advanced Alien Alloy Crate Crate"
+ desc = "Hello brothers from the stars!!! Our fellow brethren have made contact at long last and gave us gifts man! They really did build the prymi- Connection Error- Bro we’ll send you a sheet of advanced alien alloy."
+ cost = 15000
+ contraband = TRUE
+ DropPodOnly = TRUE
+ contains = list(/obj/item/stack/sheet/mineral/abductor)
+ crate_name = "alien bro alloy crate"
+
+/datum/supply_pack/science/beakers
+ name = "Chemistry Beackers Crate"
+ desc = "Glassware for any chemistry lab! Contains four small beakers, three large, two plastic, and one metamaterial. As well as three droppers and two pairs of latex gloves."
+ cost = 1500
+ contains = list(/obj/item/reagent_containers/glass/beaker,
+ /obj/item/reagent_containers/glass/beaker,
+ /obj/item/reagent_containers/glass/beaker,
+ /obj/item/reagent_containers/glass/beaker,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/reagent_containers/glass/beaker/large,
+ /obj/item/reagent_containers/glass/beaker/plastic,
+ /obj/item/reagent_containers/glass/beaker/plastic,
+ /obj/item/reagent_containers/glass/beaker/meta,
+ /obj/item/reagent_containers/glass/beaker/noreact,
+ /obj/item/reagent_containers/dropper,
+ /obj/item/reagent_containers/dropper,
+ /obj/item/reagent_containers/dropper,
+ /obj/item/clothing/gloves/color/latex,
+ /obj/item/clothing/gloves/color/latex)
+ crate_name = "chemistry beaker crate"
+
+/datum/supply_pack/science/robotics/mecha_odysseus
+ name = "Circuit Crate (Odysseus)"
+ desc = "Ever wanted to build your own giant medical robot? Well, now you can! Contains the Odysseus main control board and Odysseus peripherals board. Requires Robotics access to open."
+ cost = 2500
+ access = ACCESS_ROBOTICS
+ contains = list(/obj/item/circuitboard/mecha/odysseus/peripherals,
+ /obj/item/circuitboard/mecha/odysseus/main)
+ crate_name = "\improper Odysseus circuit crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/robotics/mecha_ripley
+ name = "Circuit Crate (Ripley APLU)"
+ desc = "Rip apart rocks and xenomorphs alike with the Ripley APLU. Contains the Main Ripley control board, as well as the Ripley Peripherals board. Requires Robotics access to open."
+ cost = 3000
+ access = ACCESS_ROBOTICS
+ contains = list(/obj/item/book/manual/ripley_build_and_repair,
+ /obj/item/circuitboard/mecha/ripley/main,
+ /obj/item/circuitboard/mecha/ripley/peripherals)
+ crate_name = "\improper APLU Ripley circuit crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/circuitry
+ name = "Circuitry Starter Pack Crate"
+ desc = "Journey into the mysterious world of Circuitry with this starter pack. Contains a circuit printer, analyzer, debugger and wirer. Power cells not included."
+ cost = 1000
+ contains = list(/obj/item/integrated_electronics/analyzer,
+ /obj/item/integrated_circuit_printer,
+ /obj/item/integrated_electronics/debugger,
+ /obj/item/integrated_electronics/wirer)
+ crate_name = "circuitry starter pack crate"
+
+/datum/supply_pack/science/monkey
+ name = "Monkey Cube Crate"
+ desc = "Stop monkeying around! Contains seven monkey cubes. Just add water!"
+ cost = 2000
+ contains = list (/obj/item/storage/box/monkeycubes)
+ crate_name = "monkey cube crate"
+
+/datum/supply_pack/science/nitrilegloves
+ name = "Nitrile Gloves Crate"
+ desc = "Handling toxic chemicals? Well worry not, keep your flesh intact with some nitrile made gloves! Contains three pairs of nitrile gloves."
+ cost = 1500
+ contains = list(/obj/item/clothing/gloves/color/latex/nitrile,
+ /obj/item/clothing/gloves/color/latex/nitrile,
+ /obj/item/clothing/gloves/color/latex/nitrile)
+ crate_name = "nitrile gloves crate"
+
+/datum/supply_pack/science/nuke_b_gone
+ name = "Nuke Defusal Kit"
+ desc = "Contains set of tools to defuse a nuke."
+ cost = 7500 //Usefull for traitors/nukies that fucked up
+ dangerous = TRUE
+ DropPodOnly = TRUE
+ contains = list(/obj/item/nuke_core_container/nt,
+ /obj/item/screwdriver/nuke/nt,
+ /obj/item/paper/guides/nt/nuke_instructions)
+ crate_name = "safe defusal kit storage"
+
+/datum/supply_pack/science/plasma
+ name = "Plasma Assembly Crate"
+ desc = "Everything you need to burn something to the ground, this contains three plasma assembly sets. Each set contains a plasma tank, igniter, proximity sensor, and timer! Warranty void if exposed to high temperatures. Requires Toxins access to open."
+ cost = 1800
+ access = ACCESS_TOX_STORAGE
+ contains = list(/obj/item/tank/internals/plasma,
+ /obj/item/tank/internals/plasma,
+ /obj/item/tank/internals/plasma,
+ /obj/item/assembly/igniter,
+ /obj/item/assembly/igniter,
+ /obj/item/assembly/igniter,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/assembly/timer,
+ /obj/item/assembly/timer,
+ /obj/item/assembly/timer)
+ crate_name = "plasma assembly crate"
+ crate_type = /obj/structure/closet/crate/secure/plasma
+
+/datum/supply_pack/science/relic
+ name = "Relic Crate"
+ desc = "Ever want to play with old discounted toys? Look no more. Contains two relics."
+ cost = 1000
+ contraband = TRUE
+ contains = list(/obj/item/relic,
+ /obj/item/relic)
+ crate_name = "relic crate"
+
+/datum/supply_pack/science/robotics
+ name = "Robotics Assembly Crate"
+ desc = "The tools you need to replace those finicky humans with a loyal robot army! Contains three proximity sensors, two high-powered cells, six flashes, and an electrical toolbox. Requires Robotics access to open."
+ cost = 1500
+ access = ACCESS_ROBOTICS
+ contains = list(/obj/item/assembly/prox_sensor,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/assembly/prox_sensor,
+ /obj/item/storage/toolbox/electrical,
+ /obj/item/storage/box/flashes,
+ /obj/item/stock_parts/cell/high,
+ /obj/item/stock_parts/cell/high)
+ crate_name = "robotics assembly crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/shieldwalls
+ name = "Shield Generator Crate"
+ desc = "These high powered Shield Wall Generators are guaranteed to keep any unwanted lifeforms on the outside, where they belong! Contains four shield wall generators. Requires Teleporter access to open."
+ cost = 2000
+ access = ACCESS_TELEPORTER
+ contains = list(/obj/machinery/shieldwallgen,
+ /obj/machinery/shieldwallgen,
+ /obj/machinery/shieldwallgen,
+ /obj/machinery/shieldwallgen)
+ crate_name = "shield generators crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/slime
+ name = "Slime Core Crate"
+ desc = "Ran out of slimes? No problem, contains one gray slime core. Requires Xenobio access to open."
+ cost = 1000
+ access = ACCESS_XENOBIOLOGY
+ contains = list(/obj/item/slime_extract/grey)
+ crate_name = "slime core crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+
+/datum/supply_pack/science/supermater
+ name = "Supermatter Extraction Tools Crate"
+ desc = "Contains a set of tools to extract a sliver of supermatter. Consult your CE today!"
+ cost = 7500 //Usefull for traitors that fucked up
+ hidden = TRUE
+ contains = list(/obj/item/nuke_core_container/supermatter,
+ /obj/item/scalpel/supermatter,
+ /obj/item/hemostat/supermatter,
+ /obj/item/paper/guides/antag/supermatter_sliver)
+ crate_name = "supermatter extraction kit crate"
+
+/datum/supply_pack/science/tablets
+ name = "Tablet Crate"
+ desc = "What's a computer? Contains five cargo tablets."
+ cost = 3000
+ contains = list(/obj/item/modular_computer/tablet/preset/cargo,
+ /obj/item/modular_computer/tablet/preset/cargo,
+ /obj/item/modular_computer/tablet/preset/cargo,
+ /obj/item/modular_computer/tablet/preset/cargo,
+ /obj/item/modular_computer/tablet/preset/cargo)
+ crate_name = "tablet crate"
+
+/datum/supply_pack/science/transfer_valves
+ name = "Tank Transfer Valves Crate"
+ desc = "The key ingredient for making a lot of people very angry very fast. Contains two tank transfer valves. Requires RD access to open."
+ cost = 6000
+ access = ACCESS_RD
+ contains = list(/obj/item/transfer_valve,
+ /obj/item/transfer_valve)
+ crate_name = "tank transfer valves crate"
+ crate_type = /obj/structure/closet/crate/secure/science
+ dangerous = TRUE
+
+/datum/supply_pack/science/tech_slugs
+ name = "Tech Slug Ammo Shells"
+ desc = "A new type of shell that is able to be made into a few different dangerous types. Contains two boxes of tech slugs, 14 shells in all."
+ cost = 1700
+ contains = list(/obj/item/storage/box/techsslug,
+ /obj/item/storage/box/techsslug)
+ crate_name = "tech slug crate"
diff --git a/code/modules/cargo/packs/security.dm b/code/modules/cargo/packs/security.dm
new file mode 100644
index 0000000000..3c68fe7f6d
--- /dev/null
+++ b/code/modules/cargo/packs/security.dm
@@ -0,0 +1,192 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Security ////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/security
+ group = "Security"
+ access = ACCESS_SECURITY
+ crate_type = /obj/structure/closet/crate/secure/gear
+
+/datum/supply_pack/security/armor
+ name = "Armor Crate"
+ desc = "Three vests of well-rounded, decently-protective armor. Requires Security access to open."
+ cost = 1200
+ contains = list(/obj/item/clothing/suit/armor/vest,
+ /obj/item/clothing/suit/armor/vest,
+ /obj/item/clothing/suit/armor/vest)
+ crate_name = "armor crate"
+
+/datum/supply_pack/security/disabler
+ name = "Disabler Crate"
+ desc = "Three stamina-draining disabler weapons. Requires Security access to open."
+ cost = 1300
+ contains = list(/obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/disabler,
+ /obj/item/gun/energy/disabler)
+ crate_name = "disabler crate"
+
+/datum/supply_pack/security/forensics
+ name = "Forensics Crate"
+ desc = "Stay hot on the criminal's heels with Nanotrasen's Detective Essentials(tm). Contains a forensics scanner, six evidence bags, camera, tape recorder, white crayon, and of course, a fedora. Requires Security access to open."
+ cost = 1800
+ contains = list(/obj/item/detective_scanner,
+ /obj/item/storage/box/evidence,
+ /obj/item/camera,
+ /obj/item/taperecorder,
+ /obj/item/toy/crayon/white,
+ /obj/item/clothing/head/fedora/det_hat)
+ crate_name = "forensics crate"
+
+/datum/supply_pack/security/helmets
+ name = "Helmets Crate"
+ desc = "Contains three standard-issue brain buckets. Requires Security access to open."
+ cost = 1200
+ contains = list(/obj/item/clothing/head/helmet/sec,
+ /obj/item/clothing/head/helmet/sec,
+ /obj/item/clothing/head/helmet/sec)
+ crate_name = "helmet crate"
+
+/datum/supply_pack/security/laser
+ name = "Lasers Crate"
+ desc = "Contains three lethal, high-energy laser guns. Requires Security access to open."
+ cost = 1750
+ contains = list(/obj/item/gun/energy/laser,
+ /obj/item/gun/energy/laser,
+ /obj/item/gun/energy/laser)
+ crate_name = "laser crate"
+
+/datum/supply_pack/security/russianclothing
+ name = "Russian Surplus Clothing"
+ desc = "An old russian crate full of surplus armor that they used to use! Has two sets of bulletproff armor, a few union suits and some warm hats!"
+ contraband = TRUE
+ cost = 5750 // Its basicly sec suits, good boots/gloves
+ contains = list(/obj/item/clothing/suit/security/officer/russian,
+ /obj/item/clothing/suit/security/officer/russian,
+ /obj/item/clothing/shoes/combat,
+ /obj/item/clothing/shoes/combat,
+ /obj/item/clothing/head/ushanka,
+ /obj/item/clothing/head/ushanka,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/gloves/combat,
+ /obj/item/clothing/gloves/combat,
+ /obj/item/clothing/mask/gas,
+ /obj/item/clothing/mask/gas)
+ crate_name = "surplus russian clothing"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/security/russianmosin
+ name = "Russian Minutemen Gear"
+ desc = "An old russian Minutemen crate, comes with a full russian outfit, a mosin and a stripper clip."
+ contraband = TRUE
+ access = FALSE
+ cost = 5500 //
+ contains = list(/obj/item/clothing/suit/security/officer/russian,
+ /obj/item/clothing/shoes/combat,
+ /obj/item/clothing/head/ushanka,
+ /obj/item/clothing/suit/armor/bulletproof,
+ /obj/item/clothing/head/helmet/alt,
+ /obj/item/clothing/gloves/combat,
+ /obj/item/clothing/mask/gas,
+ /obj/item/gun/ballistic/shotgun/boltaction,
+ /obj/item/ammo_box/a762)
+ crate_name = "surplus russian gear"
+ crate_type = /obj/structure/closet/crate/internals
+
+/datum/supply_pack/security/sechardsuit
+ name = "Sec Hardsuit"
+ desc = "One Sec Hardsuit with a small air tank and mask."
+ cost = 3000 // half of SWAT gear for have the armor and half the gear
+ contains = list(/obj/item/clothing/suit/space/hardsuit/security,
+ /obj/item/tank/internals/air,
+ /obj/item/clothing/mask/gas)
+ crate_name = "sec hardsuit crate"
+
+/datum/supply_pack/security/securitybarriers
+ name = "Security Barrier Grenades"
+ desc = "Stem the tide with four Security Barrier grenades. Requires Security access to open."
+ contains = list(/obj/item/grenade/barrier,
+ /obj/item/grenade/barrier,
+ /obj/item/grenade/barrier,
+ /obj/item/grenade/barrier)
+ cost = 2000
+ crate_name = "security barriers crate"
+
+/datum/supply_pack/security/securityclothes
+ name = "Security Clothing Crate"
+ desc = "Contains appropriate outfits for the station's private security force. Contains outfits for the Warden, Head of Security, and two Security Officers. Each outfit comes with a rank-appropriate jumpsuit, suit, and beret. Requires Security access to open."
+ cost = 3250
+ contains = list(/obj/item/clothing/under/rank/security/navyblue,
+ /obj/item/clothing/under/rank/security/navyblue,
+ /obj/item/clothing/suit/security/officer,
+ /obj/item/clothing/suit/security/officer,
+ /obj/item/clothing/head/beret/sec/navyofficer,
+ /obj/item/clothing/head/beret/sec/navyofficer,
+ /obj/item/clothing/under/rank/warden/navyblue,
+ /obj/item/clothing/suit/security/warden,
+ /obj/item/clothing/head/beret/sec/navywarden,
+ /obj/item/clothing/under/rank/head_of_security/navyblue,
+ /obj/item/clothing/suit/security/hos,
+ /obj/item/clothing/head/beret/sec/navyhos)
+ crate_name = "security clothing crate"
+
+/datum/supply_pack/security/supplies
+ name = "Security Supplies Crate"
+ desc = "Contains seven flashbangs, seven teargas grenades, six flashes, and seven handcuffs. Requires Security access to open."
+ cost = 1200
+ contains = list(/obj/item/storage/box/flashbangs,
+ /obj/item/storage/box/teargas,
+ /obj/item/storage/box/flashes,
+ /obj/item/storage/box/handcuffs)
+ crate_name = "security supply crate"
+
+/datum/supply_pack/security/firingpins
+ name = "Standard Firing Pins Crate"
+ desc = "Upgrade your arsenal with 10 standard firing pins. Requires Security access to open."
+ cost = 2000
+ contains = list(/obj/item/storage/box/firingpins,
+ /obj/item/storage/box/firingpins)
+ crate_name = "firing pins crate"
+
+/datum/supply_pack/security/justiceinbound
+ name = "Standard Justice Enforcer Crate"
+ desc = "This is it. The Bee's Knees. The Creme of the Crop. The Pick of the Litter. The best of the best of the best. The Crown Jewel of Nanotrasen. The Alpha and the Omega of security headwear. Guaranteed to strike fear into the hearts of each and every criminal aboard the station. Also comes with a security gasmask. Requires Security access to open."
+ cost = 6000 //justice comes at a price. An expensive, noisy price.
+ contraband = TRUE
+ contains = list(/obj/item/clothing/head/helmet/justice,
+ /obj/item/clothing/mask/gas/sechailer)
+ crate_name = "security clothing crate"
+
+/datum/supply_pack/security/baton
+ name = "Stun Batons Crate"
+ desc = "Arm the Civil Protection Forces with three stun batons. Batteries included. Requires Security access to open."
+ cost = 1200
+ contains = list(/obj/item/melee/baton/loaded,
+ /obj/item/melee/baton/loaded,
+ /obj/item/melee/baton/loaded)
+ crate_name = "stun baton crate"
+
+/datum/supply_pack/security/taser
+ name = "Taser Crate"
+ desc = "From the depths of stunbased combat, this order rises above, supreme. Contains three hybrid tasers, capable of firing both electrodes and disabling shots. Requires Security access to open."
+ cost = 3500
+ contains = list(/obj/item/gun/energy/e_gun/advtaser,
+ /obj/item/gun/energy/e_gun/advtaser,
+ /obj/item/gun/energy/e_gun/advtaser)
+ crate_name = "taser crate"
+
+/datum/supply_pack/security/wall_flash
+ name = "Wall-Mounted Flash Crate"
+ desc = "Contains four wall-mounted flashes. Requires Security access to open."
+ cost = 1000
+ contains = list(/obj/item/storage/box/wall_flash,
+ /obj/item/storage/box/wall_flash,
+ /obj/item/storage/box/wall_flash,
+ /obj/item/storage/box/wall_flash)
+ crate_name = "wall-mounted flash crate"
diff --git a/code/modules/cargo/packs/service.dm b/code/modules/cargo/packs/service.dm
new file mode 100644
index 0000000000..14bde519e1
--- /dev/null
+++ b/code/modules/cargo/packs/service.dm
@@ -0,0 +1,266 @@
+
+//Reminders-
+// If you add something to this list, please group it by type and sort it alphabetically instead of just jamming it in like an animal
+// cost = 700- Minimum cost, or infinite points are possible.
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////////// Service //////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/service
+ group = "Service"
+
+/datum/supply_pack/service/advlighting
+ name = "Advanced Lighting crate"
+ desc = "Thanks to advanced lighting tech we here at the Lamp Factory have be able to produce more lamps and lamp items! This crate has three lamps, a box of lights and a state of the art rapid-light-device!"
+ cost = 2750
+ contains = list(/obj/item/construction/rld,
+ /obj/item/flashlight/lamp,
+ /obj/item/flashlight/lamp,
+ /obj/item/flashlight/lamp/green,
+ /obj/item/storage/box/lights/mixed)
+ crate_name = "advanced lighting crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/service/cargo_supples
+ name = "Cargo Supplies Crate"
+ desc = "Sold everything that wasn't bolted down? You can get right back to work with this crate containing stamps, an export scanner, destination tagger, hand labeler and some package wrapping."
+ cost = 1000
+ contains = list(/obj/item/stamp,
+ /obj/item/stamp/denied,
+ /obj/item/export_scanner,
+ /obj/item/destTagger,
+ /obj/item/hand_labeler,
+ /obj/item/stack/packageWrap)
+ crate_name = "cargo supplies crate"
+
+/datum/supply_pack/service/carpet_exotic
+ name = "Exotic Carpet Crate"
+ desc = "Exotic carpets straight from Space Russia, for all your decorating needs. Contains 100 tiles each of 10 different flooring patterns."
+ cost = 7000
+ contains = list(/obj/item/stack/tile/carpet/blue/fifty,
+ /obj/item/stack/tile/carpet/blue/fifty,
+ /obj/item/stack/tile/carpet/cyan/fifty,
+ /obj/item/stack/tile/carpet/cyan/fifty,
+ /obj/item/stack/tile/carpet/green/fifty,
+ /obj/item/stack/tile/carpet/green/fifty,
+ /obj/item/stack/tile/carpet/orange/fifty,
+ /obj/item/stack/tile/carpet/orange/fifty,
+ /obj/item/stack/tile/carpet/purple/fifty,
+ /obj/item/stack/tile/carpet/purple/fifty,
+ /obj/item/stack/tile/carpet/red/fifty,
+ /obj/item/stack/tile/carpet/red/fifty,
+ /obj/item/stack/tile/carpet/royalblue/fifty,
+ /obj/item/stack/tile/carpet/royalblue/fifty,
+ /obj/item/stack/tile/carpet/royalblack/fifty,
+ /obj/item/stack/tile/carpet/royalblack/fifty,
+ /obj/item/stack/tile/carpet/blackred/fifty,
+ /obj/item/stack/tile/carpet/blackred/fifty,
+ /obj/item/stack/tile/carpet/monochrome/fifty,
+ /obj/item/stack/tile/carpet/monochrome/fifty)
+ crate_name = "exotic carpet crate"
+
+/datum/supply_pack/service/food_cart
+ name = "Food Cart Crate"
+ desc = "Want to sell food on the go? Cook lost their cart? Well we just so happen to have a few carts to spare!"
+ cost = 1000
+ contains = list(/obj/machinery/food_cart)
+ crate_name = "food cart crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/noslipfloor
+ name = "High-traction Floor Tiles"
+ desc = "Make slipping a thing of the past with sixty industrial-grade anti-slip floortiles!"
+ cost = 2000
+ contains = list(/obj/item/stack/tile/noslip/thirty,
+ /obj/item/stack/tile/noslip/thirty)
+ crate_name = "high-traction floor tiles crate"
+
+/datum/supply_pack/service/icecream_cart
+ name = "Ice Cream Cart Crate"
+ desc = "Plasma fire a to hot for you, want a nice treat after a hard days work? Well now we have the cart for you! This Ice Cream Vat has everthing you need to make you and your friends so ice cream treats! This cart comes stocked with some ingredients for each type of scoopable icecream."
+ cost = 2750 //Comes prestocked with basic ingredients
+ contains = list(/obj/machinery/icecream_vat)
+ crate_name = "ice cream vat crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/janitor
+ name = "Janitorial Supplies Crate"
+ desc = "Fight back against dirt and grime with Nanotrasen's Janitorial Essentials(tm)! Contains three buckets, caution signs, and cleaner grenades. Also has a single mop, spray cleaner, rag, NT soap and a trash bag."
+ cost = 1300
+ contains = list(/obj/item/reagent_containers/glass/bucket,
+ /obj/item/reagent_containers/glass/bucket,
+ /obj/item/reagent_containers/glass/bucket,
+ /obj/item/mop,
+ /obj/item/caution,
+ /obj/item/caution,
+ /obj/item/caution,
+ /obj/item/storage/bag/trash,
+ /obj/item/reagent_containers/spray/cleaner,
+ /obj/item/reagent_containers/rag,
+ /obj/item/grenade/chem_grenade/cleaner,
+ /obj/item/grenade/chem_grenade/cleaner,
+ /obj/item/grenade/chem_grenade/cleaner,
+ /obj/item/soap/nanotrasen)
+ crate_name = "janitorial supplies crate"
+
+/datum/supply_pack/service/janitor/janicart
+ name = "Janitorial Cart and Galoshes Crate"
+ desc = "The keystone to any successful janitor. As long as you have feet, this pair of galoshes will keep them firmly planted on the ground. Also contains a janitorial cart."
+ cost = 2000
+ contains = list(/obj/structure/janitorialcart,
+ /obj/item/clothing/shoes/galoshes)
+ crate_name = "janitorial cart crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/service/janitor/janitank
+ name = "Janitor Backpack Crate"
+ desc = "Call forth divine judgement upon dirt and grime with this high capacity janitor backpack. Contains 500 units of station-cleansing cleaner. Requires janitor access to open."
+ cost = 1000
+ access = ACCESS_JANITOR
+ contains = list(/obj/item/watertank/janitor)
+ crate_name = "janitor backpack crate"
+ crate_type = /obj/structure/closet/crate/secure
+
+/datum/supply_pack/service/janitor/janpremium
+ name = "Janitor Premium Supplies"
+ desc = "Do to the union for better supplies, we have desided to make a deal for you, In this crate you can get a brand new chem, Drying Angent this stuff is the work of slimes or magic! This crate also contains a rag to test out the Drying Angent magic, three wet floor signs, and some spare bottles of ammonia."
+ cost = 1750
+ access = ACCESS_JANITOR
+ contains = list(/obj/item/caution,
+ /obj/item/caution,
+ /obj/item/caution,
+ /obj/item/reagent_containers/rag,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/reagent_containers/glass/bottle/ammonia,
+ /obj/item/reagent_containers/spray/drying_agent)
+ crate_name = "janitor backpack crate"
+
+/datum/supply_pack/service/janitor/janpimp
+ name = "Custodial Cruiser"
+ desc = "Clown steal your ride? Assistant lock it in the dorms? Order a new one and get back to cleaning in style!"
+ cost = 3000
+ access = ACCESS_JANITOR
+ contains = list(/obj/vehicle/ridden/janicart,
+ /obj/item/key/janitor)
+ crate_name = "janitor ride crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/service/mule
+ name = "MULEbot Crate"
+ desc = "Pink-haired Quartermaster not doing her job? Replace her with this tireless worker, today!"
+ cost = 2000
+ contains = list(/mob/living/simple_animal/bot/mulebot)
+ crate_name = "\improper MULEbot Crate"
+ crate_type = /obj/structure/closet/crate/large
+
+/datum/supply_pack/service/party
+ name = "Party Equipment"
+ desc = "Celebrate both life and death on the station with Nanotrasen's Party Essentials(tm)! Contains seven colored glowsticks, four beers, two ales, and a bottle of patron, goldschlager, and shaker!"
+ cost = 2000
+ contains = list(/obj/item/storage/box/drinkingglasses,
+ /obj/item/reagent_containers/food/drinks/shaker,
+ /obj/item/reagent_containers/food/drinks/bottle/patron,
+ /obj/item/reagent_containers/food/drinks/bottle/goldschlager,
+ /obj/item/reagent_containers/food/drinks/ale,
+ /obj/item/reagent_containers/food/drinks/ale,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/reagent_containers/food/drinks/beer,
+ /obj/item/flashlight/glowstick,
+ /obj/item/flashlight/glowstick/red,
+ /obj/item/flashlight/glowstick/blue,
+ /obj/item/flashlight/glowstick/cyan,
+ /obj/item/flashlight/glowstick/orange,
+ /obj/item/flashlight/glowstick/yellow,
+ /obj/item/flashlight/glowstick/pink)
+ crate_name = "party equipment crate"
+
+/datum/supply_pack/service/carpet
+ name = "Premium Carpet Crate"
+ desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains the classics."
+ cost = 1000
+ contains = list(/obj/item/stack/tile/carpet/fifty,
+ /obj/item/stack/tile/carpet/fifty,
+ /obj/item/stack/tile/carpet/black/fifty,
+ /obj/item/stack/tile/carpet/black/fifty)
+ crate_name = "premium carpet crate"
+
+/datum/supply_pack/service/carpet2
+ name = "Premium Carpet Crate #2"
+ desc = "Plasteel floor tiles getting on your nerves? These stacks of extra soft carpet will tie any room together. Contains red, and monochrome"
+ cost = 1000
+ contains = list(/obj/item/stack/tile/carpet/blackred/fifty,
+ /obj/item/stack/tile/carpet/blackred/fifty,
+ /obj/item/stack/tile/carpet/monochrome/fifty,
+ /obj/item/stack/tile/carpet/monochrome/fifty)
+ crate_name = "premium carpet crate #2"
+
+/datum/supply_pack/service/lightbulbs
+ name = "Replacement Lights"
+ desc = "May the light of Aether shine upon this station! Or at least, the light of forty two light tubes and twenty one light bulbs as well as a light replacer."
+ cost = 1200
+ contains = list(/obj/item/storage/box/lights/mixed,
+ /obj/item/storage/box/lights/mixed,
+ /obj/item/storage/box/lights/mixed,
+ /obj/item/lightreplacer)
+ crate_name = "replacement lights"
+
+/datum/supply_pack/service/minerkit
+ name = "Shaft Miner Starter Kit"
+ desc = "All the miners died too fast? Assistant wants to get a taste of life off-station? Either way, this kit is the best way to turn a regular crewman into an ore-producing, monster-slaying machine. Contains meson goggles, a pickaxe, advanced mining scanner, cargo headset, ore bag, gasmask, and explorer suit. Requires QM access to open."
+ cost = 2500
+ access = ACCESS_QM
+ contains = list(/obj/item/pickaxe/mini,
+ /obj/item/clothing/glasses/meson,
+ /obj/item/t_scanner/adv_mining_scanner/lesser,
+ /obj/item/radio/headset/headset_cargo/mining,
+ /obj/item/storage/bag/ore,
+ /obj/item/clothing/suit/hooded/explorer/standard,
+ /obj/item/clothing/mask/gas/explorer)
+ crate_name = "shaft miner starter kit"
+ crate_type = /obj/structure/closet/crate/secure
+
+//////////////////////////////////////////////////////////////////////////////
+/////////////////////////// Vending Restocks /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+
+/datum/supply_pack/service/vending/bartending
+ name = "Bartending Supply Crate"
+ desc = "Bring on the booze with vending machine refills, as well as a free book containing the well-kept secrets to the bartending trade!"
+ cost = 2000
+ contains = list(/obj/item/vending_refill/boozeomat,
+ /obj/item/vending_refill/coffee,
+ /obj/item/book/granter/action/drink_fling)
+ crate_name = "bartending supply crate"
+
+/datum/supply_pack/service/vending/cigarette
+ name = "Cigarette Supply Crate"
+ desc = "Don't believe the reports - smoke today! Contains a cigarette vending machine refill."
+ cost = 1500
+ contains = list(/obj/item/vending_refill/cigarette)
+ crate_name = "cigarette supply crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/vending/games
+ name = "Games Supply Crate"
+ desc = "Get your game on with this game vending machine refill."
+ cost = 1000
+ contains = list(/obj/item/vending_refill/games)
+ crate_name = "games supply crate"
+ crate_type = /obj/structure/closet/crate
+
+/datum/supply_pack/service/vending/snack
+ name = "Snack Supply Crate"
+ desc = "One vending machine refill of cavity-bringin' goodness! The number one dentist recommended order!"
+ cost = 1500
+ contains = list(/obj/item/vending_refill/snack)
+ crate_name = "snacks supply crate"
+
+/datum/supply_pack/service/vending/cola
+ name = "Softdrinks Supply Crate"
+ desc = "Got whacked by a toolbox, but you still have those pesky teeth? Get rid of those pearly whites with this soda machine refill, today!"
+ cost = 1500
+ contains = list(/obj/item/vending_refill/cola)
+ crate_name = "soft drinks supply crate"
diff --git a/code/modules/client/asset_cache.dm b/code/modules/client/asset_cache.dm
index 5402353fd4..643d072469 100644
--- a/code/modules/client/asset_cache.dm
+++ b/code/modules/client/asset_cache.dm
@@ -571,6 +571,8 @@ GLOBAL_LIST_EMPTY(asset_datums)
"fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff',
"font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css',
"browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
+ "browserOutput_dark.css" = 'code/modules/goonchat/browserassets/css/browserOutput_dark.css',
+ "browserOutput_light.css" = 'code/modules/goonchat/browserassets/css/browserOutput_light.css'
)
/datum/asset/spritesheet/goonchat
diff --git a/code/modules/client/darkmode.dm b/code/modules/client/darkmode.dm
index 9e8d136b3b..f806e5c964 100644
--- a/code/modules/client/darkmode.dm
+++ b/code/modules/client/darkmode.dm
@@ -5,7 +5,7 @@ This lets you switch chat themes by using winset and CSS loading, you must relog
Things to note:
If you change ANYTHING in interface/skin.dmf you need to change it here:
Format:
-winset(src, "window as appears in skin.dmf after elem", "var to change = currentvalue;var to change = desired value")
+winset(src, "window as appears in skin.dmf after elem", "var to change = desired value")
How this works:
I've added a function to browseroutput.js which registers a cookie for darkmode and swaps the chat accordingly. You can find the button to do this under the "cog" icon next to the ping button (top right of chat)
This then swaps the window theme automatically
@@ -14,104 +14,52 @@ Thanks to spacemaniac and mcdonald for help with the JS side of this.
/client/proc/force_white_theme() //There's no way round it. We're essentially changing the skin by hand. It's painful but it works, and is the way Lummox suggested.
//Main windows
- winset(src, "infowindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
- winset(src, "infowindow", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "info", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]")
- winset(src, "info", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "browseroutput", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]")
- winset(src, "browseroutput", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "outputwindow", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
- winset(src, "outputwindow", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "mainwindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
- winset(src, "split", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]")
+ winset(src, "infowindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "info", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "browseroutput", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "outputwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "mainwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
+ winset(src, "split", "background-color = [COLOR_WHITEMODE_BACKGROUND]")
//Buttons
- winset(src, "changelog", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]")
- winset(src, "changelog", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "rules", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]")
- winset(src, "rules", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "wiki", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]")
- winset(src, "wiki", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "forum", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]")
- winset(src, "forum", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "github", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG]")
- winset(src, "github", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "report-issue", "background-color = [COLOR_DARKMODE_ISSUE_BUTTON_BG];background-color = [COLOR_WHITEMODE_ISSUE_BUTTON_BG]")
- winset(src, "report-issue", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "changelog", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "rules", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "wiki", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "forum", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "github", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "report-issue", "background-color = [COLOR_WHITEMODE_ISSUE_BUTTON_BG];text-color = [COLOR_WHITEMODE_TEXT]")
//Status and verb tabs
- winset(src, "output", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]")
- winset(src, "output", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "statwindow", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
- winset(src, "statwindow", "text-color = #eaeaea;text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "stat", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]")
- winset(src, "stat", "tab-background-color = [COLOR_DARKMODE_BACKGROUND];tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
- winset(src, "stat", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "stat", "tab-text-color = [COLOR_DARKMODE_TEXT];tab-text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "stat", "prefix-color = [COLOR_DARKMODE_TEXT];prefix-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "stat", "suffix-color = [COLOR_DARKMODE_TEXT];suffix-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "output", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "statwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "stat", "background-color = [COLOR_WHITEMODE_BACKGROUND];tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND];\
+ text-color = [COLOR_WHITEMODE_TEXT];tab-text-color = [COLOR_WHITEMODE_TEXT];\
+ prefix-color = [COLOR_WHITEMODE_TEXT];suffix-color = [COLOR_WHITEMODE_TEXT]")
//Etc.
- winset(src, "say", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
- winset(src, "say", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "asset_cache_browser", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_DARKBACKGROUND]")
- winset(src, "asset_cache_browser", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
- winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];background-color = [COLOR_WHITEMODE_BACKGROUND]")
- winset(src, "tooltip", "text-color = [COLOR_DARKMODE_TEXT];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "say", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "asset_cache_browser", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
+ winset(src, "tooltip", "background-color = [COLOR_WHITEMODE_BACKGROUND];text-color = [COLOR_WHITEMODE_TEXT]")
/client/proc/force_dark_theme() //Inversely, if theyre using white theme and want to swap to the superior dark theme, let's get WINSET() ing
//Main windows
- winset(src, "infowindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_DARKBACKGROUND]")
- winset(src, "infowindow", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "info", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]")
- winset(src, "info", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "browseroutput", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]")
- winset(src, "browseroutput", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "outputwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]")
- winset(src, "outputwindow", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "mainwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_DARKBACKGROUND]")
- winset(src, "split", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]")
+ winset(src, "infowindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "info", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "browseroutput", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "outputwindow", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "mainwindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND]")
+ winset(src, "split", "background-color = [COLOR_DARKMODE_BACKGROUND]")
//Buttons
- winset(src, "changelog", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]")
- winset(src, "changelog", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "rules", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]")
- winset(src, "rules", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "wiki", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]")
- winset(src, "wiki", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "forum", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]")
- winset(src, "forum", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "github", "background-color = [COLOR_WHITEMODE_INFO_BUTTONS_BG];background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG]")
- winset(src, "github", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "report-issue", "background-color = [COLOR_WHITEMODE_ISSUE_BUTTON_BG];background-color = [COLOR_DARKMODE_ISSUE_BUTTON_BG]")
- winset(src, "report-issue", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "changelog", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "rules", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "wiki", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "forum", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "github", "background-color = [COLOR_DARKMODE_INFO_BUTTONS_BG];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "report-issue", "background-color = [COLOR_DARKMODE_ISSUE_BUTTON_BG];text-color = [COLOR_DARKMODE_TEXT]")
//Status and verb tabs
- winset(src, "output", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]")
- winset(src, "output", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "statwindow", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_DARKBACKGROUND]")
- winset(src, "statwindow", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "stat", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_DARKBACKGROUND]")
- winset(src, "stat", "tab-background-color = [COLOR_WHITEMODE_DARKBACKGROUND];tab-background-color = [COLOR_DARKMODE_BACKGROUND]")
- winset(src, "stat", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "stat", "tab-text-color = [COLOR_WHITEMODE_TEXT];tab-text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "stat", "prefix-color = [COLOR_WHITEMODE_TEXT];prefix-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "stat", "suffix-color = [COLOR_WHITEMODE_TEXT];suffix-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "output", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "statwindow", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "stat", "background-color = [COLOR_DARKMODE_DARKBACKGROUND];tab-background-color = [COLOR_DARKMODE_BACKGROUND];\
+ text-color = [COLOR_DARKMODE_TEXT];tab-text-color = [COLOR_DARKMODE_TEXT];\
+ prefix-color = [COLOR_DARKMODE_TEXT];suffix-color = [COLOR_DARKMODE_TEXT]")
//Etc.
- winset(src, "say", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]")
- winset(src, "say", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "asset_cache_browser", "background-color = [COLOR_WHITEMODE_DARKBACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]")
- winset(src, "asset_cache_browser", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
- winset(src, "tooltip", "background-color = [COLOR_WHITEMODE_BACKGROUND];background-color = [COLOR_DARKMODE_BACKGROUND]")
- winset(src, "tooltip", "text-color = [COLOR_WHITEMODE_TEXT];text-color = [COLOR_DARKMODE_TEXT]")
-
-
-/datum/asset/simple/goonchat
- verify = FALSE
- assets = list(
- "json2.min.js" = 'code/modules/goonchat/browserassets/js/json2.min.js',
- "errorHandler.js" = 'code/modules/goonchat/browserassets/js/errorHandler.js',
- "browserOutput.js" = 'code/modules/goonchat/browserassets/js/browserOutput.js',
- "fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot',
- "fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg',
- "fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf',
- "fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff',
- "font-awesome.css" = 'code/modules/goonchat/browserassets/css/font-awesome.css',
- "browserOutput.css" = 'code/modules/goonchat/browserassets/css/browserOutput.css',
- "browserOutput_white.css" = 'code/modules/goonchat/browserassets/css/browserOutput_white.css',
- )
+ winset(src, "say", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "asset_cache_browser", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
+ winset(src, "tooltip", "background-color = [COLOR_DARKMODE_BACKGROUND];text-color = [COLOR_DARKMODE_TEXT]")
\ No newline at end of file
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index ae6de5ba05..edec4d74a6 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -86,6 +86,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/skin_tone = "caucasian1" //Skin color
var/eye_color = "000" //Eye color
var/horn_color = "85615a" //Horn color
+ var/wing_color = "fff" //Wing color
var/datum/species/pref_species = new /datum/species/human() //Mutant race
var/list/features = list("mcolor" = "FFF",
"tail_lizard" = "Smooth",
@@ -95,6 +96,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"ears" = "None",
"wings" = "None",
"frills" = "None",
+ "deco_wings" = "None",
"spines" = "None",
"body_markings" = "None",
"legs" = "Plantigrade",
@@ -111,7 +113,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
"xenohead" = "Standard",
"xenotail" = "Xenomorph Tail",
"taur" = "None",
- "exhibitionist" = FALSE,
"genitals_use_skintone" = FALSE,
"has_cock" = FALSE,
"cock_shape" = "Human",
@@ -583,6 +584,15 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(mutant_category >= MAX_MUTANT_ROWS)
dat += " "
mutant_category = 0
+ if("deco_wings" in pref_species.default_features)
+ if(!mutant_category)
+ dat += APPEARANCE_CATEGORY_COLUMN
+
+ dat += "Decorative wings "
+
+ dat += "[features["deco_wings"]] "
+ dat += " Change "
+
if("insect_wings" in pref_species.default_features)
if(!mutant_category)
dat += APPEARANCE_CATEGORY_COLUMN
@@ -590,6 +600,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Insect wings "
dat += "[features["insect_wings"]] "
+ dat += " Change "
mutant_category++
if(mutant_category >= MAX_MUTANT_ROWS)
dat += ""
@@ -814,7 +825,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat +=""
dat += "Citadel Preferences " //Because fuck me if preferences can't be fucking modularized and expected to update in a reasonable timeframe.
dat += "Arousal: [arousable == TRUE ? "Enabled" : "Disabled"] "
- dat += "Exhibitionist: [features["exhibitionist"] == TRUE ? "Yes" : "No"] "
dat += "Voracious MediHound sleepers: [(cit_toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"] "
dat += "Hear Vore Sounds: [(cit_toggles & EATING_NOISES) ? "Yes" : "No"] "
dat += "Hear Vore Digestion Sounds: [(cit_toggles & DIGESTION_NOISES) ? "Yes" : "No"] "
@@ -1681,7 +1691,10 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if("horns_color")
var/new_horn_color = input(user, "Choose your character's horn colour:", "Character Preference","#"+horn_color) as color|null
if(new_horn_color)
- horn_color = sanitize_hexcolor(new_horn_color)
+ if (new_horn_color == "#000000")
+ horn_color = "#85615A"
+ else
+ horn_color = sanitize_hexcolor(new_horn_color)
if("wings")
var/new_wings
@@ -1689,6 +1702,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_wings)
features["wings"] = new_wings
+ if("wings_color")
+ var/new_wing_color = input(user, "Choose your character's wing colour:", "Character Preference","#"+wing_color) as color|null
+ if(new_wing_color)
+ if (new_wing_color == "#000000")
+ wing_color = "#FFFFFF"
+ else
+ wing_color = sanitize_hexcolor(new_wing_color)
+
if("frills")
var/new_frills
new_frills = input(user, "Choose your character's frills:", "Character Preference") as null|anything in GLOB.frills_list
@@ -1723,6 +1744,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if(new_insect_wings)
features["insect_wings"] = new_insect_wings
+ if("deco_wings")
+ var/new_deco_wings
+ new_deco_wings = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.deco_wings_list
+ if(new_deco_wings)
+ features["deco_wings"] = new_deco_wings
+
if("insect_fluffs")
var/new_insect_fluff
new_insect_fluff = input(user, "Choose your character's wings:", "Character Preference") as null|anything in GLOB.insect_fluffs_list
@@ -2028,8 +2055,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
features["has_womb"] = FALSE
if("has_womb")
features["has_womb"] = !features["has_womb"]
- if("exhibitionist")
- features["exhibitionist"] = !features["exhibitionist"]
if("widescreenpref")
widescreenpref = !widescreenpref
user.client.change_view(CONFIG_GET(string/default_view))
@@ -2248,6 +2273,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character.hair_color = hair_color
character.facial_hair_color = facial_hair_color
character.horn_color = horn_color
+ character.wing_color = wing_color
character.skin_tone = skin_tone
character.hair_style = hair_style
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index ebd135916c..98ef2ed0e8 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
-#define SAVEFILE_VERSION_MAX 23
+#define SAVEFILE_VERSION_MAX 24
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -109,6 +109,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
else if(current_version < 23) // we are fixing a gamebreaking bug.
job_preferences = list() //It loaded null from nonexistant savefile field.
+ if(current_version < 24 && S["feature_exhibitionist"])
+ var/datum/quirk/exhibitionism/E
+ var/quirk_name = initial(E.name)
+ neutral_quirks += quirk_name
+ all_quirks += quirk_name
+
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
return
@@ -317,6 +323,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
WRITE_FILE(S["features["mcolor"]"] , "#FFF")
+ if(!S["features["horn_color"]"] || S["features["horn_color"]"] == "#000")
+ WRITE_FILE(S["features["horn_color"]"] , "#85615a")
+
+ if(!S["features["wing_color"]"] || S["features["wing_color"]"] == "#000")
+ WRITE_FILE(S["features["wing_color"]"] , "#FFF")
+
//Character
S["real_name"] >> real_name
S["nameless"] >> nameless
@@ -338,6 +350,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["socks"] >> socks
S["socks_color"] >> socks_color
S["horn_color"] >> horn_color
+ S["wing_color"] >> wing_color
S["backbag"] >> backbag
S["jumpsuit_style"] >> jumpsuit_style
S["uplink_loc"] >> uplink_spawn_loc
@@ -352,6 +365,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_human_tail"] >> features["tail_human"]
S["feature_human_ears"] >> features["ears"]
S["feature_insect_wings"] >> features["insect_wings"]
+ S["feature_deco_wings"] >> features["deco_wings"]
S["feature_insect_fluff"] >> features["insect_fluff"]
//Custom names
@@ -448,6 +462,12 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(!features["mcolor"] || features["mcolor"] == "#000")
features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
+ if(!features["horn_color"] || features["horn_color"] == "#000")
+ features["horn_color"] = "85615a"
+
+ if(!features["wing_color"] || features["wing_color"] == "#000")
+ features["wing_color"] = "FFFFFF"
+
nameless = sanitize_integer(nameless, 0, 1, initial(nameless))
be_random_name = sanitize_integer(be_random_name, 0, 1, initial(be_random_name))
be_random_body = sanitize_integer(be_random_body, 0, 1, initial(be_random_body))
@@ -470,6 +490,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
eye_color = sanitize_hexcolor(eye_color, 3, 0)
skin_tone = sanitize_inlist(skin_tone, GLOB.skin_tones)
horn_color = sanitize_hexcolor(horn_color, 3, FALSE)
+ wing_color = sanitize_hexcolor(wing_color, 3, FALSE, "#FFFFFF")
backbag = sanitize_inlist(backbag, GLOB.backbaglist, initial(backbag))
jumpsuit_style = sanitize_inlist(jumpsuit_style, GLOB.jumpsuitlist, initial(jumpsuit_style))
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, GLOB.uplink_spawn_loc_list, initial(uplink_spawn_loc))
@@ -484,6 +505,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["body_markings"] = sanitize_inlist(features["body_markings"], GLOB.body_markings_list)
features["feature_lizard_legs"] = sanitize_inlist(features["legs"], GLOB.legs_list)
features["insect_wings"] = sanitize_inlist(features["insect_wings"], GLOB.insect_wings_list)
+ features["deco_wings"] = sanitize_inlist(features["deco_wings"], GLOB.deco_wings_list, "None")
features["insect_fluff"] = sanitize_inlist(features["insect_fluff"], GLOB.insect_fluffs_list)
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
@@ -538,6 +560,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["socks"] , socks)
WRITE_FILE(S["socks_color"] , socks_color)
WRITE_FILE(S["horn_color"] , horn_color)
+ WRITE_FILE(S["wing_color"] , wing_color)
WRITE_FILE(S["backbag"] , backbag)
WRITE_FILE(S["jumpsuit_style"] , jumpsuit_style)
WRITE_FILE(S["uplink_loc"] , uplink_spawn_loc)
@@ -553,6 +576,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
WRITE_FILE(S["feature_lizard_body_markings"] , features["body_markings"])
WRITE_FILE(S["feature_lizard_legs"] , features["legs"])
WRITE_FILE(S["feature_insect_wings"] , features["insect_wings"])
+ WRITE_FILE(S["feature_deco_wings"] , features["deco_wings"])
WRITE_FILE(S["feature_insect_fluff"] , features["insect_fluff"])
WRITE_FILE(S["feature_meat"] , features["meat_type"])
diff --git a/code/modules/client/verbs/looc.dm b/code/modules/client/verbs/looc.dm
index 4049034203..b371372dfe 100644
--- a/code/modules/client/verbs/looc.dm
+++ b/code/modules/client/verbs/looc.dm
@@ -1,3 +1,6 @@
+GLOBAL_VAR_INIT(LOOC_COLOR, null)//If this is null, use the CSS for OOC. Otherwise, use a custom colour.
+GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC")
+
/client/verb/looc(msg as text)
set name = "LOOC"
set desc = "Local OOC, seen only by those in view."
@@ -59,30 +62,17 @@
continue //Also handled later.
if(C.prefs.toggles & CHAT_OOC)
-// var/display_name = src.key
-// if(holder)
-// if(holder.fakekey)
-// if(C.holder)
-// display_name = "[holder.fakekey]/([src.key])"
-// else
-// display_name = holder.fakekey
- to_chat(C,"LOOC: [src.mob.name]: [msg] ")
+ if(GLOB.LOOC_COLOR)
+ to_chat(C, "LOOC: [src.mob.name]: [msg] ")
+ else
+ to_chat(C, "LOOC: [src.mob.name]: [msg] ")
for(var/client/C in GLOB.admins)
if(C.prefs.toggles & CHAT_OOC)
var/prefix = "(R)LOOC"
if (C.mob in heard)
prefix = "LOOC"
- to_chat(C,"[ADMIN_FLW(usr)][prefix]: [src.key]/[src.mob.name]: [msg] ")
-
- /*for(var/mob/dead/observer/G in world)
- if(!G.client)
- continue
- var/client/C = G.client
- if (C in GLOB.admins)
- continue //handled earlier.
- if(C.prefs.toggles & CHAT_OOC)
- var/prefix = "(G)LOOC"
- if (C.mob in heard)
- prefix = "LOOC"
- to_chat(C,"[prefix]: [src.key]/[src.mob.name]: [msg] ")*/
+ if(GLOB.LOOC_COLOR)
+ to_chat(C, "[ADMIN_FLW(usr)] [prefix]: [src.key]/[src.mob.name]: [msg] ")
+ else
+ to_chat(C, "[ADMIN_FLW(usr)] [prefix]: [src.key]/[src.mob.name]: [msg] ")
diff --git a/code/modules/clothing/chameleon.dm b/code/modules/clothing/chameleon.dm
index 33a83487fc..8b2a34a089 100644
--- a/code/modules/clothing/chameleon.dm
+++ b/code/modules/clothing/chameleon.dm
@@ -561,7 +561,7 @@
/obj/item/storage/belt/chameleon/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.silent = TRUE
/obj/item/storage/belt/chameleon/emp_act(severity)
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index ed3e9f9b89..1793bd8f4b 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -41,6 +41,13 @@
var/dynamic_hair_suffix = ""//head > mask for head hair
var/dynamic_fhair_suffix = ""//mask > head for facial hair
+ //basically a restriction list.
+ var/list/species_restricted = null
+ //Basically syntax is species_restricted = list("Species Name","Species Name")
+ //Add a "exclude" string to do the opposite, making it only only species listed that can't wear it.
+ //You append this to clothing objects.
+
+
/obj/item/clothing/Initialize()
. = ..()
if(CHECK_BITFIELD(clothing_flags, VOICEBOX_TOGGLABLE))
@@ -116,7 +123,7 @@
..()
if(damaged_clothes)
to_chat(user, "It looks damaged! ")
- GET_COMPONENT(pockets, /datum/component/storage)
+ var/datum/component/storage/pockets = GetComponent(/datum/component/storage)
if(pockets)
var/list/how_cool_are_your_threads = list("")
if(pockets.attack_hand_interact)
@@ -338,3 +345,38 @@ BLIND // can't see anything
deconstruct(FALSE)
else
..()
+
+
+//Species-restricted clothing check. - Thanks Oraclestation, BS13, /vg/station etc.
+/obj/item/clothing/mob_can_equip(mob/M, slot, disable_warning = TRUE)
+
+ //if we can't equip the item anyway, don't bother with species_restricted (also cuts down on spam)
+ if(!..())
+ return FALSE
+
+ // Skip species restriction checks on non-equipment slots
+ if(slot in list(SLOT_IN_BACKPACK, SLOT_L_STORE, SLOT_R_STORE))
+ return TRUE
+
+ if(species_restricted && ishuman(M))
+
+ var/wearable = null
+ var/exclusive = null
+ var/mob/living/carbon/human/H = M
+
+ if("exclude" in species_restricted) //TURNS IT INTO A BLACKLIST - AKA ALL MINUS SPECIES LISTED.
+ exclusive = TRUE
+
+ if(H.dna.species)
+ if(exclusive)
+ if(!(H.dna.species.name in species_restricted))
+ wearable = TRUE
+ else
+ if(H.dna.species.name in species_restricted)
+ wearable = TRUE
+
+ if(!wearable)
+ to_chat(M, "Your species cannot wear [src]. ")
+ return FALSE
+
+ return TRUE
diff --git a/code/modules/clothing/glasses/_glasses.dm b/code/modules/clothing/glasses/_glasses.dm
index 097b10cae5..f140fb3074 100644
--- a/code/modules/clothing/glasses/_glasses.dm
+++ b/code/modules/clothing/glasses/_glasses.dm
@@ -104,7 +104,7 @@
resistance_flags = ACID_PROOF
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 100)
-/obj/item/clothing/glasses/science/item_action_slot_check(slot)
+/obj/item/clothing/glasses/science/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_GLASSES)
return 1
@@ -281,6 +281,33 @@
..()
user.cure_blind("blindfold_[REF(src)]")
+/obj/item/clothing/glasses/sunglasses/blindfold/white
+ name = "blind personnel blindfold"
+ desc = "Indicates that the wearer suffers from blindness."
+ icon_state = "blindfoldwhite"
+ item_state = "blindfoldwhite"
+ var/colored_before = FALSE
+
+/obj/item/clothing/glasses/sunglasses/blindfold/white/equipped(mob/living/carbon/human/user, slot)
+ if(ishuman(user) && slot == SLOT_GLASSES)
+ update_icon(user)
+ user.update_inv_glasses() //Color might have been changed by update_icon.
+ ..()
+
+/obj/item/clothing/glasses/sunglasses/blindfold/white/update_icon(mob/living/carbon/human/user)
+ if(ishuman(user) && !colored_before)
+ add_atom_colour("#[user.eye_color]", FIXED_COLOUR_PRIORITY)
+ colored_before = TRUE
+
+/obj/item/clothing/glasses/sunglasses/blindfold/white/worn_overlays(isinhands = FALSE, file2use)
+ . = list()
+ if(!isinhands && ishuman(loc) && !colored_before)
+ var/mob/living/carbon/human/H = loc
+ var/mutable_appearance/M = mutable_appearance('icons/mob/eyes.dmi', "blindfoldwhite")
+ M.appearance_flags |= RESET_COLOR
+ M.color = "#[H.eye_color]"
+ . += M
+
/obj/item/clothing/glasses/sunglasses/big
desc = "Strangely ancient technology used to help provide rudimentary eye cover. Larger than average enhanced shielding blocks flashes."
icon_state = "bigsunglasses"
diff --git a/code/modules/clothing/gloves/_gloves.dm b/code/modules/clothing/gloves/_gloves.dm
index f0c1eeb833..6b674c8595 100644
--- a/code/modules/clothing/gloves/_gloves.dm
+++ b/code/modules/clothing/gloves/_gloves.dm
@@ -14,11 +14,10 @@
/obj/item/clothing/gloves/ComponentInitialize()
. = ..()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
+ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /obj/item/clothing/gloves/clean_blood)
-/obj/item/clothing/gloves/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
- return
+/obj/item/clothing/gloves/clean_blood(datum/source, strength)
+ . = ..()
transfer_blood = 0
/obj/item/clothing/gloves/suicide_act(mob/living/carbon/user)
@@ -30,8 +29,8 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedgloves")
- IF_HAS_BLOOD_DNA(src)
- . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands")
+ if(blood_DNA)
+ . += mutable_appearance('icons/effects/blood.dmi', "bloodyhands", color = blood_DNA_to_color())
/obj/item/clothing/gloves/update_clothes_damaged_state(damaging = TRUE)
..()
@@ -41,4 +40,4 @@
// Called just before an attack_hand(), in mob/UnarmedAttack()
/obj/item/clothing/gloves/proc/Touch(atom/A, proximity)
- return 0 // return 1 to cancel attack_hand()
\ No newline at end of file
+ return FALSE // return TRUE to cancel attack_hand()
\ No newline at end of file
diff --git a/code/modules/clothing/head/_head.dm b/code/modules/clothing/head/_head.dm
index 8bd7065c1f..358942627d 100644
--- a/code/modules/clothing/head/_head.dm
+++ b/code/modules/clothing/head/_head.dm
@@ -41,13 +41,56 @@
H.update_inv_head()
+///Special throw_impact for hats to frisbee hats at people to place them on their heads/attempt to de-hat them.
+/obj/item/clothing/head/throw_impact(atom/hit_atom, datum/thrownthing/thrownthing)
+ . = ..()
+ ///if the thrown object's target zone isn't the head
+ if(thrownthing.target_zone != BODY_ZONE_HEAD)
+ return
+ ///ignore any hats with the tinfoil counter-measure enabled
+ if(clothing_flags & ANTI_TINFOIL_MANEUVER)
+ return
+ ///if the hat happens to be capable of holding contents and has something in it. mostly to prevent super cheesy stuff like stuffing a mini-bomb in a hat and throwing it
+ if(LAZYLEN(contents))
+ return
+ if(iscarbon(hit_atom))
+ var/mob/living/carbon/H = hit_atom
+ if(istype(H.head, /obj/item))
+ var/obj/item/WH = H.head
+ ///check if the item has NODROP
+ if(HAS_TRAIT(WH, TRAIT_NODROP))
+ H.visible_message("[src] bounces off [H]'s [WH.name]!", "[src] bounces off your [WH.name], falling to the floor. ")
+ return
+ ///check if the item is an actual clothing head item, since some non-clothing items can be worn
+ if(istype(WH, /obj/item/clothing/head))
+ var/obj/item/clothing/head/WHH = WH
+ ///SNUG_FIT hats are immune to being knocked off
+ if(WHH.clothing_flags & SNUG_FIT)
+ H.visible_message("[src] bounces off [H]'s [WHH.name]!", "[src] bounces off your [WHH.name], falling to the floor. ")
+ return
+ ///if the hat manages to knock something off
+ if(H.dropItemToGround(WH))
+ H.visible_message("[src] knocks [WH] off [H]'s head! ", "[WH] is suddenly knocked off your head by [src]! ")
+ if(H.equip_to_slot_if_possible(src, SLOT_HEAD, FALSE, TRUE))
+ H.visible_message("[src] lands neatly on [H]'s head!", "[src] lands perfectly onto your head! ")
+ return
+ if(iscyborg(hit_atom))
+ var/mob/living/silicon/robot/R = hit_atom
+ ///hats in the borg's blacklist bounce off
+ if(!is_type_in_typecache(src, R.equippable_hats) || R.hat_offset == INFINITY)
+ R.visible_message("[src] bounces off [R]!", "[src] bounces off you, falling to the floor. ")
+ return
+ else
+ R.visible_message("[src] lands neatly on top of [R].", "[src] lands perfectly on top of you. ")
+ R.place_on_head(src) //hats aren't designed to snugly fit borg heads or w/e so they'll always manage to knock eachother off
+
/obj/item/clothing/head/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedhelmet")
- IF_HAS_BLOOD_DNA(src)
- . += mutable_appearance('icons/effects/blood.dmi', "helmetblood")
+ if(blood_DNA)
+ . += mutable_appearance('icons/effects/blood.dmi', "helmetblood", color = blood_DNA_to_color())
/obj/item/clothing/head/update_clothes_damaged_state(damaging = TRUE)
..()
diff --git a/code/modules/clothing/head/collectable.dm b/code/modules/clothing/head/collectable.dm
index 90c0690534..5457d32e8a 100644
--- a/code/modules/clothing/head/collectable.dm
+++ b/code/modules/clothing/head/collectable.dm
@@ -13,12 +13,14 @@
/obj/item/clothing/head/collectable/slime
name = "collectable slime cap!"
desc = "It just latches right in place!"
+ clothing_flags = SNUG_FIT
icon_state = "slime"
dynamic_hair_suffix = ""
/obj/item/clothing/head/collectable/xenom
name = "collectable xenomorph helmet!"
desc = "Hiss hiss hiss!"
+ clothing_flags = SNUG_FIT
icon_state = "xenom"
/obj/item/clothing/head/collectable/chef
@@ -71,13 +73,14 @@
desc = "A collectable welding helmet. Now with 80% less lead! Not for actual welding. Any welding done while wearing this helmet is done so at the owner's own risk!"
icon_state = "welding"
item_state = "welding"
- resistance_flags = NONE
+ clothing_flags = SNUG_FIT
/obj/item/clothing/head/collectable/slime
name = "collectable slime hat"
desc = "Just like a real brain slug!"
icon_state = "headslime"
item_state = "headslime"
+ clothing_flags = SNUG_FIT
/obj/item/clothing/head/collectable/flatcap
name = "collectable flat cap"
@@ -121,6 +124,7 @@
/obj/item/clothing/head/collectable/hardhat
name = "collectable hard hat"
desc = "WARNING! Offers no real protection, or luminosity, but damn, is it fancy!"
+ clothing_flags = SNUG_FIT
icon_state = "hardhat0_yellow"
item_state = "hardhat0_yellow"
@@ -143,7 +147,7 @@
desc = "Go Red! I mean Green! I mean Red! No Green!"
icon_state = "thunderdome"
item_state = "thunderdome"
- resistance_flags = NONE
+ clothing_flags = SNUG_FIT
flags_inv = HIDEHAIR
/obj/item/clothing/head/collectable/swat
@@ -151,5 +155,5 @@
desc = "That's not real blood. That's red paint." //Reference to the actual description
icon_state = "swat"
item_state = "swat"
- resistance_flags = NONE
+ clothing_flags = SNUG_FIT
flags_inv = HIDEHAIR
diff --git a/code/modules/clothing/head/hardhat.dm b/code/modules/clothing/head/hardhat.dm
index 9d38b73cd3..d72e4ba1d7 100644
--- a/code/modules/clothing/head/hardhat.dm
+++ b/code/modules/clothing/head/hardhat.dm
@@ -11,24 +11,32 @@
armor = list("melee" = 15, "bullet" = 5, "laser" = 20,"energy" = 10, "bomb" = 20, "bio" = 10, "rad" = 20, "fire" = 100, "acid" = 50)
flags_inv = 0
actions_types = list(/datum/action/item_action/toggle_helmet_light)
+ clothing_flags = SNUG_FIT
resistance_flags = FIRE_PROOF
dynamic_hair_suffix = "+generic"
dog_fashion = /datum/dog_fashion/head
-/obj/item/clothing/head/hardhat/attack_self(mob/user)
- on = !on
- icon_state = "hardhat[on]_[item_color]"
- item_state = "hardhat[on]_[item_color]"
- user.update_inv_head() //so our mob-overlays update
+/obj/item/clothing/head/hardhat/attack_self(mob/living/user)
+ toggle_helmet_light(user)
+/obj/item/clothing/head/hardhat/proc/toggle_helmet_light(mob/living/user)
+ on = !on
if(on)
turn_on(user)
else
turn_off(user)
+ update_icon()
+
+/obj/item/clothing/head/hardhat/update_icon()
+ icon_state = "hardhat[on]_[item_color]"
+ item_state = "hardhat[on]_[item_color]"
+ if(ishuman(loc))
+ var/mob/living/carbon/human/H = loc
+ H.update_inv_head()
for(var/X in actions)
var/datum/action/A = X
- A.UpdateButtonIcon()
+ A.UpdateButtonIcon(force = TRUE)
/obj/item/clothing/head/hardhat/proc/turn_on(mob/user)
set_light(brightness_on, power_on)
@@ -85,3 +93,68 @@
cold_protection = HEAD
min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
mutantrace_variation = MUTANTRACE_VARIATION
+
+/obj/item/clothing/head/hardhat/weldhat
+ name = "welding hard hat"
+ desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight AND welding shield! The bulb seems a little smaller though."
+ brightness_on = 3 //Needs a little bit of tradeoff
+ dog_fashion = null
+ actions_types = list(/datum/action/item_action/toggle_helmet_light, /datum/action/item_action/toggle_welding_screen)
+ flash_protect = 2
+ tint = 2
+ flags_inv = HIDEEYES | HIDEFACE
+ flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
+ visor_vars_to_toggle = VISOR_FLASHPROTECT | VISOR_TINT
+ visor_flags_inv = HIDEEYES | HIDEFACE
+ visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
+
+/obj/item/clothing/head/hardhat/weldhat/Initialize()
+ . = ..()
+ update_icon()
+
+/obj/item/clothing/head/hardhat/weldhat/attack_self(mob/living/user)
+ toggle_helmet_light(user)
+
+/obj/item/clothing/head/hardhat/weldhat/AltClick(mob/user)
+ if(user.canUseTopic(src, BE_CLOSE))
+ toggle_welding_screen(user)
+
+/obj/item/clothing/head/hardhat/weldhat/proc/toggle_welding_screen(mob/living/user)
+ if(weldingvisortoggle(user))
+ playsound(src, 'sound/mecha/mechmove03.ogg', 50, TRUE) //Visors don't just come from nothing
+ update_icon()
+
+/obj/item/clothing/head/hardhat/weldhat/worn_overlays(isinhands)
+ . = ..()
+ if(!isinhands)
+ . += mutable_appearance('icons/mob/head.dmi', "weldhelmet")
+ if(!up)
+ . += mutable_appearance('icons/mob/head.dmi', "weldvisor")
+
+/obj/item/clothing/head/hardhat/weldhat/update_icon()
+ cut_overlays()
+ if(!up)
+ add_overlay("weldvisor")
+ ..()
+
+/obj/item/clothing/head/hardhat/weldhat/orange
+ icon_state = "hardhat0_orange"
+ item_state = "hardhat0_orange"
+ item_color = "orange"
+
+/obj/item/clothing/head/hardhat/weldhat/white
+ desc = "A piece of headgear used in dangerous working conditions to protect the head. Comes with a built-in flashlight AND welding shield!" //This bulb is not smaller
+ icon_state = "hardhat0_white"
+ item_state = "hardhat0_white"
+ brightness_on = 4 //Boss always takes the best stuff
+ item_color = "white"
+ clothing_flags = STOPSPRESSUREDAMAGE
+ heat_protection = HEAD
+ max_heat_protection_temperature = FIRE_HELM_MAX_TEMP_PROTECT
+ cold_protection = HEAD
+ min_cold_protection_temperature = FIRE_HELM_MIN_TEMP_PROTECT
+
+/obj/item/clothing/head/hardhat/weldhat/dblue
+ icon_state = "hardhat0_dblue"
+ item_state = "hardhat0_dblue"
+ item_color = "dblue"
\ No newline at end of file
diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm
index be6e270e45..8a1cc01bd5 100644
--- a/code/modules/clothing/head/helmet.dm
+++ b/code/modules/clothing/head/helmet.dm
@@ -10,7 +10,7 @@
heat_protection = HEAD
max_heat_protection_temperature = HELMET_MAX_TEMP_PROTECT
strip_delay = 60
- resistance_flags = NONE
+ clothing_flags = SNUG_FIT
flags_cover = HEADCOVERSEYES
flags_inv = HIDEHAIR
diff --git a/code/modules/clothing/head/misc.dm b/code/modules/clothing/head/misc.dm
index 041f0ba012..cac98e74fc 100644
--- a/code/modules/clothing/head/misc.dm
+++ b/code/modules/clothing/head/misc.dm
@@ -67,12 +67,14 @@
desc = "A plastic replica of a Syndicate agent's space helmet. You'll look just like a real murderous Syndicate agent in this! This is a toy, it is not made for use in space!"
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
mutantrace_variation = MUTANTRACE_VARIATION
+ clothing_flags = SNUG_FIT
/obj/item/clothing/head/cueball
name = "cueball helmet"
desc = "A large, featureless white orb meant to be worn on your head. How do you even see out of this thing?"
icon_state = "cueball"
item_state="cueball"
+ clothing_flags = SNUG_FIT
flags_cover = HEADCOVERSEYES|HEADCOVERSMOUTH
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
@@ -81,6 +83,7 @@
desc = "A ball of white styrofoam. So festive."
icon_state = "snowman_h"
item_state = "snowman_h"
+ clothing_flags = SNUG_FIT
flags_cover = HEADCOVERSEYES
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
@@ -90,6 +93,7 @@
icon_state = "justicered"
item_state = "justicered"
flags_inv = HIDEHAIR|HIDEEARS|HIDEEYES|HIDEFACE|HIDEFACIALHAIR|HIDESNOUT
+ clothing_flags = SNUG_FIT
flags_cover = HEADCOVERSEYES
/obj/item/clothing/head/justice/blue
@@ -161,6 +165,7 @@
icon_state = "chickenhead"
item_state = "chickensuit"
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
+ clothing_flags = SNUG_FIT
/obj/item/clothing/head/griffin
name = "griffon head"
@@ -168,6 +173,7 @@
icon_state = "griffinhat"
item_state = "griffinhat"
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
+ clothing_flags = SNUG_FIT
/obj/item/clothing/head/bearpelt
name = "bear pelt hat"
@@ -181,6 +187,7 @@
item_state = "xenos_helm"
desc = "A helmet made out of chitinous alien hide."
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
+ clothing_flags = SNUG_FIT
/obj/item/clothing/head/fedora
name = "fedora"
@@ -302,6 +309,7 @@
desc = "When everything's going to crab, protecting your head is the best choice."
icon_state = "lobster_hat"
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
+ clothing_flags = SNUG_FIT
/obj/item/clothing/head/drfreezehat
name = "doctor freeze's wig"
diff --git a/code/modules/clothing/head/misc_special.dm b/code/modules/clothing/head/misc_special.dm
index 3f96796a00..a3a4f1d859 100644
--- a/code/modules/clothing/head/misc_special.dm
+++ b/code/modules/clothing/head/misc_special.dm
@@ -29,6 +29,7 @@
visor_flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
resistance_flags = FIRE_PROOF
mutantrace_variation = MUTANTRACE_VARIATION
+ clothing_flags = SNUG_FIT
/obj/item/clothing/head/welding/attack_self(mob/user)
weldingvisortoggle(user)
@@ -76,7 +77,7 @@
hitsound = 'sound/weapons/tap.ogg'
STOP_PROCESSING(SSobj, src)
-/obj/item/clothing/head/hardhat/cakehat/is_hot()
+/obj/item/clothing/head/hardhat/cakehat/get_temperature()
return on * heat
/*
* Ushanka
@@ -115,6 +116,7 @@
item_state = "hardhat0_pumpkin"
item_color = "pumpkin"
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
+ clothing_flags = SNUG_FIT
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
brightness_on = 2 //luminosity when on
flags_cover = HEADCOVERSEYES
@@ -163,6 +165,7 @@
desc = "A helmet made out of a box."
icon_state = "cardborg_h"
item_state = "cardborg_h"
+ clothing_flags = SNUG_FIT
flags_cover = HEADCOVERSEYES
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
@@ -227,6 +230,7 @@
desc = "A crude helmet made out of bronze plates. It offers very little in the way of protection."
icon = 'icons/obj/clothing/clockwork_garb.dmi'
icon_state = "clockwork_helmet_old"
+ clothing_flags = SNUG_FIT
flags_inv = HIDEEARS|HIDEHAIR
armor = list("melee" = 5, "bullet" = 0, "laser" = -5, "energy" = 0, "bomb" = 10, "bio" = 0, "rad" = 0, "fire" = 20, "acid" = 20)
@@ -238,25 +242,62 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = -5,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = -5, "fire" = 0, "acid" = 0)
equip_delay_other = 140
var/datum/brain_trauma/mild/phobia/paranoia
+ var/warped = FALSE
+ clothing_flags = ANTI_TINFOIL_MANEUVER
+
+/obj/item/clothing/head/foilhat/Initialize(mapload)
+ . = ..()
+ if(!warped)
+ AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD, 6, TRUE, null, CALLBACK(src, .proc/warp_up))
+ else
+ warp_up()
/obj/item/clothing/head/foilhat/equipped(mob/living/carbon/human/user, slot)
- ..()
- if(slot == SLOT_HEAD)
- if(paranoia)
- QDEL_NULL(paranoia)
- paranoia = new()
- user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC, "conspiracies")
- to_chat(user, "As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. ")
+ . = ..()
+ if(slot != SLOT_HEAD || warped)
+ return
+ if(paranoia)
+ QDEL_NULL(paranoia)
+ paranoia = new()
+ user.gain_trauma(paranoia, TRAUMA_RESILIENCE_MAGIC, "conspiracies")
+ to_chat(user, "As you don the foiled hat, an entire world of conspiracy theories and seemingly insane ideas suddenly rush into your mind. What you once thought unbelievable suddenly seems.. undeniable. Everything is connected and nothing happens just by accident. You know too much and now they're out to get you. ")
+
+/obj/item/clothing/head/foilhat/MouseDrop(atom/over_object)
+ //God Im sorry
+ if(!warped && iscarbon(usr))
+ var/mob/living/carbon/C = usr
+ if(src == C.head)
+ to_chat(C, "Why would you want to take this off? Do you want them to get into your mind?! ")
+ return
+ return ..()
/obj/item/clothing/head/foilhat/dropped(mob/user)
- ..()
+ . = ..()
if(paranoia)
QDEL_NULL(paranoia)
+/obj/item/clothing/head/foilhat/proc/warp_up()
+ name = "scorched tinfoil hat"
+ desc = "A badly warped up hat. Quite unprobable this will still work against any of fictional and contemporary dangers it used to."
+ warped = TRUE
+ if(!isliving(loc) || !paranoia)
+ return
+ var/mob/living/target = loc
+ if(target.get_item_by_slot(SLOT_HEAD) != src)
+ return
+ QDEL_NULL(paranoia)
+ if(!target.IsUnconscious())
+ to_chat(target, "Your zealous conspirationism rapidly dissipates as the donned hat warps up into a ruined mess. All those theories starting to sound like nothing but a ridicolous fanfare. ")
+
/obj/item/clothing/head/foilhat/attack_hand(mob/user)
- if(iscarbon(user))
+ if(!warped && iscarbon(user))
var/mob/living/carbon/C = user
if(src == C.head)
to_chat(user, "Why would you want to take this off? Do you want them to get into your mind?! ")
return
- ..()
+ return ..()
+
+/obj/item/clothing/head/foilhat/microwave_act(obj/machinery/microwave/M)
+ . = ..()
+ if(!warped)
+ warp_up()
diff --git a/code/modules/clothing/head/vg_hats.dm b/code/modules/clothing/head/vg_hats.dm
index dc245cd39a..87f64baf13 100644
--- a/code/modules/clothing/head/vg_hats.dm
+++ b/code/modules/clothing/head/vg_hats.dm
@@ -82,13 +82,6 @@
item_state = "nr_helmet"
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
-/obj/item/clothing/head/stalhelm
- name = "Stalhelm"
- desc = "Ein Helm, um die Nazi-Interesse an fremden Raumstationen zu sichern."
- icon_state = "stalhelm"
- item_state = "stalhelm"
- icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
-
/obj/item/clothing/head/panzer
name = "Panzer Cap"
desc = "Command any mech in style."
@@ -96,13 +89,6 @@
item_state = "panzercap"
icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
-/obj/item/clothing/head/naziofficer
- name = "Officer Cap"
- desc = "Style is all that matters."
- icon_state = "officercap"
- item_state = "officercap"
- icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
-
/obj/item/clothing/head/russobluecamohat
name = "russian blue camo beret"
desc = "A symbol of discipline, honor, and lots and lots of removal of some type of skewered food."
diff --git a/code/modules/clothing/masks/_masks.dm b/code/modules/clothing/masks/_masks.dm
index 9ee2ebcd54..c00e6f72e0 100644
--- a/code/modules/clothing/masks/_masks.dm
+++ b/code/modules/clothing/masks/_masks.dm
@@ -59,8 +59,8 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
- IF_HAS_BLOOD_DNA(src)
- . += mutable_appearance('icons/effects/blood.dmi', "maskblood")
+ if(blood_DNA)
+ . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
/obj/item/clothing/mask/update_clothes_damaged_state(damaging = TRUE)
..()
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index 330f69ddaf..2356bb16eb 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -12,8 +12,8 @@
if(body_parts_covered & HEAD)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedmask")
- IF_HAS_BLOOD_DNA(src)
- . += mutable_appearance('icons/effects/blood.dmi', "maskblood")
+ if(blood_DNA)
+ . += mutable_appearance('icons/effects/blood.dmi', "maskblood", color = blood_DNA_to_color())
/obj/item/clothing/neck/tie
name = "tie"
diff --git a/code/modules/clothing/outfits/ert.dm b/code/modules/clothing/outfits/ert.dm
index 523ed55aa4..88cc7123fd 100644
--- a/code/modules/clothing/outfits/ert.dm
+++ b/code/modules/clothing/outfits/ert.dm
@@ -10,7 +10,7 @@
if(visualsOnly)
return
- var/obj/item/implant/mindshield/L = new/obj/item/implant/mindshield(H)
+ var/obj/item/implant/mindshield/L = new
L.implant(H, null, 1)
var/obj/item/radio/R = H.ears
diff --git a/code/modules/clothing/outfits/plasmaman.dm b/code/modules/clothing/outfits/plasmaman.dm
new file mode 100644
index 0000000000..20b67891d8
--- /dev/null
+++ b/code/modules/clothing/outfits/plasmaman.dm
@@ -0,0 +1,164 @@
+/datum/outfit/plasmaman/bar
+ name = "Bartender Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/white
+ uniform = /obj/item/clothing/under/plasmaman/enviroslacks
+
+/datum/outfit/plasmaman/chef
+ name = "Chef Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/white
+ uniform = /obj/item/clothing/under/plasmaman/chef
+
+/datum/outfit/plasmaman/botany
+ name = "Botany Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/botany
+ uniform = /obj/item/clothing/under/plasmaman/botany
+
+/datum/outfit/plasmaman/curator
+ name = "Curator Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/curator
+ uniform = /obj/item/clothing/under/plasmaman/curator
+
+/datum/outfit/plasmaman/chaplain
+ name = "Chaplain Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/chaplain
+ uniform = /obj/item/clothing/under/plasmaman/chaplain
+
+/datum/outfit/plasmaman/janitor
+ name = "Janitor Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/janitor
+ uniform = /obj/item/clothing/under/plasmaman/janitor
+
+/datum/outfit/plasmaman/hop
+ name = "Head of Personell Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/hop
+ uniform = /obj/item/clothing/under/plasmaman/hop
+
+/datum/outfit/plasmaman/captain
+ name = "Captain Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/captain
+ uniform = /obj/item/clothing/under/plasmaman/captain
+
+/datum/outfit/plasmaman/security
+ name = "Security Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/security
+ uniform = /obj/item/clothing/under/plasmaman/security
+ ears = /obj/item/radio/headset/headset_sec
+
+/datum/outfit/plasmaman/detective
+ name = "Detective Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/white
+ uniform = /obj/item/clothing/under/plasmaman/enviroslacks
+
+/datum/outfit/plasmaman/warden
+ name = "Warden Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/security/warden
+ uniform = /obj/item/clothing/under/plasmaman/security/warden
+
+/datum/outfit/plasmaman/hos
+ name = "Head of Security Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/security/hos
+ uniform = /obj/item/clothing/under/plasmaman/security/hos
+
+/datum/outfit/plasmaman/cargo
+ name = "Cargo Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/cargo
+ uniform = /obj/item/clothing/under/plasmaman/cargo
+
+/datum/outfit/plasmaman/mining
+ name = "Mining Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/mining
+ uniform = /obj/item/clothing/under/plasmaman/mining
+
+/datum/outfit/plasmaman/medical
+ name = "Medical Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/medical
+ uniform = /obj/item/clothing/under/plasmaman/medical
+
+/datum/outfit/plasmaman/cmo
+ name = "Chief Medical Officer Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/cmo
+ uniform = /obj/item/clothing/under/plasmaman/cmo
+
+/datum/outfit/plasmaman/viro
+ name = "Virology Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/viro
+ uniform = /obj/item/clothing/under/plasmaman/viro
+
+/datum/outfit/plasmaman/chemist
+ name = "Chemist Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/chemist
+ uniform = /obj/item/clothing/under/plasmaman/chemist
+
+/datum/outfit/plasmaman/genetics
+ name = "Genetics Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/genetics
+ uniform = /obj/item/clothing/under/plasmaman/genetics
+
+/datum/outfit/plasmaman/science
+ name = "Science Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/science
+ uniform = /obj/item/clothing/under/plasmaman/science
+
+/datum/outfit/plasmaman/rd
+ name = "Research Director Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/rd
+ uniform = /obj/item/clothing/under/plasmaman/rd
+
+/datum/outfit/plasmaman/robotics
+ name = "Robotics Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/robotics
+ uniform = /obj/item/clothing/under/plasmaman/robotics
+
+/datum/outfit/plasmaman/engineering
+ name = "Engineering Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/engineering
+ uniform = /obj/item/clothing/under/plasmaman/engineering
+
+/datum/outfit/plasmaman/ce
+ name = "Chief Engineer Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/engineering/ce
+ uniform = /obj/item/clothing/under/plasmaman/engineering/ce
+
+/datum/outfit/plasmaman/atmospherics
+ name = "Atmospherics Plasmaman"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/atmospherics
+ uniform = /obj/item/clothing/under/plasmaman/atmospherics
+
+/datum/outfit/plasmaman/mime
+ name = "Plasmamime"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/mime
+ uniform = /obj/item/clothing/under/plasmaman/mime
+ mask = /obj/item/clothing/mask/gas/mime
+
+/datum/outfit/plasmaman/clown
+ name = "Plasmaclown"
+
+ head = /obj/item/clothing/head/helmet/space/plasmaman/clown
+ uniform = /obj/item/clothing/under/plasmaman/clown
+ mask = /obj/item/clothing/mask/gas/clown_hat
\ No newline at end of file
diff --git a/code/modules/clothing/outfits/standard.dm b/code/modules/clothing/outfits/standard.dm
index 325c124867..6c961dc250 100644
--- a/code/modules/clothing/outfits/standard.dm
+++ b/code/modules/clothing/outfits/standard.dm
@@ -399,7 +399,7 @@
R.set_frequency(FREQ_CENTCOM)
R.freqlock = TRUE
- var/obj/item/implant/mindshield/L = new/obj/item/implant/mindshield(H)//Here you go Deuryn
+ var/obj/item/implant/mindshield/L = new //Here you go Deuryn
L.implant(H, null, 1)
@@ -426,7 +426,7 @@
/datum/outfit/debug //Debug objs plus hardsuit
name = "Debug outfit"
- uniform = /obj/item/clothing/under/patriotsuit
+ uniform = /obj/item/clothing/under/patriotsuit
suit = /obj/item/clothing/suit/space/hardsuit/syndi/elite
shoes = /obj/item/clothing/shoes/magboots/advance
suit_store = /obj/item/tank/internals/oxygen
diff --git a/code/modules/clothing/outfits/vr.dm b/code/modules/clothing/outfits/vr.dm
index cd8930641f..cd8115ac7d 100644
--- a/code/modules/clothing/outfits/vr.dm
+++ b/code/modules/clothing/outfits/vr.dm
@@ -29,9 +29,9 @@
. = ..()
var/obj/item/uplink/U = new /obj/item/uplink/nuclear_restricted(H, H.key, 80)
H.equip_to_slot_or_del(U, SLOT_IN_BACKPACK)
- var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(H)
+ var/obj/item/implant/weapons_auth/W = new
W.implant(H)
- var/obj/item/implant/explosive/E = new/obj/item/implant/explosive(H)
+ var/obj/item/implant/explosive/E = new
E.implant(H)
H.faction |= ROLE_SYNDICATE
H.update_icons()
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index 00cb2678cd..37ab2b2bf4 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -11,17 +11,19 @@
permeability_coefficient = 0.5
slowdown = SHOES_SLOWDOWN
var/blood_state = BLOOD_STATE_NOT_BLOODY
- var/list/bloody_shoes = list(BLOOD_STATE_HUMAN = 0,BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
+ var/list/bloody_shoes = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
var/offset = 0
var/equipped_before_drop = FALSE
//CITADEL EDIT Enables digitigrade shoe styles
var/adjusted = NORMAL_STYLE
mutantrace_variation = MUTANTRACE_VARIATION
+ var/last_bloodtype = "" //used to track the last bloodtype to have graced these shoes; makes for better performing footprint shenanigans
+ var/last_blood_DNA = "" //same as last one
/obj/item/clothing/shoes/ComponentInitialize()
. = ..()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
+ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /obj/item/clothing/shoes/clean_blood)
/obj/item/clothing/shoes/suicide_act(mob/living/carbon/user)
if(rand(2)>1)
@@ -42,22 +44,29 @@
playsound(user, 'sound/weapons/genhit2.ogg', 50, 1)
return(BRUTELOSS)
+
+/obj/item/clothing/shoes/transfer_blood_dna(list/blood_dna, diseases)
+ ..()
+ if(blood_dna.len)
+ last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
+ last_blood_DNA = blood_dna[blood_dna.len]
+
/obj/item/clothing/shoes/worn_overlays(isinhands = FALSE)
. = list()
if(!isinhands)
var/bloody = FALSE
- IF_HAS_BLOOD_DNA(src)
+ if(blood_DNA)
bloody = TRUE
else
- bloody = bloody_shoes[BLOOD_STATE_HUMAN]
+ bloody = bloody_shoes[BLOOD_STATE_BLOOD]
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damagedshoe")
if(bloody)
if(adjusted == NORMAL_STYLE)
- . += mutable_appearance('icons/effects/blood.dmi', "shoeblood")
+ . += mutable_appearance('icons/effects/blood.dmi', "shoeblood", color = blood_DNA_to_color())
else
- . += mutable_appearance('modular_citadel/icons/mob/digishoes.dmi', "shoeblood")
+ . += mutable_appearance('modular_citadel/icons/mob/digishoes.dmi', "shoeblood", color = blood_DNA_to_color())
/obj/item/clothing/shoes/equipped(mob/user, slot)
. = ..()
@@ -93,14 +102,13 @@
var/mob/M = loc
M.update_inv_shoes()
-/obj/item/clothing/shoes/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
- return
- bloody_shoes = list(BLOOD_STATE_HUMAN = 0,BLOOD_STATE_XENO = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
+/obj/item/clothing/shoes/clean_blood(datum/source, strength)
+ . = ..()
+ bloody_shoes = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
blood_state = BLOOD_STATE_NOT_BLOODY
if(ismob(loc))
var/mob/M = loc
M.update_inv_shoes()
/obj/item/proc/negates_gravity()
- return FALSE
\ No newline at end of file
+ return FALSE
diff --git a/code/modules/clothing/shoes/bananashoes.dm b/code/modules/clothing/shoes/bananashoes.dm
index b634894805..d13e655d43 100644
--- a/code/modules/clothing/shoes/bananashoes.dm
+++ b/code/modules/clothing/shoes/bananashoes.dm
@@ -17,7 +17,7 @@
/obj/item/clothing/shoes/clown_shoes/banana_shoes/step_action()
. = ..()
- GET_COMPONENT(bananium, /datum/component/material_container)
+ var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
if(on)
if(bananium.amount(MAT_BANANIUM) < 100)
on = !on
@@ -30,7 +30,7 @@
bananium.use_amount_type(100, MAT_BANANIUM)
/obj/item/clothing/shoes/clown_shoes/banana_shoes/attack_self(mob/user)
- GET_COMPONENT(bananium, /datum/component/material_container)
+ var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
var/sheet_amount = bananium.retrieve_all()
if(sheet_amount)
to_chat(user, "You retrieve [sheet_amount] sheets of bananium from the prototype shoes. ")
@@ -42,7 +42,7 @@
to_chat(user, "The shoes are [on ? "enabled" : "disabled"]. ")
/obj/item/clothing/shoes/clown_shoes/banana_shoes/ui_action_click(mob/user)
- GET_COMPONENT(bananium, /datum/component/material_container)
+ var/datum/component/material_container/bananium = GetComponent(/datum/component/material_container)
if(bananium.amount(MAT_BANANIUM))
on = !on
update_icon()
diff --git a/code/modules/clothing/shoes/miscellaneous.dm b/code/modules/clothing/shoes/miscellaneous.dm
index 7fe527fec3..080d9281cf 100644
--- a/code/modules/clothing/shoes/miscellaneous.dm
+++ b/code/modules/clothing/shoes/miscellaneous.dm
@@ -311,3 +311,25 @@
set_light(0)
lightCycle = 0
active = FALSE
+
+// kevin is into feet
+/obj/item/clothing/shoes/wraps
+ name = "gilded leg wraps"
+ desc = "Ankle coverings. These ones have a golden design."
+ icon_state = "gildedcuffs"
+ body_parts_covered = FALSE
+
+/obj/item/clothing/shoes/wraps/silver
+ name = "silver leg wraps"
+ desc = "Ankle coverings. Not made of real silver."
+ icon_state = "silvergildedcuffs"
+
+/obj/item/clothing/shoes/wraps/red
+ name = "red leg wraps"
+ desc = "Ankle coverings. Show off your style with these shiny red ones!"
+ icon_state = "redcuffs"
+
+/obj/item/clothing/shoes/wraps/blue
+ name = "blue leg wraps"
+ desc = "Ankle coverings. Hang ten, brother."
+ icon_state = "bluecuffs"
\ No newline at end of file
diff --git a/code/modules/clothing/spacesuits/_spacesuits.dm b/code/modules/clothing/spacesuits/_spacesuits.dm
index 662a91c80c..117fbc49e0 100644
--- a/code/modules/clothing/spacesuits/_spacesuits.dm
+++ b/code/modules/clothing/spacesuits/_spacesuits.dm
@@ -4,7 +4,7 @@
name = "space helmet"
icon_state = "spaceold"
desc = "A special helmet with solar UV shielding to protect your eyes from harmful rays."
- clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS
+ clothing_flags = STOPSPRESSUREDAMAGE | THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | ALLOWINTERNALS | SNUG_FIT
item_state = "spaceold"
permeability_coefficient = 0.01
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 50, "fire" = 80, "acid" = 70)
@@ -22,6 +22,7 @@
resistance_flags = NONE
dog_fashion = null
mutantrace_variation = MUTANTRACE_VARIATION
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
/obj/item/clothing/suit/space
name = "space suit"
@@ -44,4 +45,5 @@
strip_delay = 80
equip_delay_other = 80
resistance_flags = NONE
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //rated for cosmic radation :honk:
tauric = TRUE //Citadel Add for tauric hardsuits
diff --git a/code/modules/clothing/spacesuits/flightsuit.dm b/code/modules/clothing/spacesuits/flightsuit.dm
index b105b72234..7ead462b1e 100644
--- a/code/modules/clothing/spacesuits/flightsuit.dm
+++ b/code/modules/clothing/spacesuits/flightsuit.dm
@@ -547,7 +547,7 @@
changeWearer()
..()
-/obj/item/flightpack/item_action_slot_check(slot)
+/obj/item/flightpack/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == ITEM_SLOT_BACK)
return TRUE
@@ -574,7 +574,7 @@
momentum_speed_y = 0
momentum_speed = max(momentum_speed_x, momentum_speed_y)
-/obj/item/flightpack/item_action_slot_check(slot)
+/obj/item/flightpack/item_action_slot_check(slot, mob/user, datum/action/A)
return slot == SLOT_BACK
/obj/item/flightpack/proc/enable_stabilizers()
@@ -730,7 +730,7 @@
if(!active)
clothing_flags &= ~NOSLIP
-/obj/item/clothing/shoes/flightshoes/item_action_slot_check(slot)
+/obj/item/clothing/shoes/flightshoes/item_action_slot_check(slot, mob/user, datum/action/A)
return slot == SLOT_SHOES
/obj/item/clothing/shoes/flightshoes/proc/delink_suit()
diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm
index 2694497579..fa6b01415e 100644
--- a/code/modules/clothing/spacesuits/hardsuit.dm
+++ b/code/modules/clothing/spacesuits/hardsuit.dm
@@ -47,7 +47,7 @@
suit.RemoveHelmet()
soundloop.stop(user)
-/obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot)
+/obj/item/clothing/head/helmet/space/hardsuit/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_HEAD)
return 1
@@ -135,7 +135,7 @@
to_chat(user, "You cannot remove the jetpack from [src] while wearing it. ")
return
- jetpack.turn_off()
+ jetpack.turn_off(user)
jetpack.forceMove(drop_location())
jetpack = null
to_chat(user, "You successfully remove the jetpack from [src]. ")
@@ -158,7 +158,7 @@
var/datum/action/A = X
A.Remove(user)
-/obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot)
+/obj/item/clothing/suit/space/hardsuit/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_WEAR_SUIT) //we only give the mob the ability to toggle the helmet if he's wearing the hardsuit.
return 1
@@ -433,7 +433,7 @@
/obj/item/clothing/suit/space/hardsuit/wizard/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, FALSE)
+ AddComponent(/datum/component/anti_magic, TRUE, FALSE, FALSE, ITEM_SLOT_OCLOTHING, INFINITY, FALSE)
//Medical hardsuit
/obj/item/clothing/head/helmet/space/hardsuit/medical
@@ -605,7 +605,6 @@
armor = list("melee" = 30, "bullet" = 5, "laser" = 5, "energy" = 0, "bomb" = 50, "bio" = 100, "rad" = 100, "fire" = 100, "acid" = 75)
item_color = "ancient"
resistance_flags = FIRE_PROOF
- var/datum/component/mobhook
/obj/item/clothing/suit/space/hardsuit/ancient
name = "prototype RIG hardsuit"
@@ -617,7 +616,7 @@
helmettype = /obj/item/clothing/head/helmet/space/hardsuit/ancient
resistance_flags = FIRE_PROOF
var/footstep = 1
- var/datum/component/mobhook
+ var/mob/listeningTo
/obj/item/clothing/suit/space/hardsuit/ancient/mason
name = "M.A.S.O.N RIG"
@@ -674,20 +673,24 @@
/obj/item/clothing/suit/space/hardsuit/ancient/equipped(mob/user, slot)
. = ..()
- if (slot == SLOT_WEAR_SUIT)
- if (mobhook && mobhook.parent != user)
- QDEL_NULL(mobhook)
- if (!mobhook)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_mob_move)))
- else
- QDEL_NULL(mobhook)
+ if(slot != SLOT_WEAR_SUIT)
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ return
+ if(listeningTo == user)
+ return
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
+ listeningTo = user
/obj/item/clothing/suit/space/hardsuit/ancient/dropped()
. = ..()
- QDEL_NULL(mobhook)
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
/obj/item/clothing/suit/space/hardsuit/ancient/Destroy()
- QDEL_NULL(mobhook) // mobhook is not our component
+ listeningTo = null
return ..()
/////////////SHIELDED//////////////////////////////////
@@ -864,3 +867,133 @@
strip_delay = 130
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
actions_types = list()
+
+/*
+ CYDONIAN ARMOR THAT IS RGB AND STUFF WOOOOOOOOOO
+*/
+
+/obj/item/clothing/head/helmet/space/hardsuit/lavaknight
+ name = "cydonian helmet"
+ desc = "A helmet designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
+ icon_state = "knight_cydonia"
+ item_state = "knight_yellow"
+ item_color = null
+ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
+ resistance_flags = FIRE_PROOF | LAVA_PROOF
+ heat_protection = HEAD
+ armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
+ brightness_on = 7
+ allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
+ var/energy_color = "#35FFF0"
+ var/obj/item/clothing/suit/space/hardsuit/lavaknight/linkedsuit = null
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
+
+/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/Initialize()
+ . = ..()
+ if(istype(loc, /obj/item/clothing/suit/space/hardsuit/lavaknight))
+ var/obj/item/clothing/suit/space/hardsuit/lavaknight/S = loc
+ energy_color = S.energy_color
+ update_icon()
+
+/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/attack_self(mob/user)
+ on = !on
+
+ if(on)
+ set_light(brightness_on)
+ else
+ set_light(0)
+ for(var/X in actions)
+ var/datum/action/A = X
+ A.UpdateButtonIcon()
+
+/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/update_icon()
+ var/mutable_appearance/helm_overlay = mutable_appearance(icon, "knight_cydonia_overlay")
+
+ if(energy_color)
+ helm_overlay.color = energy_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(helm_overlay)
+
+/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file)
+ . = ..()
+ if(!isinhands)
+ var/mutable_appearance/energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
+ energy_overlay.plane = ABOVE_LIGHTING_LAYER
+ energy_overlay.color = energy_color
+ . += energy_overlay
+
+/obj/item/clothing/suit/space/hardsuit/lavaknight
+ icon_state = "knight_cydonia"
+ name = "cydonian armor"
+ desc = "A suit designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
+ item_state = "swat_suit"
+ max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
+ resistance_flags = FIRE_PROOF | LAVA_PROOF
+ armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
+ allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe)
+ helmettype = /obj/item/clothing/head/helmet/space/hardsuit/lavaknight
+ heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
+ tauric = TRUE //Citadel Add for tauric hardsuits
+
+ var/energy_color = "#35FFF0"
+
+/obj/item/clothing/suit/space/hardsuit/lavaknight/Initialize()
+ ..()
+ light_color = energy_color
+ set_light(1)
+ update_icon()
+
+/obj/item/clothing/suit/space/hardsuit/lavaknight/update_icon()
+ var/mutable_appearance/suit_overlay = mutable_appearance(icon, "knight_cydonia_overlay")
+
+ if(energy_color)
+ suit_overlay.color = energy_color
+
+ cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
+
+ add_overlay(suit_overlay)
+
+/obj/item/clothing/suit/space/hardsuit/lavaknight/worn_overlays(isinhands = FALSE, icon_file)
+ . = ..()
+ if(!isinhands)
+ var/mutable_appearance/energy_overlay
+ if(taurmode == SNEK_TAURIC)
+ energy_overlay = mutable_appearance('modular_citadel/icons/mob/taur_naga.dmi', "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
+ else if(taurmode == PAW_TAURIC)
+ energy_overlay = mutable_appearance('modular_citadel/icons/mob/taur_canine.dmi', "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
+ else
+ energy_overlay = mutable_appearance(icon_file, "knight_cydonia_overlay", ABOVE_LIGHTING_LAYER)
+
+ energy_overlay.plane = ABOVE_LIGHTING_LAYER
+ energy_overlay.color = energy_color
+ . += energy_overlay
+
+/obj/item/clothing/suit/space/hardsuit/lavaknight/AltClick(mob/living/user)
+ if(user.incapacitated() || !istype(user))
+ to_chat(user, "You can't do that right now! ")
+ return
+ if(!in_range(src, user))
+ return
+ if(user.incapacitated() || !istype(user) || !in_range(src, user))
+ return
+
+ if(alert("Are you sure you want to recolor your armor stripes?", "Confirm Repaint", "Yes", "No") == "Yes")
+ var/energy_color_input = input(usr,"","Choose Energy Color",energy_color) as color|null
+ if(energy_color_input)
+ energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
+ user.update_inv_wear_suit()
+ if(helmet)
+ var/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/H = helmet
+ H.energy_color = energy_color
+ user.update_inv_head()
+ H.update_icon()
+ update_icon()
+ user.update_inv_wear_suit()
+ light_color = energy_color
+ update_light()
+
+/obj/item/clothing/suit/space/hardsuit/lavaknight/examine(mob/user)
+ ..()
+ to_chat(user, "Alt-click to recolor it. ")
diff --git a/code/modules/clothing/spacesuits/miscellaneous.dm b/code/modules/clothing/spacesuits/miscellaneous.dm
index 5d718a8173..88e17d158c 100644
--- a/code/modules/clothing/spacesuits/miscellaneous.dm
+++ b/code/modules/clothing/spacesuits/miscellaneous.dm
@@ -368,6 +368,10 @@ Contains:
resistance_flags = FIRE_PROOF
mutantrace_variation = NO_MUTANTRACE_VARIATION
+/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
+ . = ..()
+ AddComponent(/datum/component/anti_magic, FALSE, FALSE, TRUE, ITEM_SLOT_HEAD)
+
/obj/item/clothing/suit/space/hardsuit/ert/paranormal
name = "paranormal response team suit"
desc = "Powerful wards are built into this hardsuit, protecting the user from all manner of paranormal threats."
@@ -380,7 +384,7 @@ Contains:
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_OCLOTHING)
/obj/item/clothing/suit/space/hardsuit/ert/paranormal/inquisitor
name = "inquisitor's hardsuit"
diff --git a/code/modules/clothing/spacesuits/plasmamen.dm b/code/modules/clothing/spacesuits/plasmamen.dm
index d1ee88d5a8..0b07aafa5d 100644
--- a/code/modules/clothing/spacesuits/plasmamen.dm
+++ b/code/modules/clothing/spacesuits/plasmamen.dm
@@ -12,7 +12,7 @@
var/next_extinguish = 0
var/extinguish_cooldown = 100
var/extinguishes_left = 10
-
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/suit/space/eva/plasmaman/examine(mob/user)
..()
@@ -45,12 +45,18 @@
resistance_flags = FIRE_PROOF
var/brightness_on = 4 //luminosity when the light is on
var/on = FALSE
+ var/light_overlay = "envirohelm-light"
actions_types = list(/datum/action/item_action/toggle_helmet_light)
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
/obj/item/clothing/head/helmet/space/plasmaman/attack_self(mob/user)
+ if(!light_overlay)
+ return
on = !on
- icon_state = "[initial(icon_state)][on ? "-light":""]"
- item_state = icon_state
+ if(!on)
+ cut_overlay(light_overlay)
+ else
+ add_overlay(light_overlay)
user.update_inv_head() //So the mob overlay updates
if(on)
@@ -61,3 +67,166 @@
for(var/X in actions)
var/datum/action/A=X
A.UpdateButtonIcon()
+
+/obj/item/clothing/head/helmet/space/plasmaman/worn_overlays(isinhands, icon_file)
+ . = ..()
+ if(!isinhands && on)
+ . += mutable_appearance(icon_file, light_overlay)
+
+/obj/item/clothing/head/helmet/space/plasmaman/security
+ name = "security plasma envirosuit helmet"
+ desc = "A plasmaman containment helmet designed for security officers, protecting them from being flashed and burning alive, along-side other undesirables."
+ icon_state = "security_envirohelm"
+ item_state = "security_envirohelm"
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75)
+
+/obj/item/clothing/head/helmet/space/plasmaman/security/warden
+ name = "warden's plasma envirosuit helmet"
+ desc = "A plasmaman containment helmet designed for the warden, a pair of white stripes being added to differeciate them from other members of security."
+ icon_state = "warden_envirohelm"
+ item_state = "warden_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/security/hos
+ name = "head of security's plasma envirosuit helmet"
+ desc = "A plasmaman containment helmet designed for the head of security, manacing black with red stripes, to differenciate them from other members of security."
+ icon_state = "hos_envirohelm"
+ item_state = "hos_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/medical
+ name = "medical's plasma envirosuit helmet"
+ desc = "An envriohelmet designed for plasmaman medical doctors, having two stripes down it's length to denote as much."
+ icon_state = "doctor_envirohelm"
+ item_state = "doctor_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/cmo
+ name = "chief medical officer's plasma envirosuit helmet"
+ desc = "A blue and white envriohelmet designed for the chief medical officer."
+ icon_state = "cmo_envirohelm"
+ item_state = "cmo_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/genetics
+ name = "geneticist's plasma envirosuit helmet"
+ desc = "A plasmaman envirohelmet designed for geneticists."
+ icon_state = "geneticist_envirohelm"
+ item_state = "geneticist_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/viro
+ name = "virology plasma envirosuit helmet"
+ desc = "The helmet worn by the safest people on the station, those who are completely immune to the monstrosities they create."
+ icon_state = "virologist_envirohelm"
+ item_state = "virologist_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/chemist
+ name = "chemistry plasma envirosuit helmet"
+ desc = "A plasmaman envirosuit designed for chemists, two orange stripes going down it's face."
+ icon_state = "chemist_envirohelm"
+ item_state = "chemist_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/science
+ name = "science plasma envirosuit helmet"
+ desc = "A plasmaman envirohelmet designed for scientists."
+ icon_state = "scientist_envirohelm"
+ item_state = "scientist_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/rd
+ name = "research director's plasma envirosuit helmet"
+ desc = "A sturdier plasmaman envirohelmet designed for research directors."
+ icon_state = "rd_envirohelm"
+ item_state = "rd_envirohelm"
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 100, "acid" = 75)
+
+/obj/item/clothing/head/helmet/space/plasmaman/robotics
+ name = "robotics plasma envirosuit helmet"
+ desc = "A plasmaman envirohelmet designed for roboticists."
+ icon_state = "roboticist_envirohelm"
+ item_state = "roboticist_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/engineering
+ name = "engineering plasma envirosuit helmet"
+ desc = "A space-worthy helmet specially designed for engineer plasmamen, the usual purple stripes being replaced by engineering's orange."
+ icon_state = "engineer_envirohelm"
+ item_state = "engineer_envirohelm"
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 75)
+
+/obj/item/clothing/head/helmet/space/plasmaman/engineering/ce
+ name = "chief engineer's plasma envirosuit helmet"
+ desc = "A space-worthy helmet specially designed for the chief engineer, white with gold stripes designed for high visibility."
+ icon_state = "ce_envirohelm"
+ item_state = "ce_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/atmospherics
+ name = "atmospherics plasma envirosuit helmet"
+ desc = "A space-worthy helmet specially designed for atmos technician plasmamen, the usual purple stripes being replaced by engineering's blue."
+ icon_state = "atmos_envirohelm"
+ item_state = "atmos_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/cargo
+ name = "cargo plasma envirosuit helmet"
+ desc = "An plasmaman envirohelmet designed for cargo techs and quartermasters."
+ icon_state = "cargo_envirohelm"
+ item_state = "cargo_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/mining
+ name = "mining plasma envirosuit helmet"
+ desc = "A khaki helmet given to plasmamen miners operating on lavaland."
+ icon_state = "explorer_envirohelm"
+ item_state = "explorer_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/chaplain
+ name = "chaplain's plasma envirosuit helmet"
+ desc = "An envirohelmet specially designed for only the most pious of plasmamen."
+ icon_state = "chap_envirohelm"
+ item_state = "chap_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/white
+ name = "white plasma envirosuit helmet"
+ desc = "A generic white envirohelm."
+ icon_state = "white_envirohelm"
+ item_state = "white_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/hop
+ name = "head of personell's plasma envirosuit helmet"
+ desc = "A finely tailored azure envirohelm designed for head of personell."
+ icon_state = "hop_envirohelm"
+ item_state = "hop_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/captain
+ name = "captain's plasma envirosuit helmet"
+ desc = "A blue and gold envirohelm designed for the station's captain, nonetheless. Made of superior materials to protect them from the station hazards and more."
+ icon_state = "captain_envirohelm"
+ item_state = "captain_envirohelm"
+ armor = list("melee" = 10, "bullet" = 10, "laser" = 10, "energy" = 10, "bomb" = 10, "bio" = 100, "rad" = 10, "fire" = 100, "acid" = 85)
+
+/obj/item/clothing/head/helmet/space/plasmaman/curator
+ name = "curator's plasma envirosuit helmet"
+ desc = "A slight modification on a tradiational voidsuit helmet, this helmet was Nano-Trasen's first solution to the *logistical problems* that come with employing plasmamen. Despite their limitations, these helmets still see use by historian and old-styled plasmamen alike."
+ icon_state = "prototype_envirohelm"
+ item_state = "prototype_envirohelm"
+ light_overlay = null
+ actions_types = list()
+
+/obj/item/clothing/head/helmet/space/plasmaman/botany
+ name = "botany plasma envirosuit helmet"
+ desc = "A green and blue envirohelmet designating it's wearer as a botanist. While not specially designed for it, it would protect against minor planet-related injuries."
+ icon_state = "botany_envirohelm"
+ item_state = "botany_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/janitor
+ name = "janitor's plasma envirosuit helmet"
+ desc = "A grey helmet bearing a pair of purple stripes, designating the wearer as a janitor."
+ icon_state = "janitor_envirohelm"
+ item_state = "janitor_envirohelm"
+
+/obj/item/clothing/head/helmet/space/plasmaman/mime
+ name = "mime envirosuit helmet"
+ desc = "The make-up is painted on, it's a miracle it doesn't chip. It's not very colourful."
+ icon_state = "mime_envirohelm"
+ item_state = "mime_envirohelm"
+ light_overlay = "mime_envirohelm-light"
+
+/obj/item/clothing/head/helmet/space/plasmaman/clown
+ name = "clown envirosuit helmet"
+ desc = "The make-up is painted on, it's a miracle it doesn't chip. 'HONK!' "
+ icon_state = "clown_envirohelm"
+ item_state = "clown_envirohelm"
+ light_overlay = "clown_envirohelm-light"
diff --git a/code/modules/clothing/spacesuits/vg_spess.dm b/code/modules/clothing/spacesuits/vg_spess.dm
index e6b1c7a1ee..517539f3af 100644
--- a/code/modules/clothing/spacesuits/vg_spess.dm
+++ b/code/modules/clothing/spacesuits/vg_spess.dm
@@ -1,24 +1,5 @@
//VG Ports
-/obj/item/clothing/head/helmet/space/hardsuit/nazi
- name = "nazi hardhelmet"
- desc = "This is the face of das vaterland's top elite. Gas or energy are your only escapes."
- item_state = "hardsuit0-nazi"
- icon_state = "hardsuit0-nazi"
- armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 20)
- item_color = "nazi"
- icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
-
-/obj/item/clothing/suit/space/hardsuit/nazi
- name = "nazi hardsuit"
- desc = "The attire of a true krieger. All shall fall, and only das vaterland will remain."
- item_state = "hardsuit-nazi"
- icon_state = "hardsuit-nazi"
- slowdown = 1
- armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 35, bio = 100, rad = 20)
- allowed = list(/obj/item/gun,/obj/item/flashlight,/obj/item/tank,/obj/item/melee/)
- helmettype = /obj/item/clothing/head/helmet/space/hardsuit/nazi
- icon = 'modular_citadel/icons/obj/clothing/vg_clothes.dmi'
/obj/item/clothing/head/helmet/space/hardsuit/soviet
name = "soviet hardhelmet"
diff --git a/code/modules/clothing/suits/_suits.dm b/code/modules/clothing/suits/_suits.dm
index 3008043156..faec9e2f4c 100644
--- a/code/modules/clothing/suits/_suits.dm
+++ b/code/modules/clothing/suits/_suits.dm
@@ -31,12 +31,12 @@
adjusted = NORMAL_STYLE
if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None"))
- if(H.dna.features["taur"] in list("Naga", "Tentacle"))
+ if(H.dna.features["taur"] in GLOB.noodle_taurs)
taurmode = SNEK_TAURIC
if(tauric == TRUE)
center = TRUE
dimension_x = 64
- else if(H.dna.features["taur"] in list("Fox","Wolf","Otie","Drake","Lab","Shepherd","Husky","Eevee","Panther","Horse","Cow","Tiger","Deer"))
+ else if(H.dna.features["taur"] in GLOB.paw_taurs)
taurmode = PAW_TAURIC
if(tauric == TRUE)
center = TRUE
@@ -54,11 +54,11 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damaged[blood_overlay_type]")
- IF_HAS_BLOOD_DNA(src)
- if(taurmode >= SNEK_TAURIC)
- . += mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "[blood_overlay_type]blood")
+ if(blood_DNA)
+ if(tauric && taurmode >= SNEK_TAURIC)
+ . += mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
else
- . += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood")
+ . += mutable_appearance('icons/effects/blood.dmi', "[blood_overlay_type]blood", color = blood_DNA_to_color())
var/mob/living/carbon/human/M = loc
if(ishuman(M) && M.w_uniform)
var/obj/item/clothing/under/U = M.w_uniform
diff --git a/code/modules/clothing/suits/bio.dm b/code/modules/clothing/suits/bio.dm
index 5d0a9b9914..369ddba7b9 100644
--- a/code/modules/clothing/suits/bio.dm
+++ b/code/modules/clothing/suits/bio.dm
@@ -4,7 +4,7 @@
icon_state = "bio"
desc = "A hood that protects the head and face from biological contaminants."
permeability_coefficient = 0.01
- clothing_flags = THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT
+ clothing_flags = THICKMATERIAL | BLOCK_GAS_SMOKE_EFFECT | SNUG_FIT
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 60, "fire" = 30, "acid" = 100)
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDEFACE|HIDESNOUT
resistance_flags = ACID_PROOF
diff --git a/code/modules/clothing/suits/cloaks.dm b/code/modules/clothing/suits/cloaks.dm
index b8287c7f4c..be81374868 100644
--- a/code/modules/clothing/suits/cloaks.dm
+++ b/code/modules/clothing/suits/cloaks.dm
@@ -69,6 +69,7 @@
icon_state = "golhood"
desc = "A protective & concealing hood."
armor = list("melee" = 35, "bullet" = 10, "laser" = 25, "energy" = 10, "bomb" = 25, "bio" = 0, "rad" = 0, "fire" = 60, "acid" = 60)
+ clothing_flags = SNUG_FIT
flags_inv = HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR
/obj/item/clothing/suit/hooded/cloak/drake
@@ -88,6 +89,7 @@
icon_state = "dragon"
desc = "The skull of a dragon."
armor = list("melee" = 70, "bullet" = 30, "laser" = 50, "energy" = 40, "bomb" = 70, "bio" = 60, "rad" = 50, "fire" = 100, "acid" = 100)
+ clothing_flags = SNUG_FIT
heat_protection = HEAD
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
resistance_flags = FIRE_PROOF | ACID_PROOF
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 942fdaed73..bc885868c5 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -324,6 +324,23 @@
item_state = "officertanjacket"
body_parts_covered = CHEST|ARMS
+/obj/item/clothing/suit/ran
+ name = "Shikigami costume"
+ desc = "A costume that looks like a certain shikigami, is super fluffy."
+ icon_state = "ran_suit"
+ item_state = "ran_suit"
+ body_parts_covered = CHEST|GROIN|LEGS
+ flags_inv = HIDEJUMPSUIT|HIDETAUR
+ heat_protection = CHEST|GROIN|LEGS //fluffy tails!
+//2061
+
+/obj/item/clothing/head/ran
+ name = "Shikigami hat"
+ desc = "A hat that looks like it keeps any fluffy ears contained super warm, has little charms over it."
+ icon_state = "ran_hat"
+ item_state = "ran_hat"
+ flags_inv = HIDEEARS
+
/*
* Misc
*/
diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm
index 5d534e00a7..cc983dbb0f 100644
--- a/code/modules/clothing/suits/toggles.dm
+++ b/code/modules/clothing/suits/toggles.dm
@@ -23,7 +23,7 @@
/obj/item/clothing/suit/hooded/ui_action_click()
ToggleHood()
-/obj/item/clothing/suit/hooded/item_action_slot_check(slot, mob/user)
+/obj/item/clothing/suit/hooded/item_action_slot_check(slot, mob/user, datum/action/A)
if(slot == SLOT_WEAR_SUIT || slot == SLOT_NECK)
return 1
diff --git a/code/modules/clothing/suits/utility.dm b/code/modules/clothing/suits/utility.dm
index d003a20167..b98d8207d9 100644
--- a/code/modules/clothing/suits/utility.dm
+++ b/code/modules/clothing/suits/utility.dm
@@ -58,7 +58,7 @@
name = "bomb hood"
desc = "Use in case of bomb."
icon_state = "bombsuit"
- clothing_flags = THICKMATERIAL
+ clothing_flags = THICKMATERIAL | SNUG_FIT
armor = list("melee" = 20, "bullet" = 0, "laser" = 20,"energy" = 10, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50)
flags_inv = HIDEFACE|HIDEMASK|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
dynamic_hair_suffix = ""
@@ -123,14 +123,14 @@
name = "radiation hood"
icon_state = "rad"
desc = "A hood with radiation protective properties. The label reads, 'Made with lead. Please do not consume insulation.'"
- clothing_flags = THICKMATERIAL
+ clothing_flags = THICKMATERIAL|SNUG_FIT
flags_inv = HIDEMASK|HIDEEARS|HIDEFACE|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT
armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 60, "rad" = 100, "fire" = 30, "acid" = 30)
strip_delay = 60
equip_delay_other = 60
flags_cover = HEADCOVERSEYES | HEADCOVERSMOUTH
resistance_flags = NONE
- rad_flags = RAD_PROTECT_CONTENTS
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
mutantrace_variation = MUTANTRACE_VARIATION
/obj/item/clothing/suit/radiation
@@ -150,5 +150,5 @@
equip_delay_other = 60
flags_inv = HIDEJUMPSUIT|HIDETAUR
resistance_flags = NONE
- rad_flags = RAD_PROTECT_CONTENTS
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
tauric = TRUE //Citadel Add for tauric hardsuits
diff --git a/code/modules/clothing/suits/wiz_robe.dm b/code/modules/clothing/suits/wiz_robe.dm
index 9d1a47f231..93eb8181c7 100644
--- a/code/modules/clothing/suits/wiz_robe.dm
+++ b/code/modules/clothing/suits/wiz_robe.dm
@@ -7,6 +7,7 @@
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 20, "bio" = 20, "rad" = 20, "fire" = 100, "acid" = 100)
strip_delay = 50
equip_delay_other = 50
+ clothing_flags = SNUG_FIT
resistance_flags = FIRE_PROOF | ACID_PROOF
dog_fashion = /datum/dog_fashion/head/blue_wizard
diff --git a/code/modules/clothing/under/_under.dm b/code/modules/clothing/under/_under.dm
index c2c3f19b9d..eda0e31e93 100644
--- a/code/modules/clothing/under/_under.dm
+++ b/code/modules/clothing/under/_under.dm
@@ -22,8 +22,8 @@
if(!isinhands)
if(damaged_clothes)
. += mutable_appearance('icons/effects/item_damage.dmi', "damageduniform")
- IF_HAS_BLOOD_DNA(src)
- . += mutable_appearance('icons/effects/blood.dmi', "uniformblood")
+ if(blood_DNA)
+ . += mutable_appearance('icons/effects/blood.dmi', "uniformblood", color = blood_DNA_to_color())
if(accessory_overlay)
. += accessory_overlay
diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm
index 878030bc5d..706f7edb0a 100644
--- a/code/modules/clothing/under/accessories.dm
+++ b/code/modules/clothing/under/accessories.dm
@@ -12,7 +12,7 @@
var/datum/component/storage/detached_pockets
/obj/item/clothing/accessory/proc/attach(obj/item/clothing/under/U, user)
- GET_COMPONENT(storage, /datum/component/storage)
+ var/datum/component/storage/storage = GetComponent(/datum/component/storage)
if(storage)
if(SEND_SIGNAL(U, COMSIG_CONTAINS_STORAGE))
return FALSE
@@ -355,6 +355,14 @@
above_suit = TRUE
armor = list("melee" = 5, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 20, "bio" = 20, "rad" = 5, "fire" = 0, "acid" = 25)
+/obj/item/clothing/accessory/skullcodpiece/fake
+ name = "false codpiece"
+ desc = "A plastic ornament, intended to protect the important things in life. It's not very good at it."
+ icon_state = "skull"
+ item_color = "skull"
+ above_suit = TRUE
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
+
/////////////////////
//Synda Accessories//
/////////////////////
diff --git a/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
new file mode 100644
index 0000000000..74181b05eb
--- /dev/null
+++ b/code/modules/clothing/under/jobs/Plasmaman/civilian_service.dm
@@ -0,0 +1,100 @@
+/obj/item/clothing/under/plasmaman/cargo
+ name = "cargo plasma envirosuit"
+ desc = "A joint envirosuit used by plasmamen quartermasters and cargo techs alike, due to the logistical problems of differenciating the two with the length of their pant legs."
+ icon_state = "cargo_envirosuit"
+ item_state = "cargo_envirosuit"
+ item_color = "cargo_envirosuit"
+
+/obj/item/clothing/under/plasmaman/mining
+ name = "mining plasma envirosuit"
+ desc = "An air-tight khaki suit designed for operations on lavaland by plasmamen."
+ icon_state = "explorer_envirosuit"
+ item_state = "explorer_envirosuit"
+ item_color = "explorer_envirosuit"
+
+
+/obj/item/clothing/under/plasmaman/chef
+ name = "chef's plasma envirosuit"
+ desc = "A white plasmaman envirosuit designed for cullinary practices. One might question why a member of a species that doesn't need to eat would become a chef."
+ icon_state = "chef_envirosuit"
+ item_state = "chef_envirosuit"
+ item_color = "chef_envirosuit"
+
+/obj/item/clothing/under/plasmaman/enviroslacks
+ name = "enviroslacks"
+ desc = "The pet project of a particularly posh plasmaman, this custom suit was quickly appropriated by Nano-Trasen for it's detectives, lawyers, and bar-tenders alike."
+ icon_state = "enviroslacks"
+ item_state = "enviroslacks"
+ item_color = "enviroslacks"
+
+/obj/item/clothing/under/plasmaman/chaplain
+ name = "chaplain's plasma envirosuit"
+ desc = "An envirosuit specially designed for only the most pious of plasmamen."
+ icon_state = "chap_envirosuit"
+ item_state = "chap_envirosuit"
+ item_color = "chap_envirosuit"
+
+/obj/item/clothing/under/plasmaman/curator
+ name = "curator's plasma envirosuit"
+ desc = "Made out of a modified voidsuit, this suit was Nano-Trasen's first solution to the *logistical problems* that come with employing plasmamen. Due to the modifications, the suit is no longer space-worthy. Despite their limitations, these suits are still in used by historian and old-styled plasmamen alike."
+ icon_state = "prototype_envirosuit"
+ item_state = "prototype_envirosuit"
+ item_color = "prototype_envirosuit"
+
+/obj/item/clothing/under/plasmaman/janitor
+ name = "janitor's plasma envirosuit"
+ desc = "A grey and purple envirosuit designated for plasmamen janitors."
+ icon_state = "janitor_envirosuit"
+ item_state = "janitor_envirosuit"
+ item_color = "janitor_envirosuit"
+
+/obj/item/clothing/under/plasmaman/botany
+ name = "botany envirosuit"
+ desc = "A green and blue envirosuit designed to protect plasmamen from minor plant-related injuries."
+ icon_state = "botany_envirosuit"
+ item_state = "botany_envirosuit"
+ item_color = "botany_envirosuit"
+
+/obj/item/clothing/under/plasmaman/hop
+ name = "head of personell's envirosuit"
+ desc = "A prestigious azure envirosuit designed for head of personell."
+ icon_state = "hop_envirosuit"
+ item_state = "hop_envirosuit"
+ item_color = "hop_envirosuit"
+
+/obj/item/clothing/under/plasmaman/captain
+ name = "captain's envirosuit"
+ desc = "An expensive piece of plasmaman envirosuit fashion. guaranteed to keep you cool while the station goes down in fierceful fires."
+ icon_state = "captain_envirosuit"
+ item_state = "captain_envirosuit"
+ item_color = "captain_envirosuit"
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+
+/obj/item/clothing/under/plasmaman/mime
+ name = "mime envirosuit"
+ desc = "It's not very colourful."
+ icon_state = "mime_envirosuit"
+ item_state = "mime_envirosuit"
+ item_color = "mime_envirosuit"
+
+/obj/item/clothing/under/plasmaman/clown
+ name = "clown envirosuit"
+ desc = "'HONK!' "
+ icon_state = "clown_envirosuit"
+ item_state = "clown_envirosuit"
+ item_color = "clown_envirosuit"
+
+/obj/item/clothing/under/plasmaman/clown/Extinguish(mob/living/carbon/human/H)
+ if(!istype(H))
+ return
+
+ if(H.on_fire)
+ if(extinguishes_left)
+ if(next_extinguish > world.time)
+ return
+ next_extinguish = world.time + extinguish_cooldown
+ extinguishes_left--
+ H.visible_message("[H]'s suit spews out a tonne of space lube! ","Your suit spews out a tonne of space lube! ")
+ H.ExtinguishMob()
+ new /obj/effect/particle_effect/foam(loc) //Truely terrifying.
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/clothing/under/jobs/Plasmaman/engineering.dm b/code/modules/clothing/under/jobs/Plasmaman/engineering.dm
new file mode 100644
index 0000000000..1f381df4cf
--- /dev/null
+++ b/code/modules/clothing/under/jobs/Plasmaman/engineering.dm
@@ -0,0 +1,21 @@
+/obj/item/clothing/under/plasmaman/engineering
+ name = "engineering plasma envirosuit"
+ desc = "An air-tight suit designed to be used by plasmamen exployed as engineers, the usual purple stripes being replaced by engineer's orange. It protects the user from fire and acid damage."
+ icon_state = "engineer_envirosuit"
+ item_state = "engineer_envirosuit"
+ item_color = "engineer_envirosuit"
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 10, "fire" = 95, "acid" = 95)
+
+/obj/item/clothing/under/plasmaman/engineering/ce
+ name = "chief engineer's plasma envirosuit"
+ desc = "An advanced air-tight suit designed to be used by plasmamen chief engineers, complete with ornamental widgets and gizmo. It protects the user from fire and acid damage."
+ icon_state = "ce_envirosuit"
+ item_state = "ce_envirosuit"
+ item_color = "ce_envirosuit"
+
+/obj/item/clothing/under/plasmaman/atmospherics
+ name = "atmospherics plasma envirosuit"
+ desc = "An air-tight suit designed to be used by plasmamen exployed as atmos technicians, the usual purple stripes being replaced by atmos's blue."
+ icon_state = "atmos_envirosuit"
+ item_state = "atmos_envirosuit"
+ item_color = "atmos_envirosuit"
diff --git a/code/modules/clothing/under/jobs/Plasmaman/medsci.dm b/code/modules/clothing/under/jobs/Plasmaman/medsci.dm
new file mode 100644
index 0000000000..6106d785a9
--- /dev/null
+++ b/code/modules/clothing/under/jobs/Plasmaman/medsci.dm
@@ -0,0 +1,56 @@
+/obj/item/clothing/under/plasmaman/medical
+ name = "medical plasma envirosuit"
+ desc = "A suit designed for the station's more plasma-based doctors."
+ icon_state = "doctor_envirosuit"
+ item_state = "doctor_envirosuit"
+ item_color = "doctor_envirosuit"
+
+/obj/item/clothing/under/plasmaman/cmo
+ name = "chief medical officer's plasma envirosuit"
+ desc = "A suit designed for the station's most plasma-based chief medical officer, but not for their cat."
+ icon_state = "cmo_envirosuit"
+ item_state = "cmo_envirosuit"
+ item_color = "cmo_envirosuit"
+
+/obj/item/clothing/under/plasmaman/science
+ name = "science plasma envirosuit"
+ desc = "A plasmaman envirosuit designed for scientists."
+ icon_state = "scientist_envirosuit"
+ item_state = "scientist_envirosuit"
+ item_color = "scientist_envirosuit"
+
+/obj/item/clothing/under/plasmaman/rd
+ name = "research direactor's plasma envirosuit"
+ desc = "A plasmaman envirosuit designed for the research director to aid them in their job of directing research into the right direction."
+ icon_state = "rd_envirosuit"
+ item_state = "rd_envirosuit"
+ item_color = "rd_envirosuit"
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 10, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+
+/obj/item/clothing/under/plasmaman/robotics
+ name = "robotics plasma envirosuit"
+ desc = "A plasmaman envirosuit designed for roboticists."
+ icon_state = "roboticist_envirosuit"
+ item_state = "roboticist_envirosuit"
+ item_color = "roboticist_envirosuit"
+
+/obj/item/clothing/under/plasmaman/viro
+ name = "virology plasma envirosuit"
+ desc = "The suit worn by the safest people on the station, those who are completely immune to the monstrosities they create."
+ icon_state = "virologist_envirosuit"
+ item_state = "virologist_envirosuit"
+ item_color = "virologist_envirosuit"
+
+/obj/item/clothing/under/plasmaman/genetics
+ name = "genetics plasma envirosuit"
+ desc = "A plasmaman envirosuit designed for geneticists."
+ icon_state = "geneticist_envirosuit"
+ item_state = "geneticist_envirosuit"
+ item_color = "geneticist_envirosuit"
+
+/obj/item/clothing/under/plasmaman/chemist
+ name = "chemistry plasma envirosuit"
+ desc = "A plasmaman envirosuit designed for chemists."
+ icon_state = "chemist_envirosuit"
+ item_state = "chemist_envirosuit"
+ item_color = "chemist_envirosuit"
diff --git a/code/modules/clothing/under/jobs/Plasmaman/security.dm b/code/modules/clothing/under/jobs/Plasmaman/security.dm
new file mode 100644
index 0000000000..ff756e09fd
--- /dev/null
+++ b/code/modules/clothing/under/jobs/Plasmaman/security.dm
@@ -0,0 +1,21 @@
+/obj/item/clothing/under/plasmaman/security
+ name = "security plasma envirosuit"
+ desc = "A plasmaman containment suit designed for security officers, offering a limited amount of extra protection."
+ icon_state = "security_envirosuit"
+ item_state = "security_envirosuit"
+ item_color = "security_envirosuit"
+ armor = list("melee" = 10, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+
+/obj/item/clothing/under/plasmaman/security/warden
+ name = "warden plasma envirosuit"
+ desc = "A plasmaman containment suit designed for the warden, white stripes being added to differeciate them from other members of security."
+ icon_state = "warden_envirosuit"
+ item_state = "warden_envirosuit"
+ item_color = "warden_envirosuit"
+
+/obj/item/clothing/under/plasmaman/security/hos
+ name = "security plasma envirosuit"
+ desc = "A slick black and red plasmaman containment suit designed for the head of security, also called the LAW."
+ icon_state = "hos_envirosuit"
+ item_state = "hos_envirosuit"
+ item_color = "hos_envirosuit"
diff --git a/code/modules/clothing/under/miscellaneous.dm b/code/modules/clothing/under/miscellaneous.dm
index 616c00b6c1..6f188d513f 100644
--- a/code/modules/clothing/under/miscellaneous.dm
+++ b/code/modules/clothing/under/miscellaneous.dm
@@ -589,6 +589,7 @@
item_state = "b_suit"
item_color = "sailor"
can_adjust = FALSE
+
/obj/item/clothing/under/plasmaman
name = "plasma envirosuit"
desc = "A special containment suit that allows plasma-based lifeforms to exist safely in an oxygenated environment, and automatically extinguishes them in a crisis. Despite being airtight, it's not spaceworthy."
@@ -596,12 +597,15 @@
item_state = "plasmaman"
item_color = "plasmaman"
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 100, "rad" = 0, "fire" = 95, "acid" = 95)
+ slowdown = 1
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
+ mutantrace_variation = NO_MUTANTRACE_VARIATION
can_adjust = FALSE
strip_delay = 80
var/next_extinguish = 0
var/extinguish_cooldown = 100
var/extinguishes_left = 5
+
/obj/item/clothing/under/plasmaman/examine(mob/user)
..()
to_chat(user, "There are [extinguishes_left] extinguisher charges left in this suit. ")
@@ -618,6 +622,7 @@
H.ExtinguishMob()
new /obj/effect/particle_effect/water(get_turf(H))
return 0
+
/obj/item/clothing/under/plasmaman/attackby(obj/item/E, mob/user, params)
..()
if (istype(E, /obj/item/extinguisher_refill))
@@ -631,11 +636,13 @@
return
return
return
+
/obj/item/extinguisher_refill
name = "envirosuit extinguisher cartridge"
desc = "A cartridge loaded with a compressed extinguisher mix, used to refill the automatic extinguisher on plasma envirosuits."
icon_state = "plasmarefill"
icon = 'icons/obj/device.dmi'
+
/obj/item/clothing/under/rank/security/navyblue/russian
name = "\improper Russian officer's uniform"
desc = "The latest in fashionable russian outfits."
@@ -708,8 +715,9 @@
name = "gear harness"
desc = "A simple, inconspicuous harness replacement for a jumpsuit."
icon_state = "gear_harness"
- item_state = "gear_harness" //We dont use golem do to being a item, item without faces making it default to error suit sprites.
+ item_state = "gear_harness"
body_parts_covered = CHEST|GROIN
+ can_adjust = FALSE
/obj/item/clothing/under/durathread
name = "durathread jumpsuit"
diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm
index 7ae1c956c9..2987b52338 100644
--- a/code/modules/crafting/recipes.dm
+++ b/code/modules/crafting/recipes.dm
@@ -1,4 +1,3 @@
-
/datum/crafting_recipe
var/name = "" //in-game display name
var/reqs[] = list() //type paths of items consumed associated with how many are needed
@@ -9,943 +8,4 @@
var/chem_catalysts[] = list() //like tools but for reagents
var/category = CAT_NONE //where it shows up in the crafting UI
var/subcategory = CAT_NONE
- var/always_availible = TRUE //Set to FALSE if it needs to be learned first.
-
-/datum/crafting_recipe/pin_removal
- name = "Pin Removal"
- result = /obj/item/gun
- reqs = list(/obj/item/gun = 1)
- parts = list(/obj/item/gun = 1)
- tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- time = 50
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/IED
- name = "IED"
- result = /obj/item/grenade/iedcasing
- reqs = list(/datum/reagent/fuel = 50,
- /obj/item/stack/cable_coil = 1,
- /obj/item/assembly/igniter = 1,
- /obj/item/reagent_containers/food/drinks/soda_cans = 1)
- parts = list(/obj/item/reagent_containers/food/drinks/soda_cans = 1)
- time = 15
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/lance
- name = "Explosive Lance (Grenade)"
- result = /obj/item/twohanded/spear
- reqs = list(/obj/item/twohanded/spear = 1,
- /obj/item/grenade = 1)
- parts = list(/obj/item/twohanded/spear = 1,
- /obj/item/grenade = 1)
- time = 15
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/strobeshield
- name = "Strobe Shield"
- result = /obj/item/assembly/flash/shield
- reqs = list(/obj/item/wallframe/flasher = 1,
- /obj/item/assembly/flash/handheld = 1,
- /obj/item/shield/riot = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/makeshiftshield
- name = "Makeshift Metal Shield"
- result = /obj/item/shield/makeshift
- reqs = list(/obj/item/stack/cable_coil = 30,
- /obj/item/stack/sheet/metal = 10,
- /obj/item/stack/sheet/cloth = 2,
- /obj/item/stack/sheet/leather = 3)
- tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- time = 100
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/molotov
- name = "Molotov"
- result = /obj/item/reagent_containers/food/drinks/bottle/molotov
- reqs = list(/obj/item/reagent_containers/rag = 1,
- /obj/item/reagent_containers/food/drinks/bottle = 1)
- parts = list(/obj/item/reagent_containers/food/drinks/bottle = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/stunprod
- name = "Stunprod"
- result = /obj/item/melee/baton/cattleprod
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/stack/rods = 1,
- /obj/item/assembly/igniter = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/teleprod
- name = "Teleprod"
- result = /obj/item/melee/baton/cattleprod/teleprod
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/stack/rods = 1,
- /obj/item/assembly/igniter = 1,
- /obj/item/stack/ore/bluespace_crystal = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/bola
- name = "Bola"
- result = /obj/item/restraints/legcuffs/bola
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/stack/sheet/metal = 6)
- time = 20//15 faster than crafting them by hand!
- category= CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/tailclub
- name = "Tail Club"
- result = /obj/item/tailclub
- reqs = list(/obj/item/organ/tail/lizard = 1,
- /obj/item/stack/sheet/metal = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/tailwhip
- name = "Liz O' Nine Tails"
- result = /obj/item/melee/chainofcommand/tailwhip
- reqs = list(/obj/item/organ/tail/lizard = 1,
- /obj/item/stack/cable_coil = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/catwhip
- name = "Cat O' Nine Tails"
- result = /obj/item/melee/chainofcommand/tailwhip/kitty
- reqs = list(/obj/item/organ/tail/cat = 1,
- /obj/item/stack/cable_coil = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/minigun
- name = "Laser Minigun"
- result = /obj/item/minigunpack2
- reqs = list(/obj/item/gun/energy/laser/carbine = 3,
- /obj/item/stack/sheet/plasteel = 5,
- /obj/item/stack/cable_coil = 30,
- /obj/item/stock_parts/cell/bluespace = 2)
- tools = list(TOOL_WIRECUTTER, TOOL_SCREWDRIVER, TOOL_WELDER)
- time = 150
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/ed209
- name = "ED209"
- result = /mob/living/simple_animal/bot/ed209
- reqs = list(/obj/item/robot_suit = 1,
- /obj/item/clothing/head/helmet = 1,
- /obj/item/clothing/suit/armor/vest = 1,
- /obj/item/bodypart/l_leg/robot = 1,
- /obj/item/bodypart/r_leg/robot = 1,
- /obj/item/stack/sheet/metal = 1,
- /obj/item/stack/cable_coil = 1,
- /obj/item/gun/energy/e_gun/advtaser = 1,
- /obj/item/stock_parts/cell = 1,
- /obj/item/assembly/prox_sensor = 1)
- tools = list(TOOL_WELDER, TOOL_SCREWDRIVER)
- time = 60
- category = CAT_ROBOT
-
-/datum/crafting_recipe/secbot
- name = "Secbot"
- result = /mob/living/simple_animal/bot/secbot
- reqs = list(/obj/item/assembly/signaler = 1,
- /obj/item/clothing/head/helmet/sec = 1,
- /obj/item/melee/baton = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bodypart/r_arm/robot = 1)
- tools = list(TOOL_WELDER)
- time = 60
- category = CAT_ROBOT
-
-/datum/crafting_recipe/cleanbot
- name = "Cleanbot"
- result = /mob/living/simple_animal/bot/cleanbot
- reqs = list(/obj/item/reagent_containers/glass/bucket = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bodypart/r_arm/robot = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/floorbot
- name = "Floorbot"
- result = /mob/living/simple_animal/bot/floorbot
- reqs = list(/obj/item/storage/toolbox/mechanical = 1,
- /obj/item/stack/tile/plasteel = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bodypart/r_arm/robot = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/medbot
- name = "Medbot"
- result = /mob/living/simple_animal/bot/medbot
- reqs = list(/obj/item/healthanalyzer = 1,
- /obj/item/storage/firstaid = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bodypart/r_arm/robot = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/honkbot
- name = "Honkbot"
- result = /mob/living/simple_animal/bot/honkbot
- reqs = list(/obj/item/storage/box/clown = 1,
- /obj/item/bodypart/r_arm/robot = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/bikehorn/ = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/Firebot
- name = "Firebot"
- result = /mob/living/simple_animal/bot/firebot
- reqs = list(/obj/item/extinguisher = 1,
- /obj/item/bodypart/r_arm/robot = 1,
- /obj/item/assembly/prox_sensor = 1,
- /obj/item/clothing/head/hardhat/red = 1)
- time = 40
- category = CAT_ROBOT
-
-/datum/crafting_recipe/potatos
- name = "Potat-OS"
- reqs = list(/obj/item/stack/cable_coil = 1, /obj/item/stack/rods = 1, /obj/item/reagent_containers/food/snacks/grown/potato = 1, /obj/item/aicard = 1 )
- result = /obj/item/aicard/potato
- category = CAT_ROBOT
-
-/datum/crafting_recipe/improvised_pneumatic_cannon //Pretty easy to obtain but
- name = "Pneumatic Cannon"
- result = /obj/item/pneumatic_cannon/ghetto
- tools = list(TOOL_WELDER, TOOL_WRENCH)
- reqs = list(/obj/item/stack/sheet/metal = 4,
- /obj/item/stack/packageWrap = 8,
- /obj/item/pipe = 2)
- time = 300
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/flamethrower
- name = "Flamethrower"
- result = /obj/item/flamethrower
- reqs = list(/obj/item/weldingtool = 1,
- /obj/item/assembly/igniter = 1,
- /obj/item/stack/rods = 1)
- parts = list(/obj/item/assembly/igniter = 1,
- /obj/item/weldingtool = 1)
- tools = list(TOOL_SCREWDRIVER)
- time = 10
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/meteorslug
- name = "Meteorslug Shell"
- result = /obj/item/ammo_casing/shotgun/meteorslug
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /obj/item/rcd_ammo = 1,
- /obj/item/stock_parts/manipulator = 2)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/pulseslug
- name = "Pulse Slug Shell"
- result = /obj/item/ammo_casing/shotgun/pulseslug
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /obj/item/stock_parts/capacitor/adv = 2,
- /obj/item/stock_parts/micro_laser/ultra = 1)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/dragonsbreath
- name = "Dragonsbreath Shell"
- result = /obj/item/ammo_casing/shotgun/dragonsbreath
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1, /datum/reagent/phosphorus = 5)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/frag12
- name = "FRAG-12 Shell"
- result = /obj/item/ammo_casing/shotgun/frag12
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /datum/reagent/glycerol = 5,
- /datum/reagent/toxin/acid = 5,
- /datum/reagent/toxin/acid/fluacid = 5)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/ionslug
- name = "Ion Scatter Shell"
- result = /obj/item/ammo_casing/shotgun/ion
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /obj/item/stock_parts/micro_laser/ultra = 1,
- /obj/item/stock_parts/subspace/crystal = 1)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/improvisedslug
- name = "Improvised Shotgun Shell"
- result = /obj/item/ammo_casing/shotgun/improvised
- reqs = list(/obj/item/grenade/chem_grenade = 1,
- /obj/item/stack/sheet/metal = 1,
- /obj/item/stack/cable_coil = 1,
- /datum/reagent/fuel = 10)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/laserslug
- name = "Scatter Laser Shell"
- result = /obj/item/ammo_casing/shotgun/laserslug
- reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
- /obj/item/stock_parts/capacitor/adv = 1,
- /obj/item/stock_parts/micro_laser/high = 1)
- tools = list(TOOL_SCREWDRIVER)
- time = 5
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/ishotgun
- name = "Improvised Shotgun"
- result = /obj/item/gun/ballistic/revolver/doublebarrel/improvised
- reqs = list(/obj/item/weaponcrafting/receiver = 1,
- /obj/item/pipe = 1,
- /obj/item/weaponcrafting/stock = 1,
- /obj/item/stack/packageWrap = 5)
- tools = list(TOOL_SCREWDRIVER)
- time = 100
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/irifle
- name = "Improvised Rifle(7.62mm)"
- result = /obj/item/gun/ballistic/shotgun/boltaction/improvised
- reqs = list(/obj/item/weaponcrafting/receiver = 1,
- /obj/item/pipe = 2,
- /obj/item/weaponcrafting/stock = 1,
- /obj/item/stack/packageWrap = 5)
- tools = list(TOOL_SCREWDRIVER)
- time = 100
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/chainsaw
- name = "Chainsaw"
- result = /obj/item/twohanded/required/chainsaw
- reqs = list(/obj/item/circular_saw = 1,
- /obj/item/stack/cable_coil = 3,
- /obj/item/stack/sheet/plasteel = 5)
- tools = list(TOOL_WELDER)
- time = 50
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/spear
- name = "Spear"
- result = /obj/item/twohanded/spear
- reqs = list(/obj/item/restraints/handcuffs/cable = 1,
- /obj/item/shard = 1,
- /obj/item/stack/rods = 1)
- parts = list(/obj/item/shard = 1)
- time = 40
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/spooky_camera
- name = "Camera Obscura"
- result = /obj/item/camera/spooky
- time = 15
- reqs = list(/obj/item/camera = 1,
- /datum/reagent/water/holywater = 10)
- parts = list(/obj/item/camera = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/skateboard
- name = "Skateboard"
- result = /obj/vehicle/ridden/scooter/skateboard
- time = 60
- reqs = list(/obj/item/stack/sheet/metal = 5,
- /obj/item/stack/rods = 10)
- category = CAT_MISC
-
-/datum/crafting_recipe/scooter
- name = "Scooter"
- result = /obj/vehicle/ridden/scooter
- time = 65
- reqs = list(/obj/item/stack/sheet/metal = 5,
- /obj/item/stack/rods = 12)
- category = CAT_MISC
-
-/datum/crafting_recipe/mousetrap
- name = "Mouse Trap"
- result = /obj/item/assembly/mousetrap
- time = 10
- reqs = list(/obj/item/stack/sheet/cardboard = 1,
- /obj/item/stack/rods = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/papersack
- name = "Paper Sack"
- result = /obj/item/storage/box/papersack
- time = 10
- reqs = list(/obj/item/paper = 5)
- category = CAT_MISC
-
-/datum/crafting_recipe/flashlight_eyes
- name = "Flashlight Eyes"
- result = /obj/item/organ/eyes/robotic/flashlight
- time = 10
- reqs = list(
- /obj/item/flashlight = 2,
- /obj/item/restraints/handcuffs/cable = 1
- )
- category = CAT_MISC
-
-/datum/crafting_recipe/paperframes
- name = "Paper Frames"
- result = /obj/item/stack/sheet/paperframes/five
- time = 10
- reqs = list(/obj/item/stack/sheet/mineral/wood = 5, /obj/item/paper = 20)
- category = CAT_MISC
-
-/datum/crafting_recipe/naturalpaper
- name = "Hand-Pressed Paper"
- time = 30
- reqs = list(/datum/reagent/water = 50, /obj/item/stack/sheet/mineral/wood = 1)
- tools = list(/obj/item/hatchet)
- result = /obj/item/paper_bin/bundlenatural
- category = CAT_MISC
-
-/datum/crafting_recipe/toysword
- name = "Toy Sword"
- reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
- result = /obj/item/toy/sword
- category = CAT_MISC
-
-/datum/crafting_recipe/blackcarpet
- name = "Black Carpet"
- reqs = list(/obj/item/stack/tile/carpet = 50, /obj/item/toy/crayon/black = 1)
- result = /obj/item/stack/tile/carpet/black/fifty
- category = CAT_MISC
-
-/datum/crafting_recipe/showercurtain
- name = "Shower Curtains"
- reqs = list(/obj/item/stack/sheet/cloth = 2, /obj/item/stack/sheet/plastic = 2, /obj/item/stack/rods = 1)
- result = /obj/structure/curtain
- category = CAT_MISC
-
-/datum/crafting_recipe/extendohand
- name = "Extendo-Hand"
- reqs = list(/obj/item/bodypart/r_arm/robot = 1, /obj/item/clothing/gloves/boxing = 1)
- result = /obj/item/extendohand
- category = CAT_MISC
-
-/datum/crafting_recipe/bluespacehonker
- name = "Bluespace Bike horn"
- result = /obj/item/bikehorn/bluespacehonker
- time = 10
- reqs = list(/obj/item/stack/ore/bluespace_crystal = 1,
- /obj/item/toy/crayon/blue = 1,
- /obj/item/bikehorn = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/toyneb
- name = "Non-Euplastic Blade"
- reqs = list(/obj/item/light/tube = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
- result = /obj/item/toy/sword/cx
- category = CAT_MISC
-
-/datum/crafting_recipe/chemical_payload
- name = "Chemical Payload (C4)"
- result = /obj/item/bombcore/chemical
- reqs = list(
- /obj/item/stock_parts/matter_bin = 1,
- /obj/item/grenade/plastic/c4 = 1,
- /obj/item/grenade/chem_grenade = 2
- )
- parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
- time = 30
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/chemical_payload2
- name = "Chemical Payload (Gibtonite)"
- result = /obj/item/bombcore/chemical
- reqs = list(
- /obj/item/stock_parts/matter_bin = 1,
- /obj/item/twohanded/required/gibtonite = 1,
- /obj/item/grenade/chem_grenade = 2
- )
- parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
- time = 50
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/bonearmor
- name = "Bone Armor"
- result = /obj/item/clothing/suit/armor/bone
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 6)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonetalisman
- name = "Bone Talisman"
- result = /obj/item/clothing/accessory/talisman
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2,
- /obj/item/stack/sheet/sinew = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonecodpiece
- name = "Skull Codpiece"
- result = /obj/item/clothing/accessory/skullcodpiece
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bracers
- name = "Bone Bracers"
- result = /obj/item/clothing/gloves/bracer
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2,
- /obj/item/stack/sheet/sinew = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/skullhelm
- name = "Skull Helmet"
- result = /obj/item/clothing/head/helmet/skull
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 4)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/goliathcloak
- name = "Goliath Cloak"
- result = /obj/item/clothing/suit/hooded/cloak/goliath
- time = 50
- reqs = list(/obj/item/stack/sheet/leather = 2,
- /obj/item/stack/sheet/sinew = 2,
- /obj/item/stack/sheet/animalhide/goliath_hide = 2) //it takes 4 goliaths to make 1 cloak if the plates are skinned
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/drakecloak
- name = "Ash Drake Armour"
- result = /obj/item/clothing/suit/hooded/cloak/drake
- time = 60
- reqs = list(/obj/item/stack/sheet/bone = 10,
- /obj/item/stack/sheet/sinew = 2,
- /obj/item/stack/sheet/animalhide/ashdrake = 5)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonebag
- name = "Bone Satchel"
- result = /obj/item/storage/backpack/satchel/bone
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 3,
- /obj/item/stack/sheet/sinew = 2)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/gold_horn
- name = "Golden Bike Horn"
- result = /obj/item/bikehorn/golden
- time = 20
- reqs = list(/obj/item/stack/sheet/mineral/bananium = 5,
- /obj/item/bikehorn = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/bonedagger
- name = "Bone Dagger"
- result = /obj/item/kitchen/knife/combat/bone
- time = 20
- reqs = list(/obj/item/stack/sheet/bone = 2)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonespear
- name = "Bone Spear"
- result = /obj/item/twohanded/bonespear
- time = 30
- reqs = list(/obj/item/stack/sheet/bone = 4,
- /obj/item/stack/sheet/sinew = 1)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/boneaxe
- name = "Bone Axe"
- result = /obj/item/twohanded/fireaxe/boneaxe
- time = 50
- reqs = list(/obj/item/stack/sheet/bone = 6,
- /obj/item/stack/sheet/sinew = 3)
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/bonfire
- name = "Bonfire"
- time = 60
- reqs = list(/obj/item/grown/log = 5)
- result = /obj/structure/bonfire
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/headpike
- name = "Spike Head (Glass Spear)"
- time = 65
- reqs = list(/obj/item/twohanded/spear = 1,
- /obj/item/bodypart/head = 1)
- parts = list(/obj/item/bodypart/head = 1,
- /obj/item/twohanded/spear = 1)
- result = /obj/structure/headpike
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/headpikebone
- name = "Spike Head (Bone Spear)"
- time = 65
- reqs = list(/obj/item/twohanded/bonespear = 1,
- /obj/item/bodypart/head = 1)
- parts = list(/obj/item/bodypart/head = 1,
- /obj/item/twohanded/bonespear = 1)
- result = /obj/structure/headpike/bone
- category = CAT_PRIMAL
-
-/datum/crafting_recipe/smallcarton
- name = "Small Carton"
- result = /obj/item/reagent_containers/food/drinks/sillycup/smallcarton
- time = 10
- reqs = list(/obj/item/stack/sheet/cardboard = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/pressureplate
- name = "Pressure Plate"
- result = /obj/item/pressure_plate
- time = 5
- reqs = list(/obj/item/stack/sheet/metal = 1,
- /obj/item/stack/tile/plasteel = 1,
- /obj/item/stack/cable_coil = 2,
- /obj/item/assembly/igniter = 1)
- category = CAT_MISC
-
-
-/datum/crafting_recipe/wheelchair
- name = "Wheelchair"
- result = /obj/vehicle/ridden/wheelchair
- reqs = list(/obj/item/stack/sheet/plasteel = 2,
- /obj/item/stack/rods = 8)
- time = 100
- category = CAT_MISC
-
-/datum/crafting_recipe/rcl
- name = "Makeshift Rapid Cable Layer"
- result = /obj/item/twohanded/rcl/ghetto
- time = 40
- tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
- reqs = list(/obj/item/stack/sheet/metal = 15)
- category = CAT_MISC
-
-/datum/crafting_recipe/mummy
- name = "Mummification Bandages (Mask)"
- result = /obj/item/clothing/mask/mummy
- time = 10
- tools = list(/obj/item/nullrod/egyptian)
- reqs = list(/obj/item/stack/sheet/cloth = 2)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/mummy/body
- name = "Mummification Bandages (Body)"
- result = /obj/item/clothing/under/mummy
- reqs = list(/obj/item/stack/sheet/cloth = 5)
-
-/datum/crafting_recipe/guillotine
- name = "Guillotine"
- result = /obj/structure/guillotine
- time = 150 // Building a functioning guillotine takes time
- reqs = list(/obj/item/stack/sheet/plasteel = 3,
- /obj/item/stack/sheet/mineral/wood = 20,
- /obj/item/stack/cable_coil = 10)
- tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
- category = CAT_MISC
-
-/datum/crafting_recipe/femur_breaker
- name = "Femur Breaker"
- result = /obj/structure/femur_breaker
- time = 150
- reqs = list(/obj/item/stack/sheet/metal = 20,
- /obj/item/stack/cable_coil = 30)
- tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
- category = CAT_MISC
-
-/datum/crafting_recipe/lizardhat
- name = "Lizard Cloche Hat"
- result = /obj/item/clothing/head/lizard
- time = 10
- reqs = list(/obj/item/organ/tail/lizard = 1)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/lizardhat_alternate
- name = "Lizard Cloche Hat"
- result = /obj/item/clothing/head/lizard
- time = 10
- reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/kittyears
- name = "Kitty Ears"
- result = /obj/item/clothing/head/kitty/genuine
- time = 10
- reqs = list(/obj/item/organ/tail/cat = 1,
- /obj/item/organ/ears/cat = 1)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/hudsunsec
- name = "Security HUDsunglasses"
- result = /obj/item/clothing/glasses/hud/security/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/security = 1,
- /obj/item/clothing/glasses/sunglasses = 1,
- /obj/item/stack/cable_coil = 5)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/hudsunsecremoval
- name = "Security HUD removal"
- result = /obj/item/clothing/glasses/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses = 1)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/hudsunmed
- name = "Medical HUDsunglasses"
- result = /obj/item/clothing/glasses/hud/health/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/health = 1,
- /obj/item/clothing/glasses/sunglasses = 1,
- /obj/item/stack/cable_coil = 5)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/hudsunmedremoval
- name = "Medical HUD removal"
- result = /obj/item/clothing/glasses/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/hud/health/sunglasses = 1)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/beergoggles
- name = "Beer Goggles"
- result = /obj/item/clothing/glasses/sunglasses/reagent
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/science = 1,
- /obj/item/clothing/glasses/sunglasses = 1,
- /obj/item/stack/cable_coil = 5)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/beergogglesremoval
- name = "Beer Goggles removal"
- result = /obj/item/clothing/glasses/sunglasses
- time = 20
- tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
- reqs = list(/obj/item/clothing/glasses/sunglasses/reagent = 1)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/ghostsheet
- name = "Ghost Sheet"
- result = /obj/item/clothing/suit/ghost_sheet
- time = 5
- tools = list(TOOL_WIRECUTTER)
- reqs = list(/obj/item/bedsheet = 1)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/briefcase
- name = "Hand made Briefcase"
- result = /obj/item/storage/briefcase/crafted
- time = 35
- tools = list(TOOL_WIRECUTTER)
- reqs = list(/obj/item/stack/sheet/cardboard = 1,
- /obj/item/stack/sheet/cloth = 2,
- /obj/item/stack/sheet/leather = 5)
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/aitater
- name = "intelliTater"
- result = /obj/item/aicard/aitater
- time = 30
- reqs = list(/obj/item/aicard = 1,
- /obj/item/reagent_containers/food/snacks/grown/potato = 1)
- category = CAT_MISC
-
-/datum/crafting_recipe/paperwork
- name = "Filed Paper Work"
- result = /obj/item/folder/paperwork_correct
- time = 60 //Takes time for people to file and complete paper work!
- reqs = list(/obj/item/pen = 1,
- /obj/item/folder/paperwork = 2)
- category = CAT_MISC
-
-/datum/crafting_recipe/ghettojetpack
- name = "Improvised Jetpack"
- result = /obj/item/tank/jetpack/improvised
- time = 30
- reqs = list(/obj/item/tank/internals/oxygen = 2,
- /obj/item/extinguisher = 1,
- /obj/item/pipe = 3,
- /obj/item/stack/cable_coil = 30)
- category = CAT_MISC
- tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER)
-
-/datum/crafting_recipe/goldenbox
- name = "Gold Plated Toolbox"
- result = /obj/item/storage/toolbox/gold_fake
- reqs = list(/obj/item/stack/sheet/cardboard = 1, //so we dont null items in crafting
- /obj/item/stack/cable_coil = 10,
- /obj/item/stack/sheet/mineral/gold = 1,
- /obj/item/stock_parts/cell = 1,
- /datum/reagent/water = 15)
- time = 40
- category = CAT_MISC
-
-/datum/crafting_recipe/bronze_driver
- name = "Bronze Plated Screwdriver"
- result = /obj/item/screwdriver/bronze
- reqs = list(/obj/item/screwdriver = 1,
- /obj/item/stack/cable_coil = 10,
- /obj/item/stack/tile/bronze = 1,
- /datum/reagent/water = 15)
- time = 40
- category = CAT_MISC
-
-/datum/crafting_recipe/bronze_welder
- name = "Bronze Plated Welding Tool"
- result = /obj/item/weldingtool/bronze
- reqs = list(/obj/item/weldingtool = 1,
- /obj/item/stack/cable_coil = 10,
- /obj/item/stack/tile/bronze = 1,
- /datum/reagent/water = 15)
- time = 40
- category = CAT_MISC
-
-/datum/crafting_recipe/bronze_wirecutters
- name = "Bronze Plated Wirecutters"
- result = /obj/item/wirecutters/bronze
- reqs = list(/obj/item/wirecutters = 1,
- /obj/item/stack/cable_coil = 10,
- /obj/item/stack/tile/bronze = 1,
- /datum/reagent/water = 15)
- time = 40
- category = CAT_MISC
-
-/datum/crafting_recipe/bronze_crowbar
- name = "Bronze Plated Crowbar"
- result = /obj/item/crowbar/bronze
- reqs = list(/obj/item/crowbar = 1,
- /obj/item/stack/cable_coil = 10,
- /obj/item/stack/tile/bronze = 1,
- /datum/reagent/water = 15)
- time = 40
- category = CAT_MISC
-
-/datum/crafting_recipe/bronze_wrench
- name = "Bronze Plated Wrench"
- result = /obj/item/wrench/bronze
- reqs = list(/obj/item/wrench = 1,
- /obj/item/stack/cable_coil = 10,
- /obj/item/stack/tile/bronze = 1,
- /datum/reagent/water = 15)
- time = 40
- category = CAT_MISC
-
-/datum/crafting_recipe/smartdart
- name = "Medical smartdart"
- result = /obj/item/reagent_containers/syringe/dart
- reqs = list(/obj/item/stack/sheet/metal = 1,
- /obj/item/stack/sheet/glass = 1,
- /obj/item/stack/sheet/plastic = 1)
- time = 10
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/medolier
- name = "Medolier"
- result = /obj/item/storage/belt/medolier
- reqs = list(/obj/item/stack/sheet/metal = 2,
- /obj/item/stack/sheet/cloth = 3,
- /obj/item/stack/sheet/plastic = 4)
- time = 30
- category = CAT_WEAPONRY
- subcategory = CAT_AMMO
-
-/datum/crafting_recipe/smartdartgun
- name = "Smart dartgun"
- result = /obj/item/gun/syringe/dart
- reqs = list(/obj/item/stack/sheet/metal = 15,
- /obj/item/stack/sheet/glass = 10,
- /obj/item/tank/internals = 1,
- /obj/item/reagent_containers/glass/beaker = 1,
- /obj/item/stack/sheet/plastic = 10,
- /obj/item/stack/cable_coil = 2)
- time = 150 //It's a gun
- category = CAT_WEAPONRY
- subcategory = CAT_WEAPON
-
-/datum/crafting_recipe/durathread_duffelbag
- name = "Durathread Dufflebag"
- result = /obj/item/storage/backpack/duffelbag/durathread
- reqs = list(/obj/item/stack/sheet/durathread = 7,
- /obj/item/stack/sheet/leather = 3)
- time = 70
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/durathread_toolbelt
- name = "Durathread Toolbelt"
- result = /obj/item/storage/belt/durathread
- reqs = list(/obj/item/stack/sheet/durathread = 5,
- /obj/item/stack/sheet/leather = 1)
- time = 30
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/durathread_bandolier
- name = "Durathread Bandolier"
- result = /obj/item/storage/belt/bandolier/durathread
- reqs = list(/obj/item/stack/sheet/durathread = 6,
- /obj/item/stack/sheet/leather = 2)
- time = 50
- category = CAT_CLOTHING
-
- /datum/crafting_recipe/durathread_helmet
- name = "Makeshift Durathread Helmet"
- result = /obj/item/clothing/head/helmet/durathread
- reqs = list(/obj/item/stack/sheet/durathread = 4,
- /obj/item/stack/sheet/leather = 2)
- time = 30
- category = CAT_CLOTHING
-
-/datum/crafting_recipe/durathread_vest
- name = "Makeshift Durathread Armour"
- result = /obj/item/clothing/suit/armor/vest/durathread
- reqs = list(/obj/item/stack/sheet/durathread = 6,
- /obj/item/stack/sheet/leather = 3)
- time = 50
- category = CAT_CLOTHING
-
+ var/always_availible = TRUE //Set to FALSE if it needs to be learned first.
\ No newline at end of file
diff --git a/code/modules/crafting/recipes/recipes_clothing.dm b/code/modules/crafting/recipes/recipes_clothing.dm
new file mode 100644
index 0000000000..f48ee87316
--- /dev/null
+++ b/code/modules/crafting/recipes/recipes_clothing.dm
@@ -0,0 +1,160 @@
+/datum/crafting_recipe/mummy
+ name = "Mummification Bandages (Mask)"
+ result = /obj/item/clothing/mask/mummy
+ time = 10
+ tools = list(/obj/item/nullrod/egyptian)
+ reqs = list(/obj/item/stack/sheet/cloth = 2)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/mummy/body
+ name = "Mummification Bandages (Body)"
+ result = /obj/item/clothing/under/mummy
+ reqs = list(/obj/item/stack/sheet/cloth = 5)
+
+/datum/crafting_recipe/lizardhat
+ name = "Lizard Cloche Hat"
+ result = /obj/item/clothing/head/lizard
+ time = 10
+ reqs = list(/obj/item/organ/tail/lizard = 1)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/lizardhat_alternate
+ name = "Lizard Cloche Hat"
+ result = /obj/item/clothing/head/lizard
+ time = 10
+ reqs = list(/obj/item/stack/sheet/animalhide/lizard = 1)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/kittyears
+ name = "Kitty Ears"
+ result = /obj/item/clothing/head/kitty/genuine
+ time = 10
+ reqs = list(/obj/item/organ/tail/cat = 1,
+ /obj/item/organ/ears/cat = 1)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/hudsunsec
+ name = "Security HUDsunglasses"
+ result = /obj/item/clothing/glasses/hud/security/sunglasses
+ time = 20
+ tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ reqs = list(/obj/item/clothing/glasses/hud/security = 1,
+ /obj/item/clothing/glasses/sunglasses = 1,
+ /obj/item/stack/cable_coil = 5)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/hudsunsecremoval
+ name = "Security HUD removal"
+ result = /obj/item/clothing/glasses/sunglasses
+ time = 20
+ tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ reqs = list(/obj/item/clothing/glasses/hud/security/sunglasses = 1)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/hudsunmed
+ name = "Medical HUDsunglasses"
+ result = /obj/item/clothing/glasses/hud/health/sunglasses
+ time = 20
+ tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ reqs = list(/obj/item/clothing/glasses/hud/health = 1,
+ /obj/item/clothing/glasses/sunglasses = 1,
+ /obj/item/stack/cable_coil = 5)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/hudsunmedremoval
+ name = "Medical HUD removal"
+ result = /obj/item/clothing/glasses/sunglasses
+ time = 20
+ tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ reqs = list(/obj/item/clothing/glasses/hud/health/sunglasses = 1)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/beergoggles
+ name = "Beer Goggles"
+ result = /obj/item/clothing/glasses/sunglasses/reagent
+ time = 20
+ tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ reqs = list(/obj/item/clothing/glasses/science = 1,
+ /obj/item/clothing/glasses/sunglasses = 1,
+ /obj/item/stack/cable_coil = 5)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/beergogglesremoval
+ name = "Beer Goggles removal"
+ result = /obj/item/clothing/glasses/sunglasses
+ time = 20
+ tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ reqs = list(/obj/item/clothing/glasses/sunglasses/reagent = 1)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/ghostsheet
+ name = "Ghost Sheet"
+ result = /obj/item/clothing/suit/ghost_sheet
+ time = 5
+ tools = list(TOOL_WIRECUTTER)
+ reqs = list(/obj/item/bedsheet = 1)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/briefcase
+ name = "Hand made Briefcase"
+ result = /obj/item/storage/briefcase/crafted
+ time = 35
+ tools = list(TOOL_WIRECUTTER)
+ reqs = list(/obj/item/stack/sheet/cardboard = 1,
+ /obj/item/stack/sheet/cloth = 2,
+ /obj/item/stack/sheet/leather = 5)
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/medolier
+ name = "Medolier"
+ result = /obj/item/storage/belt/medolier
+ reqs = list(/obj/item/stack/sheet/metal = 2,
+ /obj/item/stack/sheet/cloth = 3,
+ /obj/item/stack/sheet/plastic = 4)
+ time = 30
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/durathread_duffelbag
+ name = "Durathread Dufflebag"
+ result = /obj/item/storage/backpack/duffelbag/durathread
+ reqs = list(/obj/item/stack/sheet/durathread = 7,
+ /obj/item/stack/sheet/leather = 3)
+ time = 70
+ always_availible = TRUE
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/durathread_toolbelt
+ name = "Durathread Toolbelt"
+ result = /obj/item/storage/belt/durathread
+ reqs = list(/obj/item/stack/sheet/durathread = 5,
+ /obj/item/stack/sheet/leather = 2)
+ time = 30
+ always_availible = TRUE
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/durathread_bandolier
+ name = "Durathread Bandolier"
+ result = /obj/item/storage/belt/bandolier/durathread
+ reqs = list(/obj/item/stack/sheet/durathread = 6,
+ /obj/item/stack/sheet/leather = 2)
+ time = 50
+ always_availible = TRUE
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/durathread_helmet
+ name = "Makeshift Durathread Helmet"
+ result = /obj/item/clothing/head/helmet/durathread
+ reqs = list(/obj/item/stack/sheet/durathread = 4,
+ /obj/item/stack/sheet/leather = 2)
+ time = 30
+ always_availible = TRUE
+ category = CAT_CLOTHING
+
+/datum/crafting_recipe/durathread_vest
+ name = "Makeshift Durathread Armour"
+ result = /obj/item/clothing/suit/armor/vest/durathread
+ reqs = list(/obj/item/stack/sheet/durathread = 6,
+ /obj/item/stack/sheet/leather = 3)
+ time = 50
+ always_availible = TRUE
+ category = CAT_CLOTHING
diff --git a/code/modules/crafting/recipes/recipes_misc.dm b/code/modules/crafting/recipes/recipes_misc.dm
new file mode 100644
index 0000000000..fdfb959fe6
--- /dev/null
+++ b/code/modules/crafting/recipes/recipes_misc.dm
@@ -0,0 +1,317 @@
+/////////////////
+//Large Objects//
+/////////////////
+
+/datum/crafting_recipe/showercurtain
+ name = "Shower Curtains"
+ reqs = list(/obj/item/stack/sheet/cloth = 2,
+ /obj/item/stack/sheet/plastic = 2,
+ /obj/item/stack/rods = 1)
+ result = /obj/structure/curtain
+ category = CAT_MISC
+
+/datum/crafting_recipe/guillotine
+ name = "Guillotine"
+ result = /obj/structure/guillotine
+ time = 150 // Building a functioning guillotine takes time
+ reqs = list(/obj/item/stack/sheet/plasteel = 3,
+ /obj/item/stack/sheet/mineral/wood = 20,
+ /obj/item/stack/cable_coil = 10)
+ tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
+ category = CAT_MISC
+
+/datum/crafting_recipe/femur_breaker
+ name = "Femur Breaker"
+ result = /obj/structure/femur_breaker
+ time = 150
+ reqs = list(/obj/item/stack/sheet/metal = 20,
+ /obj/item/stack/cable_coil = 30)
+ tools = list(TOOL_SCREWDRIVER, TOOL_WRENCH, TOOL_WELDER)
+ category = CAT_MISC
+
+///////////////////
+//Tools & Storage//
+///////////////////
+
+/datum/crafting_recipe/ghettojetpack
+ name = "Improvised Jetpack"
+ result = /obj/item/tank/jetpack/improvised
+ time = 30
+ reqs = list(/obj/item/tank/internals/oxygen = 2,
+ /obj/item/extinguisher = 1,
+ /obj/item/pipe = 3,
+ /obj/item/stack/cable_coil = 30)
+ category = CAT_MISC
+ tools = list(TOOL_WRENCH, TOOL_WELDER, TOOL_WIRECUTTER)
+
+/datum/crafting_recipe/goldenbox
+ name = "Gold Plated Toolbox"
+ result = /obj/item/storage/toolbox/gold_fake
+ reqs = list(/obj/item/stack/sheet/cardboard = 1, //so we dont null items in crafting
+ /obj/item/stack/cable_coil = 10,
+ /obj/item/stack/sheet/mineral/gold = 1,
+ /obj/item/stock_parts/cell = 1,
+ /datum/reagent/water = 15)
+ time = 40
+ category = CAT_MISC
+
+/datum/crafting_recipe/bronze_driver
+ name = "Bronze Plated Screwdriver"
+ result = /obj/item/screwdriver/bronze
+ reqs = list(/obj/item/screwdriver = 1,
+ /obj/item/stack/cable_coil = 10,
+ /obj/item/stack/tile/bronze = 1,
+ /datum/reagent/water = 15)
+ time = 40
+ category = CAT_MISC
+
+/datum/crafting_recipe/bronze_welder
+ name = "Bronze Plated Welding Tool"
+ result = /obj/item/weldingtool/bronze
+ reqs = list(/obj/item/weldingtool = 1,
+ /obj/item/stack/cable_coil = 10,
+ /obj/item/stack/tile/bronze = 1,
+ /datum/reagent/water = 15)
+ time = 40
+ category = CAT_MISC
+
+/datum/crafting_recipe/bronze_wirecutters
+ name = "Bronze Plated Wirecutters"
+ result = /obj/item/wirecutters/bronze
+ reqs = list(/obj/item/wirecutters = 1,
+ /obj/item/stack/cable_coil = 10,
+ /obj/item/stack/tile/bronze = 1,
+ /datum/reagent/water = 15)
+ time = 40
+ category = CAT_MISC
+
+/datum/crafting_recipe/bronze_crowbar
+ name = "Bronze Plated Crowbar"
+ result = /obj/item/crowbar/bronze
+ reqs = list(/obj/item/crowbar = 1,
+ /obj/item/stack/cable_coil = 10,
+ /obj/item/stack/tile/bronze = 1,
+ /datum/reagent/water = 15)
+ time = 40
+ category = CAT_MISC
+
+/datum/crafting_recipe/bronze_wrench
+ name = "Bronze Plated Wrench"
+ result = /obj/item/wrench/bronze
+ reqs = list(/obj/item/wrench = 1,
+ /obj/item/stack/cable_coil = 10,
+ /obj/item/stack/tile/bronze = 1,
+ /datum/reagent/water = 15)
+ time = 40
+ category = CAT_MISC
+
+/datum/crafting_recipe/rcl
+ name = "Makeshift Rapid Cable Layer"
+ result = /obj/item/twohanded/rcl/ghetto
+ time = 40
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WRENCH)
+ reqs = list(/obj/item/stack/sheet/metal = 15)
+ category = CAT_MISC
+
+////////////
+//Vehicles//
+////////////
+
+/datum/crafting_recipe/wheelchair
+ name = "Wheelchair"
+ result = /obj/vehicle/ridden/wheelchair
+ reqs = list(/obj/item/stack/sheet/plasteel = 2,
+ /obj/item/stack/rods = 8)
+ time = 100
+ category = CAT_MISC
+
+/datum/crafting_recipe/skateboard
+ name = "Skateboard"
+ result = /obj/vehicle/ridden/scooter/skateboard
+ time = 60
+ reqs = list(/obj/item/stack/sheet/metal = 5,
+ /obj/item/stack/rods = 10)
+ category = CAT_MISC
+
+/datum/crafting_recipe/scooter
+ name = "Scooter"
+ result = /obj/vehicle/ridden/scooter
+ time = 65
+ reqs = list(/obj/item/stack/sheet/metal = 5,
+ /obj/item/stack/rods = 12)
+ category = CAT_MISC
+
+/////////
+//Toys///
+/////////
+
+/datum/crafting_recipe/toysword
+ name = "Toy Sword"
+ reqs = list(/obj/item/light/bulb = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
+ result = /obj/item/toy/sword
+ category = CAT_MISC
+
+/datum/crafting_recipe/extendohand
+ name = "Extendo-Hand"
+ reqs = list(/obj/item/bodypart/r_arm/robot = 1, /obj/item/clothing/gloves/boxing = 1)
+ result = /obj/item/extendohand
+ category = CAT_MISC
+
+/datum/crafting_recipe/toyneb
+ name = "Non-Euplastic Blade"
+ reqs = list(/obj/item/light/tube = 1, /obj/item/stack/cable_coil = 1, /obj/item/stack/sheet/plastic = 4)
+ result = /obj/item/toy/sword/cx
+ category = CAT_MISC
+
+////////////
+//Unsorted//
+////////////
+
+/datum/crafting_recipe/blackcarpet
+ name = "Black Carpet"
+ reqs = list(/obj/item/stack/tile/carpet = 50, /obj/item/toy/crayon/black = 1)
+ result = /obj/item/stack/tile/carpet/black/fifty
+ category = CAT_MISC
+
+/datum/crafting_recipe/paperframes
+ name = "Paper Frames"
+ result = /obj/item/stack/sheet/paperframes/five
+ time = 10
+ reqs = list(/obj/item/stack/sheet/mineral/wood = 5, /obj/item/paper = 20)
+ category = CAT_MISC
+
+/datum/crafting_recipe/naturalpaper
+ name = "Hand-Pressed Paper"
+ time = 30
+ reqs = list(/datum/reagent/water = 50, /obj/item/stack/sheet/mineral/wood = 1)
+ tools = list(/obj/item/hatchet)
+ result = /obj/item/paper_bin/bundlenatural
+ category = CAT_MISC
+
+/datum/crafting_recipe/bluespacehonker
+ name = "Bluespace Bike horn"
+ result = /obj/item/bikehorn/bluespacehonker
+ time = 10
+ reqs = list(/obj/item/stack/ore/bluespace_crystal = 1,
+ /obj/item/toy/crayon/blue = 1,
+ /obj/item/bikehorn = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/mousetrap
+ name = "Mouse Trap"
+ result = /obj/item/assembly/mousetrap
+ time = 10
+ reqs = list(/obj/item/stack/sheet/cardboard = 1,
+ /obj/item/stack/rods = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/papersack
+ name = "Paper Sack"
+ result = /obj/item/storage/box/papersack
+ time = 10
+ reqs = list(/obj/item/paper = 5)
+ category = CAT_MISC
+
+/datum/crafting_recipe/flashlight_eyes
+ name = "Flashlight Eyes"
+ result = /obj/item/organ/eyes/robotic/flashlight
+ time = 10
+ reqs = list(
+ /obj/item/flashlight = 2,
+ /obj/item/restraints/handcuffs/cable = 1
+ )
+ category = CAT_MISC
+
+/datum/crafting_recipe/smallcarton
+ name = "Small Carton"
+ result = /obj/item/reagent_containers/food/drinks/sillycup/smallcarton
+ time = 10
+ reqs = list(/obj/item/stack/sheet/cardboard = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/pressureplate
+ name = "Pressure Plate"
+ result = /obj/item/pressure_plate
+ time = 5
+ reqs = list(/obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/tile/plasteel = 1,
+ /obj/item/stack/cable_coil = 2,
+ /obj/item/assembly/igniter = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/gold_horn
+ name = "Golden Bike Horn"
+ result = /obj/item/bikehorn/golden
+ time = 20
+ reqs = list(/obj/item/stack/sheet/mineral/bananium = 5,
+ /obj/item/bikehorn = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/spooky_camera
+ name = "Camera Obscura"
+ result = /obj/item/camera/spooky
+ time = 15
+ reqs = list(/obj/item/camera = 1,
+ /datum/reagent/water/holywater = 10)
+ parts = list(/obj/item/camera = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/paperwork
+ name = "Filed Paper Work"
+ result = /obj/item/folder/paperwork_correct
+ time = 10 //Takes time for people to file and complete paper work!
+ tools = list(/obj/item/pen)
+ reqs = list(/obj/item/folder/paperwork = 1)
+ category = CAT_MISC
+
+//////////////
+//Banners/////
+//////////////
+
+/datum/crafting_recipe/command_banner
+ name = "Command Banner"
+ result = /obj/item/banner/command/mundane
+ time = 40
+ reqs = list(/obj/item/stack/rods = 2,
+ /obj/item/clothing/under/captainparade = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/engineering_banner
+ name = "Engitopia Banner"
+ result = /obj/item/banner/engineering/mundane
+ time = 40
+ reqs = list(/obj/item/stack/rods = 2,
+ /obj/item/clothing/under/rank/engineer = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/cargo_banner
+ name = "Cargonia Banner"
+ result = /obj/item/banner/cargo/mundane
+ time = 40
+ reqs = list(/obj/item/stack/rods = 2,
+ /obj/item/clothing/under/rank/cargotech = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/science_banner
+ name = "Sciencia Banner"
+ result = /obj/item/banner/science/mundane
+ time = 40
+ reqs = list(/obj/item/stack/rods = 2,
+ /obj/item/clothing/under/rank/scientist = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/medical_banner
+ name = "Meditopia Banner"
+ result = /obj/item/banner/medical/mundane
+ time = 40
+ reqs = list(/obj/item/stack/rods = 2,
+ /obj/item/clothing/under/rank/medical = 1)
+ category = CAT_MISC
+
+/datum/crafting_recipe/security_banner
+ name = "Securistan Banner"
+ result = /obj/item/banner/security/mundane
+ time = 40
+ reqs = list(/obj/item/stack/rods = 2,
+ /obj/item/clothing/under/rank/security = 1)
+ category = CAT_MISC
diff --git a/code/modules/crafting/recipes/recipes_primal.dm b/code/modules/crafting/recipes/recipes_primal.dm
new file mode 100644
index 0000000000..1be479e4e1
--- /dev/null
+++ b/code/modules/crafting/recipes/recipes_primal.dm
@@ -0,0 +1,113 @@
+/datum/crafting_recipe/bonearmor
+ name = "Bone Armor"
+ result = /obj/item/clothing/suit/armor/bone
+ time = 30
+ reqs = list(/obj/item/stack/sheet/bone = 6)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonetalisman
+ name = "Bone Talisman"
+ result = /obj/item/clothing/accessory/talisman
+ time = 20
+ reqs = list(/obj/item/stack/sheet/bone = 2,
+ /obj/item/stack/sheet/sinew = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonecodpiece
+ name = "Skull Codpiece"
+ result = /obj/item/clothing/accessory/skullcodpiece
+ time = 20
+ reqs = list(/obj/item/stack/sheet/bone = 2,
+ /obj/item/stack/sheet/animalhide/goliath_hide = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bracers
+ name = "Bone Bracers"
+ result = /obj/item/clothing/gloves/bracer
+ time = 20
+ reqs = list(/obj/item/stack/sheet/bone = 2,
+ /obj/item/stack/sheet/sinew = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/skullhelm
+ name = "Skull Helmet"
+ result = /obj/item/clothing/head/helmet/skull
+ time = 30
+ reqs = list(/obj/item/stack/sheet/bone = 4)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/goliathcloak
+ name = "Goliath Cloak"
+ result = /obj/item/clothing/suit/hooded/cloak/goliath
+ time = 50
+ reqs = list(/obj/item/stack/sheet/leather = 2,
+ /obj/item/stack/sheet/sinew = 2,
+ /obj/item/stack/sheet/animalhide/goliath_hide = 2) //it takes 4 goliaths to make 1 cloak if the plates are skinned
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/drakecloak
+ name = "Ash Drake Armour"
+ result = /obj/item/clothing/suit/hooded/cloak/drake
+ time = 60
+ reqs = list(/obj/item/stack/sheet/bone = 10,
+ /obj/item/stack/sheet/sinew = 2,
+ /obj/item/stack/sheet/animalhide/ashdrake = 5)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonebag
+ name = "Bone Satchel"
+ result = /obj/item/storage/backpack/satchel/bone
+ time = 30
+ reqs = list(/obj/item/stack/sheet/bone = 3,
+ /obj/item/stack/sheet/sinew = 2)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonedagger
+ name = "Bone Dagger"
+ result = /obj/item/kitchen/knife/combat/bone
+ time = 20
+ reqs = list(/obj/item/stack/sheet/bone = 2)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonespear
+ name = "Bone Spear"
+ result = /obj/item/twohanded/bonespear
+ time = 30
+ reqs = list(/obj/item/stack/sheet/bone = 4,
+ /obj/item/stack/sheet/sinew = 1)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/boneaxe
+ name = "Bone Axe"
+ result = /obj/item/twohanded/fireaxe/boneaxe
+ time = 50
+ reqs = list(/obj/item/stack/sheet/bone = 6,
+ /obj/item/stack/sheet/sinew = 3)
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/bonfire
+ name = "Bonfire"
+ time = 60
+ reqs = list(/obj/item/grown/log = 5)
+ result = /obj/structure/bonfire
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/headpike
+ name = "Spike Head (Glass Spear)"
+ time = 65
+ reqs = list(/obj/item/twohanded/spear = 1,
+ /obj/item/bodypart/head = 1)
+ parts = list(/obj/item/bodypart/head = 1,
+ /obj/item/twohanded/spear = 1)
+ result = /obj/structure/headpike
+ category = CAT_PRIMAL
+
+/datum/crafting_recipe/headpikebone
+ name = "Spike Head (Bone Spear)"
+ time = 65
+ reqs = list(/obj/item/twohanded/bonespear = 1,
+ /obj/item/bodypart/head = 1)
+ parts = list(/obj/item/bodypart/head = 1,
+ /obj/item/twohanded/bonespear = 1)
+ result = /obj/structure/headpike/bone
+ category = CAT_PRIMAL
\ No newline at end of file
diff --git a/code/modules/crafting/recipes/recipes_robot.dm b/code/modules/crafting/recipes/recipes_robot.dm
new file mode 100644
index 0000000000..2b8ee0fe3a
--- /dev/null
+++ b/code/modules/crafting/recipes/recipes_robot.dm
@@ -0,0 +1,98 @@
+
+/datum/crafting_recipe/ed209
+ name = "ED209"
+ result = /mob/living/simple_animal/bot/ed209
+ reqs = list(/obj/item/robot_suit = 1,
+ /obj/item/clothing/head/helmet = 1,
+ /obj/item/clothing/suit/armor/vest = 1,
+ /obj/item/bodypart/l_leg/robot = 1,
+ /obj/item/bodypart/r_leg/robot = 1,
+ /obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/cable_coil = 1,
+ /obj/item/gun/energy/e_gun/advtaser = 1,
+ /obj/item/stock_parts/cell = 1,
+ /obj/item/assembly/prox_sensor = 1)
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER)
+ time = 60
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/secbot
+ name = "Secbot"
+ result = /mob/living/simple_animal/bot/secbot
+ reqs = list(/obj/item/assembly/signaler = 1,
+ /obj/item/clothing/head/helmet/sec = 1,
+ /obj/item/melee/baton = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bodypart/r_arm/robot = 1)
+ tools = list(TOOL_WELDER)
+ time = 60
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/cleanbot
+ name = "Cleanbot"
+ result = /mob/living/simple_animal/bot/cleanbot
+ reqs = list(/obj/item/reagent_containers/glass/bucket = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bodypart/r_arm/robot = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/floorbot
+ name = "Floorbot"
+ result = /mob/living/simple_animal/bot/floorbot
+ reqs = list(/obj/item/storage/toolbox/mechanical = 1,
+ /obj/item/stack/tile/plasteel = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bodypart/r_arm/robot = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/medbot
+ name = "Medbot"
+ result = /mob/living/simple_animal/bot/medbot
+ reqs = list(/obj/item/healthanalyzer = 1,
+ /obj/item/storage/firstaid = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bodypart/r_arm/robot = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/honkbot
+ name = "Honkbot"
+ result = /mob/living/simple_animal/bot/honkbot
+ reqs = list(/obj/item/storage/box/clown = 1,
+ /obj/item/bodypart/r_arm/robot = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/bikehorn/ = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/Firebot
+ name = "Firebot"
+ result = /mob/living/simple_animal/bot/firebot
+ reqs = list(/obj/item/extinguisher = 1,
+ /obj/item/bodypart/r_arm/robot = 1,
+ /obj/item/assembly/prox_sensor = 1,
+ /obj/item/clothing/head/hardhat/red = 1)
+ time = 40
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/aitater
+ name = "intelliTater"
+ result = /obj/item/aicard/aitater
+ time = 30
+ tools = list(TOOL_WIRECUTTER)
+ reqs = list(/obj/item/aicard = 1,
+ /obj/item/reagent_containers/food/snacks/grown/potato = 1,
+ /obj/item/stack/cable_coil = 5)
+ category = CAT_ROBOT
+
+/datum/crafting_recipe/aispook
+ name = "intelliLantern"
+ result = /obj/item/aicard/aispook
+ time = 30
+ tools = list(TOOL_WIRECUTTER)
+ reqs = list(/obj/item/aicard = 1,
+ /obj/item/reagent_containers/food/snacks/grown/pumpkin = 1,
+ /obj/item/stack/cable_coil = 5)
+ category = CAT_ROBOT
\ No newline at end of file
diff --git a/code/modules/crafting/recipes/recipes_weapon_and_ammo.dm b/code/modules/crafting/recipes/recipes_weapon_and_ammo.dm
new file mode 100644
index 0000000000..6eb1c31b12
--- /dev/null
+++ b/code/modules/crafting/recipes/recipes_weapon_and_ammo.dm
@@ -0,0 +1,345 @@
+/datum/crafting_recipe/pin_removal
+ name = "Pin Removal"
+ result = /obj/item/gun
+ reqs = list(/obj/item/gun = 1)
+ parts = list(/obj/item/gun = 1)
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ time = 50
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/strobeshield
+ name = "Strobe Shield"
+ result = /obj/item/assembly/flash/shield
+ reqs = list(/obj/item/wallframe/flasher = 1,
+ /obj/item/assembly/flash/handheld = 1,
+ /obj/item/shield/riot = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/makeshiftshield
+ name = "Makeshift Metal Shield"
+ result = /obj/item/shield/makeshift
+ reqs = list(/obj/item/stack/cable_coil = 30,
+ /obj/item/stack/sheet/metal = 10,
+ /obj/item/stack/sheet/cloth = 2,
+ /obj/item/stack/sheet/leather = 3)
+ tools = list(TOOL_WELDER, TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
+ time = 100
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/spear
+ name = "Spear"
+ result = /obj/item/twohanded/spear
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/shard = 1,
+ /obj/item/stack/rods = 1)
+ parts = list(/obj/item/shard = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/stunprod
+ name = "Stunprod"
+ result = /obj/item/melee/baton/cattleprod
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/stack/rods = 1,
+ /obj/item/assembly/igniter = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/teleprod
+ name = "Teleprod"
+ result = /obj/item/melee/baton/cattleprod/teleprod
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/stack/rods = 1,
+ /obj/item/assembly/igniter = 1,
+ /obj/item/stack/ore/bluespace_crystal = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/bola
+ name = "Bola"
+ result = /obj/item/restraints/legcuffs/bola
+ reqs = list(/obj/item/restraints/handcuffs/cable = 1,
+ /obj/item/stack/sheet/metal = 6)
+ time = 20//15 faster than crafting them by hand!
+ category= CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/tailclub
+ name = "Tail Club"
+ result = /obj/item/tailclub
+ reqs = list(/obj/item/organ/tail/lizard = 1,
+ /obj/item/stack/sheet/metal = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/tailwhip
+ name = "Liz O' Nine Tails"
+ result = /obj/item/melee/chainofcommand/tailwhip
+ reqs = list(/obj/item/organ/tail/lizard = 1,
+ /obj/item/stack/cable_coil = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/catwhip
+ name = "Cat O' Nine Tails"
+ result = /obj/item/melee/chainofcommand/tailwhip/kitty
+ reqs = list(/obj/item/organ/tail/cat = 1,
+ /obj/item/stack/cable_coil = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/chainsaw
+ name = "Chainsaw"
+ result = /obj/item/twohanded/required/chainsaw
+ reqs = list(/obj/item/circular_saw = 1,
+ /obj/item/stack/cable_coil = 3,
+ /obj/item/stack/sheet/plasteel = 5)
+ tools = list(TOOL_WELDER)
+ time = 50
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+//////////////////
+///BOMB CRAFTING//
+//////////////////
+
+/datum/crafting_recipe/chemical_payload
+ name = "Chemical Payload (C4)"
+ result = /obj/item/bombcore/chemical
+ reqs = list(
+ /obj/item/stock_parts/matter_bin = 1,
+ /obj/item/grenade/plastic/c4 = 1,
+ /obj/item/grenade/chem_grenade = 2
+ )
+ parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
+ time = 30
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/chemical_payload2
+ name = "Chemical Payload (Gibtonite)"
+ result = /obj/item/bombcore/chemical
+ reqs = list(
+ /obj/item/stock_parts/matter_bin = 1,
+ /obj/item/twohanded/required/gibtonite = 1,
+ /obj/item/grenade/chem_grenade = 2
+ )
+ parts = list(/obj/item/stock_parts/matter_bin = 1, /obj/item/grenade/chem_grenade = 2)
+ time = 50
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/molotov
+ name = "Molotov"
+ result = /obj/item/reagent_containers/food/drinks/bottle/molotov
+ reqs = list(/obj/item/reagent_containers/rag = 1,
+ /obj/item/reagent_containers/food/drinks/bottle = 1)
+ parts = list(/obj/item/reagent_containers/food/drinks/bottle = 1)
+ time = 40
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/IED
+ name = "IED"
+ result = /obj/item/grenade/iedcasing
+ reqs = list(/datum/reagent/fuel = 50,
+ /obj/item/stack/cable_coil = 1,
+ /obj/item/assembly/igniter = 1,
+ /obj/item/reagent_containers/food/drinks/soda_cans = 1)
+ parts = list(/obj/item/reagent_containers/food/drinks/soda_cans = 1)
+ time = 15
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/lance
+ name = "Explosive Lance (Grenade)"
+ result = /obj/item/twohanded/spear
+ reqs = list(/obj/item/twohanded/spear = 1,
+ /obj/item/grenade = 1)
+ parts = list(/obj/item/twohanded/spear = 1,
+ /obj/item/grenade = 1)
+ time = 15
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+//////////////////
+///GUNS CRAFTING//
+//////////////////
+
+
+/datum/crafting_recipe/smartdartgun
+ name = "Smart dartgun"
+ result = /obj/item/gun/syringe/dart
+ reqs = list(/obj/item/stack/sheet/metal = 10,
+ /obj/item/stack/sheet/glass = 5,
+ /obj/item/tank/internals = 1,
+ /obj/item/reagent_containers/glass/beaker = 1,
+ /obj/item/stack/sheet/plastic = 5,
+ /obj/item/stack/cable_coil = 1)
+ time = 150 //It's a gun
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/rapiddartgun
+ name = "Rapid Smart dartgun"
+ result = /obj/item/gun/syringe/dart/rapiddart
+ reqs = list(
+ /obj/item/gun/syringe/dart = 1,
+ /obj/item/stack/sheet/plastic = 5,
+ /obj/item/stack/cable_coil = 1,
+ /obj/item/reagent_containers/glass/beaker = 1
+ )
+ parts = list(/obj/item/reagent_containers/glass/beaker = 1)
+ time = 120 //Modifying your gun
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/improvised_pneumatic_cannon
+ name = "Pneumatic Cannon"
+ result = /obj/item/pneumatic_cannon/ghetto
+ tools = list(TOOL_WELDER, TOOL_WRENCH)
+ reqs = list(/obj/item/stack/sheet/metal = 4,
+ /obj/item/stack/packageWrap = 8,
+ /obj/item/pipe = 2)
+ time = 300
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/flamethrower //Gun*
+ name = "Flamethrower"
+ result = /obj/item/flamethrower
+ reqs = list(/obj/item/weldingtool = 1,
+ /obj/item/assembly/igniter = 1,
+ /obj/item/stack/rods = 1)
+ parts = list(/obj/item/assembly/igniter = 1,
+ /obj/item/weldingtool = 1)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 10
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/ishotgun
+ name = "Improvised Shotgun"
+ result = /obj/item/gun/ballistic/revolver/doublebarrel/improvised
+ reqs = list(/obj/item/weaponcrafting/receiver = 1,
+ /obj/item/pipe = 1,
+ /obj/item/weaponcrafting/stock = 1,
+ /obj/item/stack/packageWrap = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 100
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+/datum/crafting_recipe/irifle
+ name = "Improvised Rifle(7.62mm)"
+ result = /obj/item/gun/ballistic/shotgun/boltaction/improvised
+ reqs = list(/obj/item/weaponcrafting/receiver = 1,
+ /obj/item/pipe = 2,
+ /obj/item/weaponcrafting/stock = 1,
+ /obj/item/stack/packageWrap = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 100
+ category = CAT_WEAPONRY
+ subcategory = CAT_WEAPON
+
+//////////////////
+///AMMO CRAFTING//
+//////////////////
+
+/datum/crafting_recipe/smartdart
+ name = "Medical smartdart"
+ result = /obj/item/reagent_containers/syringe/dart
+ reqs = list(/obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/sheet/glass = 1,
+ /obj/item/stack/sheet/plastic = 1)
+ time = 10
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/meteorslug
+ name = "Meteorslug Shell"
+ result = /obj/item/ammo_casing/shotgun/meteorslug
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /obj/item/rcd_ammo = 1,
+ /obj/item/stock_parts/manipulator = 2)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/pulseslug
+ name = "Pulse Slug Shell"
+ result = /obj/item/ammo_casing/shotgun/pulseslug
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /obj/item/stock_parts/capacitor/adv = 2,
+ /obj/item/stock_parts/micro_laser/ultra = 1)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/dragonsbreath
+ name = "Dragonsbreath Shell"
+ result = /obj/item/ammo_casing/shotgun/dragonsbreath
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /datum/reagent/phosphorus = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/frag12
+ name = "FRAG-12 Shell"
+ result = /obj/item/ammo_casing/shotgun/frag12
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /datum/reagent/glycerol = 5,
+ /datum/reagent/toxin/acid = 5,
+ /datum/reagent/toxin/acid/fluacid = 5)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/ionslug
+ name = "Ion Scatter Shell"
+ result = /obj/item/ammo_casing/shotgun/ion
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /obj/item/stock_parts/micro_laser/ultra = 1,
+ /obj/item/stock_parts/subspace/crystal = 1)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/improvisedslug
+ name = "Improvised Shotgun Shell"
+ result = /obj/item/ammo_casing/shotgun/improvised
+ reqs = list(/obj/item/grenade/chem_grenade = 1,
+ /obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/cable_coil = 1,
+ /datum/reagent/fuel = 10)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
+
+/datum/crafting_recipe/laserslug
+ name = "Scatter Laser Shell"
+ result = /obj/item/ammo_casing/shotgun/laserslug
+ reqs = list(/obj/item/ammo_casing/shotgun/techshell = 1,
+ /obj/item/stock_parts/capacitor/adv = 1,
+ /obj/item/stock_parts/micro_laser/high = 1)
+ tools = list(TOOL_SCREWDRIVER)
+ time = 5
+ category = CAT_WEAPONRY
+ subcategory = CAT_AMMO
diff --git a/code/modules/detectivework/detective_work.dm b/code/modules/detectivework/detective_work.dm
index c892bfeffc..1a2405b9c4 100644
--- a/code/modules/detectivework/detective_work.dm
+++ b/code/modules/detectivework/detective_work.dm
@@ -1,111 +1,107 @@
//CONTAINS: Suit fibers and Detective's Scanning Computer
-/atom/proc/return_fingerprints()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = D.fingerprints
+/atom/proc/add_fibers(mob/living/carbon/human/M)
+ if(M.gloves && istype(M.gloves, /obj/item/clothing/))
+ var/obj/item/clothing/gloves/G = M.gloves
+ if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
+ if(add_blood_DNA(G.blood_DNA)) //only reduces the bloodiness of our gloves if the item wasn't already bloody
+ G.transfer_blood--
+ else if(M.bloody_hands > 1)
+ if(add_blood_DNA(M.blood_DNA, M.diseases))
+ M.bloody_hands--
+ if(!suit_fibers)
+ suit_fibers = list()
+ var/fibertext
+ var/item_multiplier = isitem(src)?1.2:1
+ if(M.wear_suit)
+ fibertext = "Material from \a [M.wear_suit]."
+ if(prob(10*item_multiplier) && !(fibertext in suit_fibers))
+ suit_fibers += fibertext
+ if(!(M.wear_suit.body_parts_covered & CHEST))
+ if(M.w_uniform)
+ fibertext = "Fibers from \a [M.w_uniform]."
+ if(prob(12*item_multiplier) && !(fibertext in suit_fibers)) //Wearing a suit means less of the uniform exposed.
+ suit_fibers += fibertext
+ if(!(M.wear_suit.body_parts_covered & HANDS))
+ if(M.gloves)
+ fibertext = "Material from a pair of [M.gloves.name]."
+ if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
+ suit_fibers += fibertext
+ else if(M.w_uniform)
+ fibertext = "Fibers from \a [M.w_uniform]."
+ if(prob(15*item_multiplier) && !(fibertext in suit_fibers))
+ // "Added fibertext: [fibertext]"
+ suit_fibers += fibertext
+ if(M.gloves)
+ fibertext = "Material from a pair of [M.gloves.name]."
+ if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
+ suit_fibers += "Material from a pair of [M.gloves.name]."
+ else if(M.gloves)
+ fibertext = "Material from a pair of [M.gloves.name]."
+ if(prob(20*item_multiplier) && !(fibertext in suit_fibers))
+ suit_fibers += "Material from a pair of [M.gloves.name]."
-/atom/proc/return_hiddenprints()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = D.hiddenprints
-/atom/proc/return_blood_DNA()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = D.blood_DNA
+/atom/proc/add_hiddenprint(mob/living/M)
+ if(!M || !M.key)
+ return
-/atom/proc/blood_DNA_length()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = length(D.blood_DNA)
+ if(!fingerprintshidden) //Add the list if it does not exist
+ fingerprintshidden = list()
-/atom/proc/return_fibers()
- GET_COMPONENT(D, /datum/component/forensics)
- if(D)
- . = D.fibers
+ var/hasgloves = ""
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ if(H.gloves)
+ hasgloves = "(gloves)"
+
+ var/current_time = TIME_STAMP("hh:mm:ss", FALSE)
+ if(!fingerprintshidden[M.key])
+ fingerprintshidden[M.key] = "First: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
+ else
+ var/laststamppos = findtext(fingerprintshidden[M.key], " Last: ")
+ if(laststamppos)
+ fingerprintshidden[M.key] = copytext(fingerprintshidden[M.key], 1, laststamppos)
+ fingerprintshidden[M.key] += " Last: [M.real_name]\[[current_time]\][hasgloves]. Ckey: [M.ckey]"
+
+ fingerprintslast = M.ckey
-/atom/proc/add_fingerprint_list(list/fingerprints) //ASSOC LIST FINGERPRINT = FINGERPRINT
- if(length(fingerprints))
- . = AddComponent(/datum/component/forensics, fingerprints)
//Set ignoregloves to add prints irrespective of the mob having gloves on.
/atom/proc/add_fingerprint(mob/living/M, ignoregloves = FALSE)
- var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
- . = D.add_fingerprint(M, ignoregloves)
+ if(!M || !M.key)
+ return
-/atom/proc/add_fiber_list(list/fibertext) //ASSOC LIST FIBERTEXT = FIBERTEXT
- if(length(fibertext))
- . = AddComponent(/datum/component/forensics, null, null, null, fibertext)
+ add_hiddenprint(M)
-/atom/proc/add_fibers(mob/living/carbon/human/M)
- var/old = 0
- if(M.gloves && istype(M.gloves, /obj/item/clothing))
- var/obj/item/clothing/gloves/G = M.gloves
- old = length(G.return_blood_DNA())
- if(G.transfer_blood > 1) //bloodied gloves transfer blood to touched objects
- if(add_blood_DNA(G.return_blood_DNA()) && length(G.return_blood_DNA()) > old) //only reduces the bloodiness of our gloves if the item wasn't already bloody
- G.transfer_blood--
- else if(M.bloody_hands > 1)
- old = length(M.return_blood_DNA())
- if(add_blood_DNA(M.return_blood_DNA()) && length(M.return_blood_DNA()) > old)
- M.bloody_hands--
- var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
- . = D.add_fibers(M)
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
-/atom/proc/add_hiddenprint_list(list/hiddenprints) //NOTE: THIS IS FOR ADMINISTRATION FINGERPRINTS, YOU MUST CUSTOM SET THIS TO INCLUDE CKEY/REAL NAMES! CHECK FORENSICS.DM
- if(length(hiddenprints))
- . = AddComponent(/datum/component/forensics, null, hiddenprints)
+ add_fibers(H)
-/atom/proc/add_hiddenprint(mob/living/M)
- var/datum/component/forensics/D = AddComponent(/datum/component/forensics)
- . = D.add_hiddenprint(M)
+ if(H.gloves) //Check if the gloves (if any) hide fingerprints
+ var/obj/item/clothing/gloves/G = H.gloves
+ if(G.transfer_prints)
+ ignoregloves = TRUE
-/atom/proc/add_blood_DNA(list/dna) //ASSOC LIST DNA = BLOODTYPE
- return FALSE
+ if(!ignoregloves)
+ H.gloves.add_fingerprint(H, TRUE) //ignoregloves = TRUE to avoid infinite loop.
+ return
-/obj/add_blood_DNA(list/dna)
- . = ..()
- if(length(dna))
- . = AddComponent(/datum/component/forensics, null, null, dna)
-
-/obj/item/clothing/gloves/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
- . = ..()
- transfer_blood = rand(2, 4)
-
-/turf/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
- var/obj/effect/decal/cleanable/blood/splatter/B = locate() in src
- if(!B)
- B = new /obj/effect/decal/cleanable/blood/splatter(src, diseases)
- B.add_blood_DNA(blood_dna) //give blood info to the blood decal.
- return TRUE //we bloodied the floor
-
-/mob/living/carbon/human/add_blood_DNA(list/blood_dna, list/datum/disease/diseases)
- if(wear_suit)
- wear_suit.add_blood_DNA(blood_dna)
- update_inv_wear_suit()
- else if(w_uniform)
- w_uniform.add_blood_DNA(blood_dna)
- update_inv_w_uniform()
- if(gloves)
- var/obj/item/clothing/gloves/G = gloves
- G.add_blood_DNA(blood_dna)
- else if(length(blood_dna))
- AddComponent(/datum/component/forensics, null, null, blood_dna)
- bloody_hands = rand(2, 4)
- if(head)
- head.add_blood_DNA(blood_dna)
- update_inv_head()
- else if(wear_mask)
- wear_mask.add_blood_DNA(blood_dna)
- update_inv_wear_mask()
- if(wear_neck)
- wear_neck.add_blood_DNA(blood_dna)
- update_inv_neck()
- update_inv_gloves() //handles bloody hands overlays and updating
- return TRUE
+ LAZYINITLIST(fingerprints) //Add the list if it does not exist
+ var/full_print = md5(H.dna.uni_identity)
+ fingerprints[full_print] = full_print
/atom/proc/transfer_fingerprints_to(atom/A)
- A.add_fingerprint_list(return_fingerprints())
- A.add_hiddenprint_list(return_hiddenprints())
- A.fingerprintslast = fingerprintslast
+ // Make sure everything are lists.
+ LAZYINITLIST(A.fingerprints)
+ LAZYINITLIST(A.fingerprintshidden)
+ LAZYINITLIST(fingerprints)
+ LAZYINITLIST(fingerprintshidden)
+
+ // Transfer
+ if(fingerprints)
+ A.fingerprints |= fingerprints.Copy() //detective
+ if(fingerprintshidden)
+ A.fingerprintshidden |= fingerprintshidden.Copy() //admin
+ A.fingerprintslast = fingerprintslast
\ No newline at end of file
diff --git a/code/modules/detectivework/evidence.dm b/code/modules/detectivework/evidence.dm
index a3b17a4c1f..5b4a75a36c 100644
--- a/code/modules/detectivework/evidence.dm
+++ b/code/modules/detectivework/evidence.dm
@@ -16,7 +16,7 @@
/obj/item/evidencebag/attackby(obj/item/I, mob/user, params)
if(evidencebagEquip(I, user))
- return 1
+ return TRUE
/obj/item/evidencebag/handle_atom_del(atom/A)
cut_overlays()
@@ -25,12 +25,12 @@
desc = initial(desc)
/obj/item/evidencebag/proc/evidencebagEquip(obj/item/I, mob/user)
- if(!istype(I) || I.anchored == 1)
+ if(!istype(I) || I.anchored == TRUE)
return
if(istype(I, /obj/item/evidencebag))
to_chat(user, "You find putting an evidence bag in another evidence bag to be slightly absurd. ")
- return 1 //now this is podracing
+ return TRUE //now this is podracing
if(I.w_class > WEIGHT_CLASS_NORMAL)
to_chat(user, "[I] won't fit in [src]. ")
@@ -62,7 +62,7 @@
desc = "An evidence bag containing [I]. [I.desc]"
I.forceMove(src)
w_class = I.w_class
- return 1
+ return TRUE
/obj/item/evidencebag/attack_self(mob/user)
if(contents.len)
diff --git a/code/modules/detectivework/scanner.dm b/code/modules/detectivework/scanner.dm
index fd7591db81..c578d5b4d4 100644
--- a/code/modules/detectivework/scanner.dm
+++ b/code/modules/detectivework/scanner.dm
@@ -14,7 +14,7 @@
flags_1 = CONDUCT_1
item_flags = NOBLUDGEON
slot_flags = ITEM_SLOT_BELT
- var/scanning = 0
+ var/scanning = FALSE
var/list/log = list()
var/range = 8
var/view_check = TRUE
@@ -30,7 +30,7 @@
/obj/item/detective_scanner/attack_self(mob/user)
if(log.len && !scanning)
- scanning = 1
+ scanning = TRUE
to_chat(user, "Printing report, please wait... ")
addtimer(CALLBACK(src, .proc/PrintReport), 100)
else
@@ -56,7 +56,7 @@
// Clear the logs
log = list()
- scanning = 0
+ scanning = FALSE
/obj/item/detective_scanner/afterattack(atom/A, mob/user, params)
. = ..()
@@ -70,7 +70,7 @@
if((get_dist(A, user) > range) || (!(A in view(range, user)) && view_check) || (loc != user))
return
- scanning = 1
+ scanning = TRUE
user.visible_message("\The [user] points the [src.name] at \the [A] and performs a forensic scan.")
to_chat(user, "You scan \the [A]. The scanner is now analysing the results... ")
@@ -80,14 +80,20 @@
//Make our lists
var/list/fingerprints = list()
- var/list/blood = A.return_blood_DNA()
- var/list/fibers = A.return_fibers()
+ var/list/blood = list()
+ var/list/fibers = list()
var/list/reagents = list()
var/target_name = A.name
// Start gathering
+ if(A.blood_DNA && A.blood_DNA.len)
+ blood = A.blood_DNA.Copy()
+
+ if(A.suit_fibers && A.suit_fibers.len)
+ fibers = A.suit_fibers.Copy()
+
if(ishuman(A))
var/mob/living/carbon/human/H = A
@@ -96,7 +102,8 @@
else if(!ismob(A))
- fingerprints = A.return_fingerprints()
+ if(A.fingerprints && A.fingerprints.len)
+ fingerprints = A.fingerprints.Copy()
// Only get reagents from non-mobs.
if(A.reagents && A.reagents.reagent_list.len)
@@ -115,40 +122,40 @@
// We gathered everything. Create a fork and slowly display the results to the holder of the scanner.
- var/found_something = 0
+ var/found_something = FALSE
add_log("[STATION_TIME_TIMESTAMP("hh:mm:ss")][get_timestamp()] - [target_name] ", 0)
// Fingerprints
if(length(fingerprints))
- sleep(30)
+ sleep(3 SECONDS)
add_log("Prints: ")
for(var/finger in fingerprints)
add_log("[finger]")
- found_something = 1
+ found_something = TRUE
// Blood
if (length(blood))
- sleep(30)
+ sleep(3 SECONDS)
add_log("Blood: ")
- found_something = 1
+ found_something = TRUE
for(var/B in blood)
add_log("Type: [blood[B]] DNA: [B] ")
//Fibers
if(length(fibers))
- sleep(30)
+ sleep(3 SECONDS)
add_log("Fibers: ")
for(var/fiber in fibers)
add_log("[fiber]")
- found_something = 1
+ found_something = TRUE
//Reagents
if(length(reagents))
- sleep(30)
+ sleep(3 SECONDS)
add_log("Reagents: ")
for(var/R in reagents)
add_log("Reagent: [R] Volume: [reagents[R]] ")
- found_something = 1
+ found_something = TRUE
// Get a new user
var/mob/holder = null
@@ -164,10 +171,10 @@
to_chat(holder, "You finish scanning \the [target_name]. ")
add_log("---------------------------------------------------------", 0)
- scanning = 0
+ scanning = FALSE
return
-/obj/item/detective_scanner/proc/add_log(msg, broadcast = 1)
+/obj/item/detective_scanner/proc/add_log(msg, broadcast = TRUE)
if(scanning)
if(broadcast && ismob(loc))
var/mob/M = loc
@@ -207,4 +214,4 @@
return
to_chat(user, "Scanner Report ")
for(var/iterLog in log)
- to_chat(user, iterLog)
+ to_chat(user, iterLog)
\ No newline at end of file
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index ddc75830d6..762371886c 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -32,7 +32,7 @@
/datum/round_event/ghost_role/alien_infestation/announce(fake)
if(successSpawn || fake)
- priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
+ priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", "aliens")
/datum/round_event/ghost_role/alien_infestation/spawn_role()
diff --git a/code/modules/events/anomaly_bluespace.dm b/code/modules/events/anomaly_bluespace.dm
index 44a66e0d27..8fc1a7ab3d 100644
--- a/code/modules/events/anomaly_bluespace.dm
+++ b/code/modules/events/anomaly_bluespace.dm
@@ -13,7 +13,7 @@
if(prob(90))
priority_announce("Unstable bluespace anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/anomaly_flux.dm b/code/modules/events/anomaly_flux.dm
index cc22abe5ab..73562e49e5 100644
--- a/code/modules/events/anomaly_flux.dm
+++ b/code/modules/events/anomaly_flux.dm
@@ -14,7 +14,7 @@
if(prob(90))
priority_announce("Localized hyper-energetic flux wave detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/anomaly_grav.dm b/code/modules/events/anomaly_grav.dm
index c240be50d4..6e9014f13c 100644
--- a/code/modules/events/anomaly_grav.dm
+++ b/code/modules/events/anomaly_grav.dm
@@ -12,7 +12,7 @@
if(prob(90))
priority_announce("Gravitational anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/anomaly_pyro.dm b/code/modules/events/anomaly_pyro.dm
index 5a973db95a..988ccadb76 100644
--- a/code/modules/events/anomaly_pyro.dm
+++ b/code/modules/events/anomaly_pyro.dm
@@ -12,7 +12,7 @@
if(prob(90))
priority_announce("Pyroclastic anomaly detected on long range scanners. Expected location: [impact_area.name].", "Anomaly Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/anomaly_vortex.dm b/code/modules/events/anomaly_vortex.dm
index b57fe9e67e..2550dc191e 100644
--- a/code/modules/events/anomaly_vortex.dm
+++ b/code/modules/events/anomaly_vortex.dm
@@ -14,7 +14,7 @@
if(prob(90))
priority_announce("Localized high-intensity vortex anomaly detected on long range scanners. Expected location: [impact_area.name]", "Anomaly Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/blob.dm b/code/modules/events/blob.dm
index c17918d733..d2a5c27883 100644
--- a/code/modules/events/blob.dm
+++ b/code/modules/events/blob.dm
@@ -4,6 +4,7 @@
weight = 10
max_occurrences = 1
+ earliest_start = 60 MINUTES
min_players = 40
gamemode_blacklist = list("blob") //Just in case a blob survives that long
@@ -15,9 +16,9 @@
/datum/round_event/ghost_role/blob/announce(fake)
if(prob(75))
- priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak5.ogg')
+ priority_announce("Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak5")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/brand_intelligence.dm b/code/modules/events/brand_intelligence.dm
index a838b62e0d..d422a0aa4f 100644
--- a/code/modules/events/brand_intelligence.dm
+++ b/code/modules/events/brand_intelligence.dm
@@ -38,7 +38,7 @@
if(prob(50))
priority_announce("Rampant brand intelligence has been detected aboard [station_name()]. Please stand by. The origin is believed to be \a [source].", "Machine Learning Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/carp_migration.dm b/code/modules/events/carp_migration.dm
index 71f19e5fd7..5a592d7f34 100644
--- a/code/modules/events/carp_migration.dm
+++ b/code/modules/events/carp_migration.dm
@@ -17,7 +17,7 @@
if(prob(50))
priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm
index f63ca39874..07a399a1b6 100644
--- a/code/modules/events/disease_outbreak.dm
+++ b/code/modules/events/disease_outbreak.dm
@@ -14,7 +14,7 @@
/datum/round_event/disease_outbreak/announce(fake)
- priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", 'sound/ai/outbreak7.ogg')
+ priority_announce("Confirmed outbreak of level 7 viral biohazard aboard [station_name()]. All personnel must contain the outbreak.", "Biohazard Alert", "outbreak7")
/datum/round_event/disease_outbreak/setup()
announceWhen = rand(15, 30)
diff --git a/code/modules/events/electrical_storm.dm b/code/modules/events/electrical_storm.dm
index 268a863ebc..10936409f9 100644
--- a/code/modules/events/electrical_storm.dm
+++ b/code/modules/events/electrical_storm.dm
@@ -15,7 +15,7 @@
if(prob(50))
priority_announce("An electrical storm has been detected in your area, please repair potential electronic overloads.", "Electrical Storm Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/grid_check.dm b/code/modules/events/grid_check.dm
index 8006d63b97..b289c8ae1b 100644
--- a/code/modules/events/grid_check.dm
+++ b/code/modules/events/grid_check.dm
@@ -9,7 +9,7 @@
startWhen = 1
/datum/round_event/grid_check/announce(fake)
- priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", 'sound/ai/poweroff.ogg')
+ priority_announce("Abnormal activity detected in [station_name()]'s powernet. As a precautionary measure, the station's power will be shut off for an indeterminate duration.", "Critical Power Failure", "poweroff")
/datum/round_event/grid_check/start()
diff --git a/code/modules/events/holiday/halloween.dm b/code/modules/events/holiday/halloween.dm
index 9b72020047..66495d833d 100644
--- a/code/modules/events/holiday/halloween.dm
+++ b/code/modules/events/holiday/halloween.dm
@@ -19,6 +19,7 @@
new /mob/living/simple_animal/parrot/Poly/ghost(Poly.loc)
qdel(Poly)
+
/datum/round_event/spooky/announce(fake)
priority_announce(pick("RATTLE ME BONES!","THE RIDE NEVER ENDS!", "A SKELETON POPS OUT!", "SPOOKY SCARY SKELETONS!", "CREWMEMBERS BEWARE, YOU'RE IN FOR A SCARE!") , "THE CALL IS COMING FROM INSIDE THE HOUSE")
diff --git a/code/modules/events/holiday/xmas.dm b/code/modules/events/holiday/xmas.dm
index a76c75dd43..65d96ad150 100644
--- a/code/modules/events/holiday/xmas.dm
+++ b/code/modules/events/holiday/xmas.dm
@@ -77,19 +77,7 @@
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
- santa.key = C.key
+ C.transfer_ckey(santa, FALSE)
- santa.equipOutfit(/datum/outfit/santa)
- santa.update_icons()
-
- var/datum/objective/santa_objective = new()
- santa_objective.explanation_text = "Bring joy and presents to the station!"
- santa_objective.completed = 1 //lets cut our santas some slack.
- santa_objective.owner = santa.mind
- santa.mind.objectives += santa_objective
- santa.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/conjure/presents)
- var/obj/effect/proc_holder/spell/targeted/area_teleport/teleport/telespell = new(santa)
- telespell.clothes_req = 0 //santa robes aren't actually magical.
- santa.mind.AddSpell(telespell) //does the station have chimneys? WHO KNOWS!
-
- to_chat(santa, "You are Santa! Your objective is to bring joy to the people on this station. You can conjure more presents using a spell, and there are several presents in your bag. ")
+ var/datum/antagonist/santa/A = new
+ santa.mind.add_antag_datum(A)
diff --git a/code/modules/events/ion_storm.dm b/code/modules/events/ion_storm.dm
index 3ae71f99d8..cd7c0e3b1f 100644
--- a/code/modules/events/ion_storm.dm
+++ b/code/modules/events/ion_storm.dm
@@ -26,7 +26,7 @@
/datum/round_event/ion_storm/announce(fake)
if(announceEvent == ION_ANNOUNCE || (announceEvent == ION_RANDOM && prob(ionAnnounceChance)) || fake)
- priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", 'sound/ai/ionstorm.ogg')
+ priority_announce("Ion storm detected near the station. Please check all AI-controlled equipment for errors.", "Anomaly Alert", "ionstorm")
/datum/round_event/ion_storm/start()
diff --git a/code/modules/events/major_dust.dm b/code/modules/events/major_dust.dm
index d1570ea09d..c08de985fb 100644
--- a/code/modules/events/major_dust.dm
+++ b/code/modules/events/major_dust.dm
@@ -19,7 +19,7 @@
if(prob(50))
priority_announce(pick(reason), "Collision Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/meateor_wave.dm b/code/modules/events/meateor_wave.dm
index 11af56526c..f668e2332c 100644
--- a/code/modules/events/meateor_wave.dm
+++ b/code/modules/events/meateor_wave.dm
@@ -1,11 +1,11 @@
-/datum/round_event_control/meteor_wave/meaty
- name = "Meteor Wave: Meaty"
- typepath = /datum/round_event/meteor_wave/meaty
- weight = 2
- max_occurrences = 1
-
-/datum/round_event/meteor_wave/meaty
- wave_name = "meaty"
-
-/datum/round_event/meteor_wave/meaty/announce(fake)
- priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.",'sound/ai/meteors.ogg')
+/datum/round_event_control/meteor_wave/meaty
+ name = "Meteor Wave: Meaty"
+ typepath = /datum/round_event/meteor_wave/meaty
+ weight = 2
+ max_occurrences = 1
+
+/datum/round_event/meteor_wave/meaty
+ wave_name = "meaty"
+
+/datum/round_event/meteor_wave/meaty/announce(fake)
+ priority_announce("Meaty ores have been detected on collision course with the station.", "Oh crap, get the mop.", "meteors")
diff --git a/code/modules/events/meteor_wave.dm b/code/modules/events/meteor_wave.dm
index af22ae3b96..4aa9fb305d 100644
--- a/code/modules/events/meteor_wave.dm
+++ b/code/modules/events/meteor_wave.dm
@@ -1,5 +1,8 @@
// Normal strength
+#define SINGULO_BEACON_DISTURBANCE 0.2 //singularity beacon also improve the odds of meteor waves and speed them up a little.
+#define SINGULO_BEACON_MAX_DISTURBANCE 0.6 //maximum cap due to how meteor waves can be potentially round ending.
+
/datum/round_event_control/meteor_wave
name = "Meteor Wave: Normal"
typepath = /datum/round_event/meteor_wave
@@ -18,6 +21,8 @@
/datum/round_event/meteor_wave/setup()
announceWhen = 1
startWhen = rand(300, 600) //Yeah for SOME REASON this is measured in seconds and not deciseconds???
+ if(GLOB.singularity_counter)
+ startWhen *= 1 - min(GLOB.singularity_counter * SINGULO_BEACON_DISTURBANCE, SINGULO_BEACON_MAX_DISTURBANCE)
endWhen = startWhen + 60
@@ -27,8 +32,6 @@
determine_wave_type()
/datum/round_event/meteor_wave/proc/determine_wave_type()
- if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
- wave_name = "halloween"
if(!wave_name)
wave_name = pickweight(list(
"normal" = 50,
@@ -40,7 +43,10 @@
if("threatening")
wave_type = GLOB.meteors_threatening
if("catastrophic")
- wave_type = GLOB.meteors_catastrophic
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ wave_type = GLOB.meteorsSPOOKY
+ else
+ wave_type = GLOB.meteors_catastrophic
if("meaty")
wave_type = GLOB.meteorsB
if("space dust")
@@ -52,7 +58,7 @@
kill()
/datum/round_event/meteor_wave/announce(fake)
- priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.", "Meteor Alert", 'sound/ai/meteors.ogg')
+ priority_announce("Meteors have been detected on collision course with the station. Estimated time until impact: [round(startWhen/60)] minutes.[GLOB.singularity_counter ? " Warning: Anomalous gravity pulse detected, Syndicate technology interference likely." : ""]", "Meteor Alert", "meteors")
/datum/round_event/meteor_wave/tick()
if(ISMULTIPLE(activeFor, 3))
@@ -79,3 +85,6 @@
/datum/round_event/meteor_wave/catastrophic
wave_name = "catastrophic"
+
+#undef SINGULO_BEACON_DISTURBANCE
+#undef SINGULO_BEACON_MAX_DISTURBANCE
diff --git a/code/modules/events/mice_migration.dm b/code/modules/events/mice_migration.dm
index 48a9f00423..911ce1dfbc 100644
--- a/code/modules/events/mice_migration.dm
+++ b/code/modules/events/mice_migration.dm
@@ -23,7 +23,7 @@
into the [location].", "Migration Alert",
'sound/effects/mousesqueek.ogg')
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/pirates.dm b/code/modules/events/pirates.dm
index 7256ddb6ea..477655db8b 100644
--- a/code/modules/events/pirates.dm
+++ b/code/modules/events/pirates.dm
@@ -25,7 +25,7 @@
ship_name = pick(strings(PIRATE_NAMES_FILE, "ship_names"))
/datum/round_event/pirates/announce(fake)
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
if(fake)
return
threat = new
@@ -77,7 +77,7 @@
else
notify_ghosts("Space pirates are waking up!", source = spawner, action=NOTIFY_ATTACK, flashwindow = FALSE)
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') //CITADEL EDIT also metabreak here too
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") //CITADEL EDIT also metabreak here too
//Shuttle equipment
diff --git a/code/modules/events/prison_break.dm b/code/modules/events/prison_break.dm
index 4d3beacbeb..24be0e5644 100644
--- a/code/modules/events/prison_break.dm
+++ b/code/modules/events/prison_break.dm
@@ -33,7 +33,7 @@
if(prob(50))
priority_announce("Gr3y.T1d3 virus detected in [station_name()] door subroutines. Severity level of [severity]. Recommend station AI involvement.", "Security Alert")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/radiation_storm.dm b/code/modules/events/radiation_storm.dm
index ba48779015..60e4e0e4b8 100644
--- a/code/modules/events/radiation_storm.dm
+++ b/code/modules/events/radiation_storm.dm
@@ -12,7 +12,7 @@
announceWhen = 1
/datum/round_event/radiation_storm/announce(fake)
- priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", 'sound/ai/radiation.ogg')
+ priority_announce("High levels of radiation detected near the station. Maintenance is best shielded from radiation.", "Anomaly Alert", "radiation")
//sound not longer matches the text, but an audible warning is probably good
/datum/round_event/radiation_storm/start()
diff --git a/code/modules/events/sentience.dm b/code/modules/events/sentience.dm
index 55d8ce8b14..96b6cded58 100644
--- a/code/modules/events/sentience.dm
+++ b/code/modules/events/sentience.dm
@@ -48,7 +48,7 @@
spawned_animals++
- SA.key = SG.key
+ SG.transfer_ckey(SA, FALSE)
SA.grant_all_languages(TRUE)
diff --git a/code/modules/events/shuttle_loan.dm b/code/modules/events/shuttle_loan.dm
index 769e32275b..3fe52c338b 100644
--- a/code/modules/events/shuttle_loan.dm
+++ b/code/modules/events/shuttle_loan.dm
@@ -32,7 +32,7 @@
if(prob(50))
priority_announce("Cargo: The syndicate are trying to infiltrate your station. If you let them hijack your cargo shuttle, you'll save us a headache.","CentCom Counter Intelligence")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
@@ -43,7 +43,7 @@
if(prob(50))
priority_announce("Cargo: A group of angry Russians want to have a party. Can you send them your cargo shuttle then make them disappear?","CentCom Russian Outreach Program")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
@@ -54,7 +54,7 @@
if(prob(50))
priority_announce("Cargo: The Spider Clan has sent us a mysterious gift. Can we ship it to you to see what's inside?","CentCom Diplomatic Corps")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
@@ -65,7 +65,7 @@
if(prob(50))
priority_announce("Cargo: Seems we've ordered doubles of our department resupply packages this month. Can we send them to you?","CentCom Supply Department")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
@@ -76,7 +76,7 @@
if(prob(50))
priority_announce("Cargo: Your station has been chosen for an epidemiological research project. Send us your cargo shuttle to receive your research samples.", "CentCom Research Initiatives")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
@@ -87,7 +87,7 @@
if(prob(50))
priority_announce("Cargo: It looks like a neighbouring station accidentally delivered their pizza to you instead.", "CentCom Spacepizza Division")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
@@ -98,7 +98,7 @@
if(prob(50))
priority_announce("Cargo: One of our freighters carrying a bee shipment has been attacked by eco-terrorists. Can you clean up the mess for us?", "CentCom Janitorial Division")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
@@ -110,7 +110,7 @@
if(prob(50))
priority_announce("Cargo: We have discovered an active Syndicate bomb near our VIP shuttle's fuel lines. If you feel up to the task, we will pay you for defusing it.", "CentCom Security Division")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
@@ -122,7 +122,7 @@
if(prob(50))
priority_announce("Cargo: We have discovered a warehouse of DELTA locked crates, we cant store any more of them at CC can you take them for us?.", "CentCom Security Division")
else
- priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", 'sound/ai/commandreport.ogg') // CITADEL EDIT metabreak
+ priority_announce("A report has been downloaded and printed out at all communications consoles.", "Incoming Classified Message", "commandreport") // CITADEL EDIT metabreak
for(var/obj/machinery/computer/communications/C in GLOB.machines)
if(!(C.stat & (BROKEN|NOPOWER)) && is_station_level(C.z))
var/obj/item/paper/P = new(C.loc)
diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm
index d8906de036..cb25446e4a 100644
--- a/code/modules/events/spacevine.dm
+++ b/code/modules/events/spacevine.dm
@@ -251,7 +251,7 @@
holder.obj_integrity = holder.max_integrity
/datum/spacevine_mutation/woodening/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage)
- if(I.is_sharp())
+ if(I.get_sharpness())
. = expected_damage * 0.5
else
. = expected_damage
@@ -331,7 +331,7 @@
/obj/structure/spacevine/attacked_by(obj/item/I, mob/living/user)
var/damage_dealt = I.force
- if(I.is_sharp())
+ if(I.get_sharpness())
damage_dealt *= 4
if(I.damtype == BURN)
damage_dealt *= 4
diff --git a/code/modules/events/spider_infestation.dm b/code/modules/events/spider_infestation.dm
index 58c52cbec3..a6c333145e 100644
--- a/code/modules/events/spider_infestation.dm
+++ b/code/modules/events/spider_infestation.dm
@@ -16,7 +16,7 @@
spawncount = rand(5, 8)
/datum/round_event/spider_infestation/announce(fake)
- priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", 'sound/ai/aliens.ogg')
+ priority_announce("Unidentified lifesigns detected coming aboard [station_name()]. Secure any exterior access, including ducting and ventilation.", "Lifesign Alert", "aliens")
/datum/round_event/spider_infestation/start()
diff --git a/code/modules/events/wizard/greentext.dm b/code/modules/events/wizard/greentext.dm
index 356e83757f..82e72df3b9 100644
--- a/code/modules/events/wizard/greentext.dm
+++ b/code/modules/events/wizard/greentext.dm
@@ -40,7 +40,8 @@
/obj/item/greentext/equipped(mob/living/user as mob)
to_chat(user, "So long as you leave this place with greentext in hand you know will be happy... ")
- if(user.mind && user.mind.objectives.len > 0)
+ var/list/other_objectives = user.mind.get_all_objectives()
+ if(user.mind && other_objectives.len > 0)
to_chat(user, "... so long as you still perform your other objectives that is! ")
new_holder = user
if(!last_holder)
diff --git a/code/modules/events/wizard/imposter.dm b/code/modules/events/wizard/imposter.dm
index 1c8ef95baa..29704168e9 100644
--- a/code/modules/events/wizard/imposter.dm
+++ b/code/modules/events/wizard/imposter.dm
@@ -23,7 +23,7 @@
I.name = I.dna.real_name
I.updateappearance(mutcolor_update=1)
I.domutcheck()
- I.key = C.key
+ C.transfer_ckey(I, FALSE)
var/datum/antagonist/wizard/master = M.has_antag_datum(/datum/antagonist/wizard)
if(!master.wiz_team)
master.create_wiz_team()
diff --git a/code/modules/events/wizard/magicarp.dm b/code/modules/events/wizard/magicarp.dm
index ab23c30e00..57e2a2a051 100644
--- a/code/modules/events/wizard/magicarp.dm
+++ b/code/modules/events/wizard/magicarp.dm
@@ -36,10 +36,11 @@
projectilesound = 'sound/weapons/emitter.ogg'
maxHealth = 50
health = 50
+ gold_core_spawnable = NO_SPAWN
var/allowed_projectile_types = list(/obj/item/projectile/magic/change, /obj/item/projectile/magic/animate, /obj/item/projectile/magic/resurrection,
/obj/item/projectile/magic/death, /obj/item/projectile/magic/teleport, /obj/item/projectile/magic/door, /obj/item/projectile/magic/aoe/fireball,
/obj/item/projectile/magic/spellblade, /obj/item/projectile/magic/arcane_barrage)
-
+
/mob/living/simple_animal/hostile/carp/ranged/Initialize()
projectiletype = pick(allowed_projectile_types)
. = ..()
diff --git a/code/modules/events/wizard/rpgloot.dm b/code/modules/events/wizard/rpgloot.dm
index 420582ddab..bf3104450e 100644
--- a/code/modules/events/wizard/rpgloot.dm
+++ b/code/modules/events/wizard/rpgloot.dm
@@ -8,12 +8,15 @@
/datum/round_event/wizard/rpgloot/start()
var/upgrade_scroll_chance = 0
for(var/obj/item/I in world)
- if(!istype(I.rpg_loot))
- I.rpg_loot = new(I)
+ CHECK_TICK
+ if(!(I.flags_1 & INITIALIZED_1))
+ continue
+
+ I.AddComponent(/datum/component/fantasy)
if(istype(I, /obj/item/storage))
var/obj/item/storage/S = I
- GET_COMPONENT_FROM(STR, /datum/component/storage, S)
+ var/datum/component/storage/STR = S.GetComponent(/datum/component/storage)
if(prob(upgrade_scroll_chance) && S.contents.len < STR.max_items && !S.invisibility)
var/obj/item/upgradescroll/scroll = new
SEND_SIGNAL(S, COMSIG_TRY_STORAGE_INSERT, scroll, null, TRUE, TRUE)
@@ -31,86 +34,20 @@
var/upgrade_amount = 1
var/can_backfire = TRUE
- var/one_use = TRUE
+ var/uses = 1
/obj/item/upgradescroll/afterattack(obj/item/target, mob/user , proximity)
. = ..()
if(!proximity || !istype(target))
return
- var/datum/rpg_loot/rpg_loot_datum = target.rpg_loot
- if(!istype(rpg_loot_datum))
- target.rpg_loot = rpg_loot_datum = new /datum/rpg_loot(target)
+ target.AddComponent(/datum/component/fantasy, upgrade_amount, null, null, can_backfire, TRUE)
- var/quality = rpg_loot_datum.quality
-
- if(can_backfire && (quality > 9 && prob((quality - 9)*10)))
- to_chat(user, "[target] violently glows blue for a while, then evaporates. ")
- target.burn()
- else
- to_chat(user, "[target] glows blue and seems vaguely \"better\"! ")
- rpg_loot_datum.modify(upgrade_amount)
-
- if(one_use)
+ if(--uses <= 0)
qdel(src)
/obj/item/upgradescroll/unlimited
name = "unlimited foolproof item fortification scroll"
desc = "Somehow, this piece of paper can be applied to items to make them \"better\". This scroll is made from the tongues of dead paper wizards, and can be used an unlimited number of times, with no drawbacks."
- one_use = FALSE
+ uses = INFINITY
can_backfire = FALSE
-
-/datum/rpg_loot
- var/positive_prefix = "okay"
- var/negative_prefix = "weak"
- var/suffix = "something profound"
- var/quality = 0
-
- var/obj/item/attached
- var/original_name
-
-/datum/rpg_loot/New(attached_item=null)
- attached = attached_item
-
- randomise()
-
-/datum/rpg_loot/Destroy()
- attached = null
-
-/datum/rpg_loot/proc/randomise()
- var/static/list/prefixespositive = list("greater", "major", "blessed", "superior", "empowered", "honed", "true", "glorious", "robust")
- var/static/list/prefixesnegative = list("lesser", "minor", "blighted", "inferior", "enfeebled", "rusted", "unsteady", "tragic", "gimped")
- var/static/list/suffixes = list("orc slaying", "elf slaying", "corgi slaying", "strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma", "the forest", "the hills", "the plains", "the sea", "the sun", "the moon", "the void", "the world", "the fool", "many secrets", "many tales", "many colors", "rending", "sundering", "the night", "the day")
-
- var/new_quality = pick(1;15, 2;14, 2;13, 2;12, 3;11, 3;10, 3;9, 4;8, 4;7, 4;6, 5;5, 5;4, 5;3, 6;2, 6;1, 6;0)
-
- suffix = pick(suffixes)
- positive_prefix = pick(prefixespositive)
- negative_prefix = pick(prefixesnegative)
-
- if(prob(50))
- new_quality = -new_quality
-
- modify(new_quality)
-
-/datum/rpg_loot/proc/rename()
- var/obj/item/I = attached
- if(!original_name)
- original_name = I.name
- if(quality < 0)
- I.name = "[negative_prefix] [original_name] of [suffix] [quality]"
- else if(quality == 0)
- I.name = "[original_name] of [suffix]"
- else if(quality > 0)
- I.name = "[positive_prefix] [original_name] of [suffix] +[quality]"
-
-/datum/rpg_loot/proc/modify(quality_mod)
- var/obj/item/I = attached
- quality += quality_mod
-
- I.force = max(0,I.force + quality_mod)
- I.throwforce = max(0,I.throwforce + quality_mod)
-
- I.armor = I.armor.modifyAllRatings(quality)
-
- rename()
diff --git a/code/modules/events/wormholes.dm b/code/modules/events/wormholes.dm
index bb601b7c82..9dbe1443d1 100644
--- a/code/modules/events/wormholes.dm
+++ b/code/modules/events/wormholes.dm
@@ -29,7 +29,7 @@
wormholes += new /obj/effect/portal/wormhole(T, null, 0, null, FALSE)
/datum/round_event/wormholes/announce(fake)
- priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", 'sound/ai/spanomalies.ogg')
+ priority_announce("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert", "spanomalies")
/datum/round_event/wormholes/tick()
if(activeFor % shift_frequency == 0)
diff --git a/code/modules/fields/fields.dm b/code/modules/fields/fields.dm
index 5e34c934d9..5b0b4bc1f8 100644
--- a/code/modules/fields/fields.dm
+++ b/code/modules/fields/fields.dm
@@ -283,7 +283,7 @@
var/field_type = /datum/proximity_monitor/advanced/debug
var/operating = FALSE
var/datum/proximity_monitor/advanced/current = null
- var/datum/component/mobhook
+ var/mob/listeningTo
/obj/item/multitool/field_debug/Initialize()
. = ..()
@@ -292,7 +292,7 @@
/obj/item/multitool/field_debug/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_NULL(current)
- QDEL_NULL(mobhook)
+ listeningTo = null
return ..()
/obj/item/multitool/field_debug/proc/setup_debug_field()
@@ -303,16 +303,20 @@
/obj/item/multitool/field_debug/attack_self(mob/user)
operating = !operating
to_chat(user, "You turn [src] [operating? "on":"off"].")
- QDEL_NULL(mobhook)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
if(!istype(current) && operating)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_mob_move)))
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
+ listeningTo = user
setup_debug_field()
else if(!operating)
QDEL_NULL(current)
/obj/item/multitool/field_debug/dropped()
. = ..()
- QDEL_NULL(mobhook)
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
/obj/item/multitool/field_debug/proc/on_mob_move()
check_turf(get_turf(src))
diff --git a/code/modules/fields/timestop.dm b/code/modules/fields/timestop.dm
index 11a5d416e7..a063296edf 100644
--- a/code/modules/fields/timestop.dm
+++ b/code/modules/fields/timestop.dm
@@ -133,6 +133,7 @@
/datum/proximity_monitor/advanced/timestop/proc/freeze_mob(mob/living/L)
if(L.anti_magic_check(check_anti_magic, check_holy))
+ immune += L
return
L.Stun(20, 1, 1)
frozen_mobs[L] = L.anchored
diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm
index 88f72d27c3..48704d7623 100644
--- a/code/modules/flufftext/Hallucination.dm
+++ b/code/modules/flufftext/Hallucination.dm
@@ -236,10 +236,10 @@ GLOBAL_LIST_INIT(hallucination_list, list(
xeno = new(pump.loc,target)
sleep(10)
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
- xeno.throw_at(target,7,1, xeno, FALSE, TRUE)
+ xeno.throw_at(target,7,1, null, FALSE, TRUE)
sleep(10)
xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32)
- xeno.throw_at(pump,7,1, xeno, FALSE, TRUE)
+ xeno.throw_at(pump,7,1, null, FALSE, TRUE)
sleep(10)
var/xeno_name = xeno.name
to_chat(target, "[xeno_name] begins climbing into the ventilation system... ")
@@ -771,7 +771,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
..()
var/turf/source = random_far_turf()
if(!sound_type)
- sound_type = pick("airlock","airlock pry","console","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
+ sound_type = pick("airlock","airlock pry","console","flash","explosion","far explosion","mech","glass","alarm","beepsky","mech","wall decon","door hack")
feedback_details += "Type: [sound_type]"
//Strange audio
switch(sound_type)
@@ -788,6 +788,8 @@ GLOBAL_LIST_INIT(hallucination_list, list(
target.playsound_local(source,'sound/effects/explosion1.ogg', 50, 1)
else
target.playsound_local(source, 'sound/effects/explosion2.ogg', 50, 1)
+ if("flash")
+ target.playsound_local(source, 'sound/weapons/flash.ogg', 50, 1)
if("far explosion")
target.playsound_local(source, 'sound/effects/explosionfar.ogg', 50, 1)
if("glass")
@@ -876,7 +878,7 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if("blob alert")
to_chat(target, "Biohazard Alert ")
to_chat(target, "Confirmed outbreak of level 5 biohazard aboard [station_name()]. All personnel must contain the outbreak. ")
- SEND_SOUND(target, 'sound/ai/outbreak5.ogg')
+ SEND_SOUND(target, get_announcer_sound("outbreak5"))
if("ratvar")
target.playsound_local(target, 'sound/machines/clockcult/ark_deathrattle.ogg', 50, FALSE, pressure_affected = FALSE)
target.playsound_local(target, 'sound/effects/clockcult_gateway_disrupted.ogg', 50, FALSE, pressure_affected = FALSE)
@@ -885,15 +887,15 @@ GLOBAL_LIST_INIT(hallucination_list, list(
if("shuttle dock")
to_chat(target, "Priority Announcement ")
to_chat(target, "The Emergency Shuttle has docked with the station. You have 3 minutes to board the Emergency Shuttle. ")
- SEND_SOUND(target, 'sound/ai/shuttledock.ogg')
+ SEND_SOUND(target, get_announcer_sound("shuttledock"))
if("malf ai") //AI is doomsdaying!
to_chat(target, "Anomaly Alert ")
to_chat(target, "Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core. ")
- SEND_SOUND(target, 'sound/ai/aimalf.ogg')
+ SEND_SOUND(target, get_announcer_sound("aimalf"))
if("meteors") //Meteors inbound!
to_chat(target, "Meteor Alert ")
- to_chat(target, "Meteors have been detected on collision course with the station. ")
- SEND_SOUND(target, 'sound/ai/meteors.ogg')
+ to_chat(target, "Meteors have been detected on collision course with the station. Estimated time until impact: [round(rand(300,600)/60)] minutes. ")
+ SEND_SOUND(target, get_announcer_sound("meteors"))
if("supermatter")
SEND_SOUND(target, 'sound/magic/charge.ogg')
to_chat(target, "You feel reality distort for a moment... ")
@@ -1291,4 +1293,4 @@ GLOBAL_LIST_INIT(hallucination_list, list(
H.hal_target = target
H.preparePixelProjectile(target, start)
H.fire()
- qdel(src)
\ No newline at end of file
+ qdel(src)
diff --git a/code/modules/food_and_drinks/drinks/drinks.dm b/code/modules/food_and_drinks/drinks/drinks.dm
index 7b1d8be85e..5bf7e3dff3 100644
--- a/code/modules/food_and_drinks/drinks/drinks.dm
+++ b/code/modules/food_and_drinks/drinks/drinks.dm
@@ -95,7 +95,7 @@
to_chat(user, "You fill [src] with [trans] units of the contents of [target]. ")
/obj/item/reagent_containers/food/drinks/attackby(obj/item/I, mob/user, params)
- var/hotness = I.is_hot()
+ var/hotness = I.get_temperature()
if(hotness && reagents)
reagents.expose_temperature(hotness)
to_chat(user, "You heat [name] with [I]! ")
diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
index e72b624ae5..c5a962230a 100644
--- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm
+++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm
@@ -455,7 +455,7 @@
..()
/obj/item/reagent_containers/food/drinks/bottle/molotov/attackby(obj/item/I, mob/user, params)
- if(I.is_hot() && !active)
+ if(I.get_temperature() && !active)
active = 1
var/message = "[ADMIN_LOOKUP(user)] has primed a [name] for detonation at [ADMIN_VERBOSEJMP(user)]."
GLOB.bombers += message
diff --git a/code/modules/food_and_drinks/food/snacks.dm b/code/modules/food_and_drinks/food/snacks.dm
index 7eea6fb9ca..637e0b929c 100644
--- a/code/modules/food_and_drinks/food/snacks.dm
+++ b/code/modules/food_and_drinks/food/snacks.dm
@@ -181,7 +181,7 @@ All foods are distributed among various categories. Use common sense.
var/obj/item/reagent_containers/food/snacks/customizable/C = new custom_food_type(get_turf(src))
C.initialize_custom_food(src, S, user)
return 0
- var/sharp = W.is_sharp()
+ var/sharp = W.get_sharpness()
if(sharp)
if(slice(sharp, W, user))
return 1
@@ -337,7 +337,7 @@ All foods are distributed among various categories. Use common sense.
/obj/item/reagent_containers/food/snacks/store/attackby(obj/item/W, mob/user, params)
..()
if(W.w_class <= WEIGHT_CLASS_SMALL & !istype(W, /obj/item/reagent_containers/food/snacks)) //can't slip snacks inside, they're used for custom foods.
- if(W.is_sharp())
+ if(W.get_sharpness())
return 0
if(stored_item)
return 0
diff --git a/code/modules/food_and_drinks/food/snacks_cake.dm b/code/modules/food_and_drinks/food/snacks_cake.dm
index 98f80331a7..7dadd2b12e 100644
--- a/code/modules/food_and_drinks/food/snacks_cake.dm
+++ b/code/modules/food_and_drinks/food/snacks_cake.dm
@@ -272,7 +272,7 @@
/obj/item/reagent_containers/food/snacks/cakeslice/bscc
name = "blackberry and strawberry chocolate cake slice"
desc = "Just a slice of cake filled with assortment of blackberries and strawberries!"
- icon_state = "blackbarry_strawberries_cake_coco_cake_slice"
+ icon_state = "blackbarry_strawberries_cake_coco_slice"
filling_color = "#FFD700"
tastes = list("blackberry" = 2, "strawberries" = 2, "chocolate" = 2, "sweetness" = 2,"cake" = 3)
foodtype = GRAIN | DAIRY | FRUIT | SUGAR
diff --git a/code/modules/food_and_drinks/food/snacks_pastry.dm b/code/modules/food_and_drinks/food/snacks_pastry.dm
index 9b87002738..b468b6b1d1 100644
--- a/code/modules/food_and_drinks/food/snacks_pastry.dm
+++ b/code/modules/food_and_drinks/food/snacks_pastry.dm
@@ -38,9 +38,7 @@
if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM) && !HAS_TRAIT(H, TRAIT_AGEUSIA))
to_chat(H,"I love this taste! ")
H.adjust_disgust(-5 + -2.5 * fraction)
- GET_COMPONENT_FROM(mood, /datum/component/mood, H)
- if(mood)
- mood.add_event(null, "fav_food", /datum/mood_event/favorite_food)
+ SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "fav_food", /datum/mood_event/favorite_food)
last_check_time = world.time
return
..()
diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
index 483055cb0d..ceb7a01ede 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm
@@ -144,6 +144,13 @@
else
O.forceMove(src)
return TRUE
+
+///Really simple proc, just moves the object "O" into the hands of mob "M" if able, done so I could modify the proc a little for the organ fridge
+/obj/machinery/smartfridge/proc/dispense(obj/item/O, var/mob/M)
+ if(!M.put_in_hands(O))
+ O.forceMove(drop_location())
+ adjust_item_drop_location(O)
+
/obj/machinery/smartfridge/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
@@ -197,9 +204,7 @@
if(desired == 1 && Adjacent(usr) && !issilicon(usr))
for(var/obj/item/O in src)
if(O.name == params["name"])
- if(!usr.put_in_hands(O))
- O.forceMove(drop_location())
- adjust_item_drop_location(O)
+ dispense(O, usr)
break
if (visible_contents)
update_icon()
@@ -209,8 +214,7 @@
if(desired <= 0)
break
if(O.name == params["name"])
- O.forceMove(drop_location())
- adjust_item_drop_location(O)
+ dispense(O, usr)
desired--
if (visible_contents)
update_icon()
@@ -378,6 +382,44 @@
/obj/machinery/smartfridge/extract/preloaded
initial_contents = list(/obj/item/slime_scanner = 2)
+// ------------------------- You think you're better than Chem, huh?
+// Organ Surgery Smartfridge
+// ------------------------- Just wait till Tamiorgans
+/obj/machinery/smartfridge/organ
+ name = "smart organ storage"
+ desc = "A refrigerated storage unit for organ storage."
+ max_n_of_items = 20 //vastly lower to prevent processing too long
+ var/repair_rate = 0
+
+/obj/machinery/smartfridge/organ/accept_check(obj/item/O)
+ if(istype(O, /obj/item/organ))
+ return TRUE
+ return FALSE
+
+/obj/machinery/smartfridge/organ/load(obj/item/O)
+ . = ..()
+ if(!.) //if the item loads, clear can_decompose
+ return
+ var/obj/item/organ/organ = O
+ organ.organ_flags |= ORGAN_FROZEN
+
+/obj/machinery/smartfridge/organ/RefreshParts()
+ for(var/obj/item/stock_parts/matter_bin/B in component_parts)
+ max_n_of_items = 20 * B.rating
+ repair_rate = max(0, STANDARD_ORGAN_HEALING * (B.rating - 1))
+
+/obj/machinery/smartfridge/organ/process()
+ for(var/organ in contents)
+ var/obj/item/organ/O = organ
+ if(!istype(O))
+ return
+ O.applyOrganDamage(-repair_rate)
+
+/obj/machinery/smartfridge/organ/Exited(obj/item/organ/AM, atom/newLoc)
+ . = ..()
+ if(istype(AM))
+ AM.organ_flags &= ~ORGAN_FROZEN
+
// -----------------------------
// Chemistry Medical Smartfridge
// -----------------------------
diff --git a/code/modules/food_and_drinks/recipes/drinks_recipes.dm b/code/modules/food_and_drinks/recipes/drinks_recipes.dm
index 6880260c4c..c83048e4b1 100644
--- a/code/modules/food_and_drinks/recipes/drinks_recipes.dm
+++ b/code/modules/food_and_drinks/recipes/drinks_recipes.dm
@@ -397,13 +397,16 @@
FermiChem = TRUE//If the chemical uses the Fermichem reaction mechanics
FermiExplode = FALSE //If the chemical explodes in a special way
PurityMin = 0 //The minimum purity something has to be above, otherwise it explodes.
+ clear_conversion = REACTION_CLEAR_INVERSE
+/*
/datum/chemical_reaction/neurotoxin/FermiFinish(datum/reagents/holder, var/atom/my_atom)
var/datum/reagent/consumable/ethanol/neurotoxin/Nt = locate(/datum/reagent/consumable/ethanol/neurotoxin) in my_atom.reagents.reagent_list
var/cached_volume = Nt.volume
if(Nt.purity < 0.5)
holder.remove_reagent(src.id, cached_volume)
holder.add_reagent("neuroweak", cached_volume)
+*/
/datum/chemical_reaction/neurotoxin/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH)//reduced size
volume = volume/10
@@ -816,10 +819,10 @@
id = "catnip_tea"
results = list("catnip_tea" = 3)
required_reagents = list("tea" = 5, "catnip" = 2)
-
+
/datum/chemical_reaction/commander_and_chief
- name = "Commander and Chief"
- id = "commander_and_chief"
- results = list("commander_and_chief" = 50)
+ name = "Commander and Chief"
+ id = "commander_and_chief"
+ results = list("commander_and_chief" = 50)
required_reagents = list("alliescocktail" = 50, "champagne" = 20, "doctorsdelight" = 10, "quintuple_sec" = 10, "screwdrivercocktail" = 10)
- mix_message = "When your powers combine, I am Captain Pl-..."
+ mix_message = "When your powers combine, I am Captain Pl-..."
diff --git a/code/modules/goonchat/browserOutput.dm b/code/modules/goonchat/browserOutput.dm
index 082f20f524..c273690571 100644
--- a/code/modules/goonchat/browserOutput.dm
+++ b/code/modules/goonchat/browserOutput.dm
@@ -82,11 +82,13 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
if("setMusicVolume")
data = setMusicVolume(arglist(params))
- if("swaptodarkmode")
- swaptodarkmode()
+ if("colorPresetPost") //User just swapped color presets in their goonchat preferences. Do we do anything else?
+ switch(href_list["preset"])
+ if("light")
+ owner.force_white_theme()
+ if("dark" || "normal")
+ owner.force_dark_theme()
- if("swaptolightmode")
- swaptolightmode()
if(data)
ehjax_send(data = data)
@@ -160,7 +162,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
var/list/row = src.connectionHistory[i]
if (!row || row.len < 3 || (!row["ckey"] || !row["compid"] || !row["ip"])) //Passed malformed history object
return
- if (world.IsBanned(row["ckey"], row["compid"], row["ip"], real_bans_only=TRUE))
+ if (world.IsBanned(row["ckey"], row["ip"], row["compid"], real_bans_only=TRUE))
found = row
break
@@ -181,8 +183,8 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
log_world("\[[time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")]\] Client: [(src.owner.key ? src.owner.key : src.owner)] triggered JS error: [error]")
//Global chat procs
-/proc/to_chat(target, message, handle_whitespace=TRUE)
- if(!target)
+/proc/to_chat_immediate(target, message, handle_whitespace=TRUE)
+ if(!target || !message)
return
//Ok so I did my best but I accept that some calls to this will be for shit like sound and images
@@ -204,7 +206,7 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
message = replacetext(message, "\proper", "")
if(handle_whitespace)
message = replacetext(message, "\n", " ")
- message = replacetext(message, "\t", "[GLOB.TAB][GLOB.TAB]")
+ message = replacetext(message, "\t", "[FOURSPACES][FOURSPACES]")
if(islist(target))
// Do the double-encoding outside the loop to save nanoseconds
@@ -247,6 +249,11 @@ GLOBAL_DATUM_INIT(iconCache, /savefile, new("tmp/iconCache.sav")) //Cache of ico
// url_encode it TWICE, this way any UTF-8 characters are able to be decoded by the Javascript.
C << output(url_encode(url_encode(message)), "browseroutput:output")
+/proc/to_chat(target, message, handle_whitespace = TRUE)
+ if(Master.current_runlevel == RUNLEVEL_INIT || !SSchat?.initialized)
+ to_chat_immediate(target, message, handle_whitespace)
+ return
+ SSchat.queue(target, message, handle_whitespace)
/datum/chatOutput/proc/swaptolightmode() //Dark mode light mode stuff. Yell at KMC if this breaks! (See darkmode.dm for documentation)
owner.force_white_theme()
diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css
index 7b942494f4..d6918d58aa 100644
--- a/code/modules/goonchat/browserassets/css/browserOutput.css
+++ b/code/modules/goonchat/browserassets/css/browserOutput.css
@@ -7,20 +7,16 @@ html, body {
padding: 0;
margin: 0;
height: 100%;
- color: #f0f0f0;
+ color: #000000;
}
body {
- background: #171717;
+ background: #E0E0E0; /*CIT CHANGE - darkens chatbox a lil*/
font-family: Verdana, sans-serif;
- font-size: 9pt;
- font-color: #f0f0f0;
+ font-size: 13px;
line-height: 1.2;
overflow-x: hidden;
overflow-y: scroll;
- word-wrap: break-word;
- scrollbar-face-color:#1A1A1A;
- scrollbar-track-color:#171717;
- scrollbar-highlight-color:#171717;
+ word-wrap: break-word;
}
em {
@@ -60,9 +56,9 @@ img.icon {
border-radius: 10px;
}
-a {color: #397ea5;}
-a.visited {color: #7c00e6;}
-a:visited {color: #7c00e6;}
+a {color: #0000ff;}
+a.visited {color: #ff00ff;}
+a:visited {color: #ff00ff;}
a.popt {text-decoration: none;}
/*****************************************
@@ -93,21 +89,21 @@ a.popt {text-decoration: none;}
bottom: 0;
right: 0;
padding: 8px;
- background: #202020;
+ background: #d0d0d0;
text-decoration: none;
font-variant: small-caps;
font-size: 1.1em;
font-weight: bold;
- color: #a4bad6;
+ color: #333;
}
-#newMessages:hover {background: #171717;}
+#newMessages:hover {background: #ccc;}
#newMessages i {vertical-align: middle; padding-left: 3px;}
#ping {
position: fixed;
top: 0;
right: 115px;
width: 45px;
- background: #202020;
+ background: #d0d0d0;
height: 30px;
padding: 8px 0 2px 0;
}
@@ -124,19 +120,19 @@ a.popt {text-decoration: none;}
right: 0;
}
#userBar .subCell {
- background: #202020;
+ background: #d0d0d0;
height: 30px;
padding: 5px 0;
display: block;
- color: #a4bad6;
+ color: #333;
text-decoration: none;
line-height: 28px;
- border-top: 1px solid #171717;
+ border-top: 1px solid #b4b4b4;
}
-#userBar .subCell:hover {background: #202020;}
+#userBar .subCell:hover {background: #ccc;}
#userBar .toggle {
width: 40px;
- background: #202020;
+ background: #ccc;
border-top: 0;
float: right;
text-align: center;
@@ -172,7 +168,7 @@ a.popt {text-decoration: none;}
position: fixed;
top: 50%;
left: 50%;
- background: #ddd;
+ background: #d0d0d0;
}
.popup .close {
position: absolute;
@@ -189,7 +185,7 @@ a.popt {text-decoration: none;}
.popup .close:hover {background: #999;}
.popup .head {
background: #999;
- color: #ddd;
+ color: #d0d0d0;
padding: 0 10px;
height: 30px;
line-height: 30px;
@@ -200,7 +196,7 @@ a.popt {text-decoration: none;}
}
.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;}
.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;}
-.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;}
+.popup input[type=submit] {padding: 5px 10px; background: #999; color: #d0d0d0; text-transform: uppercase; font-size: 0.9em; font-weight: bold;}
.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;}
.changeFont {padding: 10px;}
@@ -214,7 +210,7 @@ a.popt {text-decoration: none;}
/* ADMIN CONTEXT MENU */
.contextMenu {
- background-color: #ddd;
+ background-color: #d0d0d0;
position: fixed;
margin: 2px;
width: 150px;
@@ -246,9 +242,9 @@ a.popt {text-decoration: none;}
******************************************/
/* MOTD */
-.motd {color: #a4bad6; font-family: Verdana, sans-serif;}
-.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #a4bad6; text-decoration: underline;}
-.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #a4bad6;}
+.motd {color: #638500; font-family: Verdana, sans-serif;}
+.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;}
+.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;}
/* ADD HERE FOR BOLD */
.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;}
@@ -259,151 +255,153 @@ a.popt {text-decoration: none;}
/* OUTPUT COLORS */
.highlight {background: yellow;}
-h1, h2, h3, h4, h5, h6 {color: #a4bad6;font-family: Georgia, Verdana, sans-serif;}
-h1.alert, h2.alert {color: #a4bad6;}
+h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;}
+h1.alert, h2.alert {color: #000000;}
em {font-style: normal; font-weight: bold;}
-.ooc {color: #cca300; font-weight: bold;}
-.antagooc {color: #ce254f; font-weight: bold;}
+.ooc {color: #002eb8; font-weight: bold;}
+.looc {color: #6699CC; font-weight: bold;}
+.antagooc {color: #b8002e; font-weight: bold;}
.adminobserverooc {color: #0099cc; font-weight: bold;}
-.adminooc {color: #3d5bc3; font-weight: bold;}
+.adminooc {color: #700038; font-weight: bold;}
-.adminsay {color: #ff4500; font-weight: bold;}
-.admin {color: #5975da; font-weight: bold;}
+.adminsay {color: #FF4500}
+.admin {color: #386aff; font-weight: bold;}
.name { font-weight: bold;}
.say {}
-.deadsay {color: #e2c1ff;}
+.deadsay {color: #5c00e6;}
.binarysay {color: #20c20e; background-color: #000000; display: block;}
.binarysay a {color: #00ff00;}
.binarysay a:active, .binarysay a:visited {color: #88ff88;}
-.radio {color: #1ecc43;}
-.sciradio {color: #c68cfa;}
-.comradio {color: #5177ff;}
-.secradio {color: #dd3535;}
-.medradio {color: #57b8f0;}
-.engradio {color: #f37746;}
-.suppradio {color: #b88646;}
-.servradio {color: #6ca729;}
-.syndradio {color: #8f4a4b;}
-.centcomradio {color: #2681a5;}
-.aiprivradio {color: #d65d95;}
-.redteamradio {color: #ff4444;}
-.blueteamradio {color: #3434fd;}
+.radio {color: #008000;}
+.sciradio {color: #993399;}
+.comradio {color: #948f02;}
+.secradio {color: #a30000;}
+.medradio {color: #337296;}
+.engradio {color: #fb5613;}
+.suppradio {color: #a8732b;}
+.servradio {color: #6eaa2c;}
+.syndradio {color: #6d3f40;}
+.centcomradio {color: #686868;}
+.aiprivradio {color: #ff00ff;}
+.redteamradio {color: #ff0000;}
+.blueteamradio {color: #0000ff;}
.yell { font-weight: bold;}
-.alert {color: #d82020;}
-h1.alert, h2.alert {color: #99aab5;}
+.alert {color: #ff0000;}
+h1.alert, h2.alert {color: #000000;}
.emote { font-style: italic;}
.selecteddna {color: #ffffff; background-color: #001B1B}
-.attack {color: #e01c1c;}
-.disarm {color: #b42525;}
-.passive {color: #a00f0f;}
+.attack {color: #ff0000;}
+.disarm {color: #990000;}
+.passive {color: #660000;}
-.userdanger {color: #c51e1e; font-weight: bold; font-size: 24px;}
-.danger {color: #c51e1e;}
-.warning {color: #c51e1e; font-style: italic;}
+.userdanger {color: #ff0000; font-weight: bold; font-size: 185%;}
+.danger {color: #ff0000;}
+.warning {color: #ff0000; font-style: italic;}
.alertwarning {color: #FF0000; font-weight: bold}
-.boldwarning {color: #c51e1e; font-style: italic; font-weight: bold}
-.announce {color: #c51e1e; font-weight: bold;}
-.boldannounce {color: #c51e1e; font-weight: bold;}
-.greenannounce {color: #059223; font-weight: bold;}
+.boldwarning {color: #ff0000; font-style: italic; font-weight: bold}
+.announce {color: #228b22; font-weight: bold;}
+.boldannounce {color: #ff0000; font-weight: bold;}
+.greenannounce {color: #00ff00; font-weight: bold;}
.rose {color: #ff5050;}
-.info {color: #6685f5;}
-.notice {color: #6685f5;}
-.boldnotice {color: #6685f5; font-weight: bold;}
-.adminnotice {color: #6685f5;}
+.info {color: #0000CC;}
+.notice {color: #000099;}
+.boldnotice {color: #000099; font-weight: bold;}
+.adminnotice {color: #0000ff;}
.adminhelp {color: #ff0000; font-weight: bold;}
-.unconscious {color: #a4bad6; font-weight: bold;}
+.unconscious {color: #0000ff; font-weight: bold;}
.suicide {color: #ff5050; font-style: italic;}
-.red {color: #FF0000}
-.pink {color: #ff70c1;}
-.blue {color: #215cff}
-.green {color: #059223;}
-.nicegreen {color: #059223;}
+.green {color: #03ff39;}
+.red {color: #FF0000;}
+.pink {color: #FF69Bf;}
+.blue {color: #0000FF;}
+.nicegreen {color: #14a833;}
.userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;}
.love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;}
-.shadowling {color: #8e8a99;}
-.cult {color: #aa1c1c;}
+.shadowling {color: #3b2769;}
+.cult {color: #960000;}
-.cultitalic {color: #aa1c1c; font-style: italic;}
-.cultbold {color: #aa1c1c; font-style: italic; font-weight: bold;}
-.cultboldtalic {color: #aa1c1c; font-weight: bold; font-size: 24px;}
+.cultitalic {color: #960000; font-style: italic;}
+.cultbold {color: #960000; font-style: italic; font-weight: bold;}
+.cultboldtalic {color: #960000; font-weight: bold; font-size: 185%;}
-.cultlarge {color: #aa1c1c; font-weight: bold; font-size: 24px;}
-.narsie {color: #aa1c1c; font-weight: bold; font-size: 120px;}
-.narsiesmall {color: #aa1c1c; font-weight: bold; font-size: 48px;}
-.colossus {color: #7F282A; font-size: 40px;}
-.hierophant {color: #b441ee; font-weight: bold; font-style: italic;}
-.hierophant_warning {color: #c56bf1; font-style: italic;}
-.purple {color: #9956d3;}
-.holoparasite {color: #88809c;}
+.cultlarge {color: #960000; font-weight: bold; font-size: 185%;}
+.narsie {color: #960000; font-weight: bold; font-size: 925%;}
+.narsiesmall {color: #960000; font-weight: bold; font-size: 370%;}
+.colossus {color: #7F282A; font-size: 310%;}
+.hierophant {color: #660099; font-weight: bold; font-style: italic;}
+.hierophant_warning {color: #660099; font-style: italic;}
+.purple {color: #5e2d79;}
+.holoparasite {color: #35333a;}
.revennotice {color: #1d2953;}
.revenboldnotice {color: #1d2953; font-weight: bold;}
-.revenbignotice {color: #1d2953; font-weight: bold; font-size: 24px;}
+.revenbignotice {color: #1d2953; font-weight: bold; font-size: 185%;}
.revenminor {color: #823abb}
.revenwarning {color: #760fbb; font-style: italic;}
-.revendanger {color: #760fbb; font-weight: bold; font-size: 24px;}
-.umbra {color: #7c00e6;}
-.umbra_emphasis {color: #7c00e6; font-weight: bold; font-style: italic;}
-.umbra_large {color: #7c00e6; font-size: 24px; font-weight: bold; font-style: italic;}
+.revendanger {color: #760fbb; font-weight: bold; font-size: 185%;}
+.umbra {color: #5000A0;}
+.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;}
+.umbra_large {color: #5000A0; font-size: 185%; font-weight: bold; font-style: italic;}
-.deconversion_message {color: #a947ff; font-size: 24px; font-style: italic;}
+.deconversion_message {color: #5000A0; font-size: 185%; font-style: italic;}
.brass {color: #BE8700;}
.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;}
-.large_brass {color: #BE8700; font-size: 24px;}
-.big_brass {color: #BE8700; font-size: 24px; font-weight: bold; font-style: italic;}
-.ratvar {color: #BE8700; font-size: 48px; font-weight: bold; font-style: italic;}
+.large_brass {color: #BE8700; font-size: 185%;}
+.big_brass {color: #BE8700; font-size: 185%; font-weight: bold; font-style: italic;}
+.ratvar {color: #BE8700; font-size: 370%; font-weight: bold; font-style: italic;}
.alloy {color: #42474D;}
.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;}
-.nezbere_large {color: #42474D; font-size: 24px; font-weight: bold; font-style: italic;}
+.nezbere_large {color: #42474D; font-size: 185%; font-weight: bold; font-style: italic;}
.nezbere {color: #42474D; font-weight: bold; font-style: italic;}
.nezbere_small {color: #42474D;}
-.sevtug_large {color: #AF0AAF; font-size: 24px; font-weight: bold; font-style: italic;}
+.sevtug_large {color: #AF0AAF; font-size: 185%; font-weight: bold; font-style: italic;}
.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;}
.sevtug_small {color: #AF0AAF;}
-.inathneq_large {color: #1E8CE1; font-size: 24px; font-weight: bold; font-style: italic;}
+.inathneq_large {color: #1E8CE1; font-size: 185%; font-weight: bold; font-style: italic;}
.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;}
.inathneq_small {color: #1E8CE1;}
-.nzcrentr_large {color: #DAAA18; font-size: 24px; font-weight: bold; font-style: italic;}
+.nzcrentr_large {color: #DAAA18; font-size: 185%; font-weight: bold; font-style: italic;}
.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;}
.nzcrentr_small {color: #DAAA18;}
-.neovgre_large {color: #6E001A; font-size: 24px; font-weight: bold; font-style: italic;}
+.neovgre_large {color: #6E001A; font-size: 185%; font-weight: bold; font-style: italic;}
.neovgre {color: #6E001A; font-weight: bold; font-style: italic;}
.neovgre_small {color: #6E001A;}
-.newscaster {color: #c05d5d;}
-.ghostalert {color: #6600ff; font-style: italic; font-weight: bold;}
+.newscaster {color: #800000;}
+.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;}
-.alien {color: #855d85;}
-.noticealien {color: #059223;}
-.alertalien {color: #059223; font-weight: bold;}
-.changeling {color: #059223; font-style: italic;}
+.alien {color: #543354;}
+.noticealien {color: #00c000;}
+.alertalien {color: #00c000; font-weight: bold;}
+.changeling {color: #800080; font-style: italic;}
-.spider {color: #8800ff;}
+.spider {color: #4d004d; font-weight: bold; font-size: 185%;}
-.interface {color: #750e75;}
+.interface {color: #330033;}
.sans {font-family: "Comic Sans MS", cursive, sans-serif;}
.papyrus {font-family: "Papyrus", cursive, sans-serif;}
.robot {font-family: "Courier New", cursive, sans-serif;}
-.command_headset {font-weight: bold; font-size: 24px;}
-.small {font-size: 8px;}
-.big {font-size: 24px;}
-.reallybig {font-size: 32px;}
-.extremelybig {font-size: 40px;}
-.greentext {color: #059223; font-size: 24px;}
-.redtext {color: #c51e1e; font-size: 24px;}
-.clown {color: #ff70c1; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
+.command_headset {font-weight: bold; font-size: 160%;}
+.small {font-size: 60%;}
+.big {font-size: 185%;}
+.reallybig {font-size: 245%;}
+.extremelybig {font-size: 310%;}
+.greentext {color: #00FF00; font-size: 185%;}
+.redtext {color: #FF0000; font-size: 185%;}
+.clown {color: #FF69Bf; font-size: 160%; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
+.spooky {color: #FF6100;}
.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;}
@keyframes velvet {
0% { color: #400020; }
@@ -433,21 +431,21 @@ h1.alert, h2.alert {color: #99aab5;}
.icon {height: 1em; width: auto;}
.memo {color: #638500; text-align: center;}
-.memoedit {text-align: center; font-size: 16px;}
-.abductor {color: #c204c2; font-style: italic;}
-.mind_control {color: #df3da9; font-size: 3; font-weight: bold; font-style: italic;}
+.memoedit {text-align: center; font-size: 125%;}
+.abductor {color: #800080; font-style: italic;}
+.mind_control {color: #A00D6F; font-size: 100%; font-weight: bold; font-style: italic;}
.slime {color: #00CED1;}
.drone {color: #848482;}
.monkey {color: #975032;}
.swarmer {color: #2C75FF;}
.resonate {color: #298F85;}
-.monkeyhive {color: #a56408;}
-.monkeylead {color: #af6805; font-size: 2;}
+.monkeyhive {color: #774704;}
+.monkeylead {color: #774704; font-size: 125%;}
.connectionClosed, .fatalError {background: red; color: white; padding: 5px;}
.connectionClosed.restored {background: green;}
-.internal.boldnshit {color: #3d5bc3; font-weight: bold;}
+.internal.boldnshit {color: #000099; font-weight: bold;}
/* HELPER CLASSES */
.text-normal {font-weight: normal; font-style: normal;}
diff --git a/code/modules/goonchat/browserassets/css/browserOutput_dark.css b/code/modules/goonchat/browserassets/css/browserOutput_dark.css
new file mode 100644
index 0000000000..3377bcf72c
--- /dev/null
+++ b/code/modules/goonchat/browserassets/css/browserOutput_dark.css
@@ -0,0 +1,159 @@
+html, body {color: #E0E0E0;}
+body {
+ background: #171717;
+ font-color: #E0E0E0;
+ scrollbar-face-color:#1A1A1A;
+ scrollbar-track-color:#171717;
+ scrollbar-highlight-color:#171717;
+}
+
+a {color: #397ea5;}
+a.visited {color: #7c00e6;}
+a:visited {color: #7c00e6;}
+
+#newMessages {
+ background: #242424;
+ color: #E0E0E0;
+}
+#newMessages:hover {background: #272727;}
+
+#ping {background: #272727;}
+
+#userBar .subCell {
+ background: #272727;
+ color: #E0E0E0;
+ border-top: 1px solid #171717;
+}
+#userBar .subCell:hover {background: #272727;}
+#userBar .toggle {background: #272727;}
+
+/* MOTD */
+.motd {color: #E0E0E0;}
+.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #E0E0E0;}
+.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #E0E0E0;}
+
+h1, h2, h3, h4, h5, h6 {color: #E0E0E0;}
+h1.alert, h2.alert {color: #E0E0E0;}
+
+.ooc {color: #cca300;}
+.looc {color: #d8b555;}
+.antagooc {color: #ce254f;}
+.adminobserverooc {color: #0099cc;}
+.adminooc {color: #3d5bc3;}
+
+.admin {color: #5975da;}
+
+.deadsay {color: #e2c1ff;}
+.radio {color: #1ecc43;}
+.sciradio {color: #c68cfa;}
+.comradio {color: #5177ff;}
+.secradio {color: #dd3535;}
+.medradio {color: #57b8f0;}
+.engradio {color: #f37746;}
+.suppradio {color: #b88646;}
+.servradio {color: #6ca729;}
+.syndradio {color: #8f4a4b;}
+.centcomradio {color: #2681a5;}
+.aiprivradio {color: #d65d95;}
+.redteamradio {color: #ff4444;}
+.blueteamradio {color: #3434fd;}
+
+.alert {color: #d82020;}
+h1.alert, h2.alert {color: #99aab5;}
+
+.attack {color: #e01c1c;}
+.disarm {color: #b42525;}
+.passive {color: #a00f0f;}
+
+.userdanger {color: #c51e1e;}
+.danger {color: #c51e1e;}
+.warning {color: #c51e1e;}
+.alertwarning {color: #c51e1e;}
+.boldwarning {color: #c51e1e;}
+.announce {color: #c51e1e;}
+.boldannounce {color: #c51e1e;}
+.greenannounce {color: #059223;}
+.info {color: #6685f5;}
+.notice {color: #6685f5;}
+.boldnotice {color: #6685f5;}
+.adminnotice {color: #6685f5;}
+.adminhelp {color: #ff0000;}
+.unconscious {color: #E0E0E0;}
+.red {color: #FF0000;}
+.pink {color: #ff70c1;}
+.blue {color: #215cff;}
+.green {color: #059223;}
+.nicegreen {color: #059223;}
+.userlove {color: #ff42a6; text-shadow: 0 0 6px #82365e;}
+.love {color: #ff4591; text-shadow: 0 0 6px #994449;}
+.shadowling {color: #8e8a99;}
+.cult {color: #aa1c1c;}
+
+.cultitalic {color: #aa1c1c;}
+.cultbold {color: #aa1c1c;}
+.cultboldtalic {color: #aa1c1c;}
+
+.cultlarge {color: #aa1c1c;}
+.narsie {color: #aa1c1c;}
+.narsiesmall {color: #aa1c1c;}
+.hierophant {color: #b441ee;}
+.hierophant_warning {color: #c56bf1;}
+.purple {color: #9956d3;}
+.holoparasite {color: #88809c;}
+
+.revennotice {color: #3645aa;}
+.revenboldnotice {color: #3645aa;}
+.revenbignotice {color: #3645aa;}
+.revenminor {color: #823ddd;}
+.revenwarning {color: #8911d9;}
+.revendanger {color: #8911d9;}
+.umbra {color: #7c00e6;}
+.umbra_emphasis {color: #7c00e6;}
+.umbra_large {color: #7c00e6;}
+
+.deconversion_message {color: #a947ff;}
+
+.alloy {color: #545b64;}
+.heavy_alloy {color: #545b64;}
+.nezbere_large {color: #545b64;}
+.nezbere {color: #545b64;}
+.nezbere_small {color: #545b64;}
+.inathneq_large {color: #1d7dc7;}
+.inathneq {color: #1d7dc7;}
+.inathneq_small {color: #1d7dc7;}
+.neovgre_large {color: #7c0622;}
+.neovgre {color: #7c0622;}
+.neovgre_small {color: #7c0622;}
+
+.newscaster {color: #c05d5d;}
+.ghostalert {color: #6600ff;}
+
+.alien {color: #855d85;}
+.noticealien {color: #059223;}
+.alertalien {color: #059223;}
+.changeling {color: #059223;}
+
+.spider {color: #8800ff;}
+
+.interface {color: #750e75;}
+
+.greentext {color: #059223;}
+.redtext {color: #c51e1e;}
+.clown {color: #ff70c1;}
+.velvet {color: #660015;}
+@keyframes velvet {
+ 0% { color: #890020; }
+ 40% { color: #c51e1e; }
+ 50% { color: #FF8888; }
+ 60% { color: #c51e1e; }
+ 100% { color: #890020; }
+}
+
+.abductor {color: #c204c2;}
+.mind_control {color: #df3da9;}
+.drone {color: #979795;}
+
+.monkeyhive {color: #a56408;}
+.monkeylead {color: #af6805;}
+
+.internal.boldnshit {color: #3d5bc3;}
diff --git a/code/modules/goonchat/browserassets/css/browserOutput_light.css b/code/modules/goonchat/browserassets/css/browserOutput_light.css
new file mode 100644
index 0000000000..b7036c74d8
--- /dev/null
+++ b/code/modules/goonchat/browserassets/css/browserOutput_light.css
@@ -0,0 +1,14 @@
+body {background: #F1F1F1;}
+
+#newMessages {background: #ddd;}
+#ping {background: #ddd;}
+
+#userBar .subCell {background: #ddd;}
+
+/* POPUPS */
+.popup {background: #ddd;}
+.popup .head {color: #ddd;}
+.popup input[type=submit] {color: #ddd;}
+
+/* ADMIN CONTEXT MENU */
+.contextMenu {background-color: #ddd;}
diff --git a/code/modules/goonchat/browserassets/css/browserOutput_white.css b/code/modules/goonchat/browserassets/css/browserOutput_white.css
deleted file mode 100644
index e21185449b..0000000000
--- a/code/modules/goonchat/browserassets/css/browserOutput_white.css
+++ /dev/null
@@ -1,426 +0,0 @@
-/*****************************************
-*
-* GLOBAL STYLES
-*
-******************************************/
-html, body {
- padding: 0;
- margin: 0;
- height: 100%;
- color: #000000;
-}
-body {
- background: #fff;
- font-family: Verdana, sans-serif;
- font-size: 9pt;
- line-height: 1.2;
- overflow-x: hidden;
- overflow-y: scroll;
- word-wrap: break-word;
-}
-
-em {
- font-style: normal;
- font-weight: bold;
-}
-
-img {
- margin: 0;
- padding: 0;
- line-height: 1;
- -ms-interpolation-mode: nearest-neighbor;
- image-rendering: pixelated;
-}
-img.icon {
- height: 1em;
- min-height: 16px;
- width: auto;
- vertical-align: bottom;
-}
-
-
-.r:before { /* "repeated" badge class for combined messages */
- content: 'x';
-}
-.r {
- display: inline-block;
- min-width: 0.5em;
- font-size: 0.7em;
- padding: 0.2em 0.3em;
- line-height: 1;
- color: white;
- text-align: center;
- white-space: nowrap;
- vertical-align: middle;
- background-color: crimson;
- border-radius: 10px;
-}
-
-a {color: #0000ff;}
-a.visited {color: #ff00ff;}
-a:visited {color: #ff00ff;}
-a.popt {text-decoration: none;}
-
-/*****************************************
-*
-* OUTPUT NOT RELATED TO ACTUAL MESSAGES
-*
-******************************************/
-#loading {
- position: fixed;
- width: 300px;
- height: 150px;
- text-align: center;
- left: 50%;
- top: 50%;
- margin: -75px 0 0 -150px;
-}
-#loading i {display: block; padding-bottom: 3px;}
-
-#messages {
- font-size: 13px;
- padding: 3px;
- margin: 0;
- word-wrap: break-word;
-}
-#newMessages {
- position: fixed;
- display: block;
- bottom: 0;
- right: 0;
- padding: 8px;
- background: #ddd;
- text-decoration: none;
- font-variant: small-caps;
- font-size: 1.1em;
- font-weight: bold;
- color: #333;
-}
-#newMessages:hover {background: #ccc;}
-#newMessages i {vertical-align: middle; padding-left: 3px;}
-#ping {
- position: fixed;
- top: 0;
- right: 115px;
- width: 45px;
- background: #ddd;
- height: 30px;
- padding: 8px 0 2px 0;
-}
-#ping i {display: block; text-align: center;}
-#ping .ms {
- display: block;
- text-align: center;
- font-size: 8pt;
- padding-top: 2px;
-}
-#userBar {
- position: fixed;
- top: 0;
- right: 0;
-}
-#userBar .subCell {
- background: #ddd;
- height: 30px;
- padding: 5px 0;
- display: block;
- color: #333;
- text-decoration: none;
- line-height: 28px;
- border-top: 1px solid #b4b4b4;
-}
-#userBar .subCell:hover {background: #ccc;}
-#userBar .toggle {
- width: 40px;
- background: #ccc;
- border-top: 0;
- float: right;
- text-align: center;
-}
-#userBar .sub {clear: both; display: none; width: 160px;}
-#userBar .sub.scroll {overflow-y: scroll;}
-#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;}
-#userBar .sub span {
- display: block;
- line-height: 30px;
- float: left;
-}
-#userBar .sub i {
- display: block;
- padding: 0 5px;
- font-size: 1.1em;
- width: 22px;
- text-align: center;
- line-height: 30px;
- float: right;
-}
-#userBar .sub input {
- position: absolute;
- padding: 7px 5px;
- width: 121px;
- line-height: 30px;
- float: left;
-}
-#userBar .topCell {border-top: 0;}
-
-/* POPUPS */
-.popup {
- position: fixed;
- top: 50%;
- left: 50%;
- background: #ddd;
-}
-.popup .close {
- position: absolute;
- background: #aaa;
- top: 0;
- right: 0;
- color: #333;
- text-decoration: none;
- z-index: 2;
- padding: 0 10px;
- height: 30px;
- line-height: 30px;
-}
-.popup .close:hover {background: #999;}
-.popup .head {
- background: #999;
- color: #ddd;
- padding: 0 10px;
- height: 30px;
- line-height: 30px;
- text-transform: uppercase;
- font-size: 0.9em;
- font-weight: bold;
- border-bottom: 2px solid green;
-}
-.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;}
-.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;}
-.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;}
-.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;}
-
-.changeFont {padding: 10px;}
-.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;}
-.changeFont a:hover {background: #ccc;}
-
-.highlightPopup {padding: 10px; text-align: center;}
-.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;}
-.highlightPopup input.highlightColor {background-color: #FFFF00;}
-.highlightPopup input.highlightTermSubmit {margin-top: 5px;}
-
-/* ADMIN CONTEXT MENU */
-.contextMenu {
- background-color: #ddd;
- position: fixed;
- margin: 2px;
- width: 150px;
-}
-.contextMenu a {
- display: block;
- padding: 2px 5px;
- text-decoration: none;
- color: #333;
-}
-
-.contextMenu a:hover {
- background-color: #ccc;
-}
-
-/* ADMIN FILTER MESSAGES MENU */
-.filterMessages {padding: 5px;}
-.filterMessages div {padding: 2px 0;}
-.filterMessages input {}
-.filterMessages label {}
-
-.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;}
-
-
-/*****************************************
-*
-* OUTPUT ACTUALLY RELATED TO MESSAGES
-*
-******************************************/
-
-/* MOTD */
-.motd {color: #638500; font-family: Verdana, sans-serif;}
-.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;}
-.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;}
-
-/* ADD HERE FOR BOLD */
-.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;}
-
-/* ADD HERE FOR ITALIC */
-.italic, .italics, .emote {font-style: italic;}
-
-/* OUTPUT COLORS */
-.highlight {background: yellow;}
-
-h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;}
-h1.alert, h2.alert {color: #000000;}
-
-em {font-style: normal; font-weight: bold;}
-
-.ooc {color: #002eb8; font-weight: bold;}
-.antagooc {color: #b8002e; font-weight: bold;}
-.adminobserverooc {color: #0099cc; font-weight: bold;}
-.adminooc {color: #700038; font-weight: bold;}
-
-.adminsay {color: #ff4500; font-weight: bold;}
-.admin {color: #4473ff; font-weight: bold;}
-
-.name { font-weight: bold;}
-
-.say {}
-.deadsay {color: #5c00e6;}
-.binarysay {color: #20c20e; background-color: #000000; display: block;}
-.binarysay a {color: #00ff00;}
-.binarysay a:active, .binarysay a:visited {color: #88ff88;}
-.radio {color: #008000;}
-.sciradio {color: #993399;}
-.comradio {color: #948f02;}
-.secradio {color: #a30000;}
-.medradio {color: #337296;}
-.engradio {color: #fb5613;}
-.suppradio {color: #a8732b;}
-.servradio {color: #6eaa2c;}
-.syndradio {color: #6d3f40;}
-.centcomradio {color: #686868;}
-.aiprivradio {color: #ff00ff;}
-.redteamradio {color: #ff0000;}
-.blueteamradio {color: #0000ff;}
-
-.yell { font-weight: bold;}
-
-.alert {color: #ff0000;}
-h1.alert, h2.alert {color: #000000;}
-
-.emote { font-style: italic;}
-.selecteddna {color: #ffffff; background-color: #001B1B}
-
-.attack {color: #ff0000;}
-.disarm {color: #990000;}
-.passive {color: #660000;}
-
-.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;}
-.danger {color: #ff0000;}
-.warning {color: #ff0000; font-style: italic;}
-.alertwarning {color: #FF0000; font-weight: bold}
-.boldwarning {color: #ff0000; font-style: italic; font-weight: bold}
-.announce {color: #228b22; font-weight: bold;}
-.boldannounce {color: #ff0000; font-weight: bold;}
-.greenannounce {color: #00ff00; font-weight: bold;}
-.rose {color: #ff5050;}
-.info {color: #0000CC;}
-.notice {color: #000099;}
-.boldnotice {color: #000099; font-weight: bold;}
-.adminnotice {color: #0000ff;}
-.adminhelp {color: #ff0000; font-weight: bold;}
-.unconscious {color: #0000ff; font-weight: bold;}
-.suicide {color: #ff5050; font-style: italic;}
-.green {color: #03ff39;}
-.red {color: #FF0000}
-.pink {color: #FF69Bf;}
-.blue {color: #0000FF}
-.nicegreen {color: #14a833;}
-.userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;}
-.love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;}
-.shadowling {color: #3b2769;}
-.cult {color: #960000;}
-
-.cultitalic {color: #960000; font-style: italic;}
-.cultbold {color: #960000; font-style: italic; font-weight: bold;}
-.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;}
-
-.cultlarge {color: #960000; font-weight: bold; font-size: 24px;}
-.narsie {color: #960000; font-weight: bold; font-size: 120px;}
-.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;}
-.colossus {color: #7F282A; font-size: 40px;}
-.hierophant {color: #660099; font-weight: bold; font-style: italic;}
-.hierophant_warning {color: #660099; font-style: italic;}
-.purple {color: #5e2d79;}
-.holoparasite {color: #35333a;}
-
-.revennotice {color: #1d2953;}
-.revenboldnotice {color: #1d2953; font-weight: bold;}
-.revenbignotice {color: #1d2953; font-weight: bold; font-size: 24px;}
-.revenminor {color: #823abb}
-.revenwarning {color: #760fbb; font-style: italic;}
-.revendanger {color: #760fbb; font-weight: bold; font-size: 24px;}
-.umbra {color: #5000A0;}
-.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;}
-.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;}
-
-.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;}
-
-.brass {color: #BE8700;}
-.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;}
-.large_brass {color: #BE8700; font-size: 24px;}
-.big_brass {color: #BE8700; font-size: 24px; font-weight: bold; font-style: italic;}
-.ratvar {color: #BE8700; font-size: 48px; font-weight: bold; font-style: italic;}
-.alloy {color: #42474D;}
-.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;}
-.nezbere_large {color: #42474D; font-size: 24px; font-weight: bold; font-style: italic;}
-.nezbere {color: #42474D; font-weight: bold; font-style: italic;}
-.nezbere_small {color: #42474D;}
-.sevtug_large {color: #AF0AAF; font-size: 24px; font-weight: bold; font-style: italic;}
-.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;}
-.sevtug_small {color: #AF0AAF;}
-.inathneq_large {color: #1E8CE1; font-size: 24px; font-weight: bold; font-style: italic;}
-.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;}
-.inathneq_small {color: #1E8CE1;}
-.nzcrentr_large {color: #DAAA18; font-size: 24px; font-weight: bold; font-style: italic;}
-.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;}
-.nzcrentr_small {color: #DAAA18;}
-.neovgre_large {color: #6E001A; font-size: 24px; font-weight: bold; font-style: italic;}
-.neovgre {color: #6E001A; font-weight: bold; font-style: italic;}
-.neovgre_small {color: #6E001A;}
-
-.newscaster {color: #800000;}
-.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;}
-
-.alien {color: #543354;}
-.noticealien {color: #00c000;}
-.alertalien {color: #00c000; font-weight: bold;}
-.changeling {color: #800080; font-style: italic;}
-
-.spider {color: #4d004d;}
-
-.interface {color: #330033;}
-
-.sans {font-family: "Comic Sans MS", cursive, sans-serif;}
-.papyrus {font-family: "Papyrus", cursive, sans-serif;}
-.robot {font-family: "Courier New", cursive, sans-serif;}
-
-.command_headset {font-weight: bold; font-size: 24px;}
-.small {font-size: 8px;}
-.big {font-size: 24px;}
-.reallybig {font-size: 32px;}
-.extremelybig {font-size: 40px;}
-.greentext {color: #00FF00; font-size: 24px;}
-.redtext {color: #FF0000; font-size: 24px;}
-.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
-.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
-
-.icon {height: 1em; width: auto;}
-
-.memo {color: #638500; text-align: center;}
-.memoedit {text-align: center; font-size: 16px;}
-.abductor {color: #800080; font-style: italic;}
-.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;}
-.slime {color: #00CED1;}
-.drone {color: #848482;}
-.monkey {color: #975032;}
-.swarmer {color: #2C75FF;}
-.resonate {color: #298F85;}
-
-.monkeyhive {color: #774704;}
-.monkeylead {color: #774704; font-size: 2;}
-
-.connectionClosed, .fatalError {background: red; color: white; padding: 5px;}
-.connectionClosed.restored {background: green;}
-.internal.boldnshit {color: blue; font-weight: bold;}
-
-/* HELPER CLASSES */
-.text-normal {font-weight: normal; font-style: normal;}
-.hidden {display: none; visibility: hidden;}
-
diff --git a/code/modules/goonchat/browserassets/html/browserOutput.html b/code/modules/goonchat/browserassets/html/browserOutput.html
index 9c6d462a85..68da251702 100644
--- a/code/modules/goonchat/browserassets/html/browserOutput.html
+++ b/code/modules/goonchat/browserassets/html/browserOutput.html
@@ -5,8 +5,9 @@
-
+
+
@@ -29,7 +30,7 @@
--ms
diff --git a/code/modules/goonchat/browserassets/js/browserOutput.js b/code/modules/goonchat/browserassets/js/browserOutput.js
index 93a498fd06..abd05d29ed 100644
--- a/code/modules/goonchat/browserassets/js/browserOutput.js
+++ b/code/modules/goonchat/browserassets/js/browserOutput.js
@@ -35,7 +35,7 @@ var opts = {
'wasd': false, //Is the user in wasd mode?
'priorChatHeight': 0, //Thing for height-resizing detection
'restarting': false, //Is the round restarting?
- 'darkmode':false, //Are we using darkmode? If not WHY ARE YOU LIVING IN 2009???
+ 'colorPreset': 0, // index in the color presets list.
//Options menu
'selectedSubLoop': null, //Contains the interval loop for closing the selected sub menu
@@ -73,6 +73,14 @@ var opts = {
};
+// Array of names for chat display color presets.
+// If not set to normal, a CSS file `browserOutput_${name}.css` will be added to the head.
+var colorPresets = [
+ 'normal',
+ 'light',
+ 'dark'
+]
+
function clamp(val, min, max) {
return Math.max(min, Math.min(val, max))
}
@@ -96,6 +104,12 @@ if (typeof String.prototype.trim !== 'function') {
};
}
+function updateColorPreset() {
+ var el = $("#colorPresetLink")[0];
+ el.href = "browserOutput_"+colorPresets[opts.colorPreset]+".css";
+ runByond('?_src_=chat&proc=colorPresetPost&preset='+colorPresets[opts.colorPreset]);
+}
+
// Linkify the contents of a node, within its parent.
function linkify(parent, insertBefore, text) {
var start = 0;
@@ -395,19 +409,6 @@ function toHex(n) {
return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16);
}
-function swap() { //Swap to darkmode
- if (opts.darkmode){
- document.getElementById("sheetofstyles").href = "browserOutput_white.css";
- opts.darkmode = false;
- runByond('?_src_=chat&proc=swaptolightmode');
- } else {
- document.getElementById("sheetofstyles").href = "browserOutput.css";
- opts.darkmode = true;
- runByond('?_src_=chat&proc=swaptodarkmode');
- }
- setCookie('darkmode', (opts.darkmode ? 'true' : 'false'), 365);
-}
-
function handleClientData(ckey, ip, compid) {
//byond sends player info to here
var currentData = {'ckey': ckey, 'ip': ip, 'compid': compid};
@@ -615,7 +616,7 @@ $(function() {
'shighlightColor': getCookie('highlightcolor'),
'smusicVolume': getCookie('musicVolume'),
'smessagecombining': getCookie('messagecombining'),
- 'sdarkmode': getCookie('darkmode'),
+ 'scolorPreset': getCookie('colorpreset'),
};
if (savedConfig.sfontSize) {
@@ -626,9 +627,6 @@ $(function() {
$("body").css('line-height', savedConfig.slineHeight);
internalOutput('
Loaded line height setting of: '+savedConfig.slineHeight+' ', 'internal');
}
- if(savedConfig.sdarkmode == 'true'){
- swap();
- }
if (savedConfig.spingDisabled) {
if (savedConfig.spingDisabled == 'true') {
opts.pingDisabled = true;
@@ -654,6 +652,13 @@ $(function() {
opts.highlightColor = savedConfig.shighlightColor;
internalOutput('
Loaded highlight color of: '+savedConfig.shighlightColor+' ', 'internal');
}
+
+ if (savedConfig.scolorPreset) {
+ opts.colorPreset = Number(savedConfig.scolorPreset);
+ updateColorPreset();
+ internalOutput('
Loaded color preset of: '+colorPresets[opts.colorPreset]+' ', 'internal');
+ }
+
if (savedConfig.smusicVolume) {
var newVolume = clamp(savedConfig.smusicVolume, 0, 100);
$('#adminMusic').prop('volume', newVolume / 100);
@@ -839,9 +844,6 @@ $(function() {
$('#toggleOptions').click(function(e) {
handleToggleClick($subOptions, $(this));
});
- $('#darkmodetoggle').click(function(e) {
- swap();
- });
$('#toggleAudio').click(function(e) {
handleToggleClick($subAudio, $(this));
});
@@ -913,7 +915,7 @@ $(function() {
$.ajax({
type: 'GET',
- url: 'browserOutput_white.css',
+ url: 'browserOutput.css',
success: function(styleData) {
var blob = new Blob(['
Chat Log ', $messages.html(), '']);
@@ -992,6 +994,13 @@ $(function() {
opts.messageCount = 0;
});
+ $('#changeColorPreset').click(function() {
+ opts.colorPreset = (opts.colorPreset+1) % colorPresets.length;
+ updateColorPreset();
+ setCookie('colorpreset', opts.colorPreset, 365);
+ internalOutput('
Changed color preset to: '+colorPresets[opts.colorPreset]);
+ });
+
$('#musicVolumeSpan').hover(function() {
$('#musicVolumeText').addClass('hidden');
$('#musicVolume').removeClass('hidden');
diff --git a/code/modules/holiday/easter.dm b/code/modules/holiday/easter.dm
index 829cb55312..3cb05a8f7e 100644
--- a/code/modules/holiday/easter.dm
+++ b/code/modules/holiday/easter.dm
@@ -18,7 +18,7 @@
max_occurrences = 10
/datum/round_event/rabbitrelease/announce(fake)
- priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", 'sound/ai/aliens.ogg')
+ priority_announce("Unidentified furry objects detected coming aboard [station_name()]. Beware of Adorable-ness.", "Fluffy Alert", "aliens")
/datum/round_event/rabbitrelease/start()
@@ -68,7 +68,7 @@
/obj/item/storage/bag/easterbasket/Initialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/egg, /obj/item/reagent_containers/food/snacks/chocolateegg, /obj/item/reagent_containers/food/snacks/boiledegg))
/obj/item/storage/bag/easterbasket/proc/countEggs()
diff --git a/code/modules/holiday/halloween/bartholomew.dm b/code/modules/holiday/halloween/bartholomew.dm
new file mode 100644
index 0000000000..aa119dca84
--- /dev/null
+++ b/code/modules/holiday/halloween/bartholomew.dm
@@ -0,0 +1,158 @@
+/obj/effect/landmark/barthpot
+ name = "barthpot"
+
+/obj/item/barthpot
+ name = "Bartholomew"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "barthpot"
+ anchored = TRUE
+ var/items_list = list()
+ speech_span = "spooky"
+ var/active = TRUE
+
+/obj/item/barthpot/Destroy()
+ var/obj/item/barthpot/n = new src(loc)
+ n.items_list = items_list
+ ..()
+
+
+/obj/item/barthpot/attackby(obj/item/I, mob/user, params)
+ if(!active)
+ say("Meow!")
+ return
+
+ for(var/I2 in items_list)
+ if(istype(I, I2))
+ qdel(I)
+ new /obj/item/reagent_containers/food/snacks/special_candy(loc)
+ to_chat(user, "You add the [I.name] to the pot and watch as it melts into the mixture, a candy crystalising in it's wake. ")
+ say("Hooray! Thank you!")
+ items_list -= I2
+ return
+ say("It doesn't seem like that's magical enough!")
+
+/obj/item/barthpot/attack_hand(mob/user)
+ if(!active)
+ say("Meow!")
+ return
+ say("Hello there, I'm Bartholomew, Jacqueline's Familiar.")
+ sleep(20)
+
+ say("I'm currently seeking items to put into my pot, if we get the right items, it should crystalise into a magic candy!")
+ if(!iscarbon(user))
+ say("Though... I'm not sure you can help me.")
+
+ var/message = "From what I can tell, "
+ if(LAZYLEN(items_list) < 5)
+ generate_items()
+ for(var/I2 in items_list)
+ if(!I2)
+ items_list -= I2
+ continue
+ var/obj/item/I3 = new I2
+ message += "a [I3.name], "
+ message += "currently seem to have the most magic potential."
+ sleep(15)
+ say("[message]")
+ sleep(15)
+ //To help people find her
+ for(var/mob/living/simple_animal/jacq/J in GLOB.simple_animals[1])
+ var/turf/L1 = J.loc
+ if(!L1) //Incase someone uh.. puts her in a locker
+ return
+ var/area/L2 = L1.loc
+ if(L2)
+ say("Also, it seems that Jacqueline is currently at the [L2], if you're looking for her too.")
+
+/obj/item/barthpot/proc/generate_items()
+ var/length = LAZYLEN(items_list)
+ var/rand_items = list(/obj/item/bodybag = 1,
+ /obj/item/clothing/glasses/meson = 2,
+ /obj/item/clothing/glasses/sunglasses = 1,
+ /obj/item/clothing/gloves/color/fyellow = 1,
+ /obj/item/clothing/head/hardhat = 1,
+ /obj/item/clothing/head/hardhat/red = 1,
+ /obj/item/clothing/head/that = 1,
+ /obj/item/clothing/head/ushanka = 1,
+ /obj/item/clothing/head/welding = 1,
+ /obj/item/clothing/mask/gas = 10,
+ /obj/item/clothing/suit/hazardvest = 1,
+ /obj/item/clothing/suit/hooded/flashsuit = 1,
+ /obj/item/assembly/prox_sensor = 4,
+ /obj/item/assembly/timer = 3,
+ /obj/item/flashlight = 6,
+ /obj/item/flashlight/pen = 1,
+ /obj/item/flashlight/glowstick = 4,
+ /obj/item/multitool = 2,
+ /obj/item/radio = 2,
+ /obj/item/t_scanner = 5,
+ /obj/item/airlock_painter = 1,
+ /obj/item/stack/cable_coil = 6,
+ /obj/item/stack/medical/bruise_pack = 1,
+ /obj/item/stack/rods = 3,
+ /obj/item/stack/sheet/cardboard = 2,
+ /obj/item/stack/sheet/metal = 1,
+ /obj/item/stack/sheet/mineral/plasma = 1,
+ /obj/item/stack/sheet/rglass = 1,
+ /obj/item/coin = 1,
+ /obj/item/crowbar = 4,
+ /obj/item/extinguisher = 3,
+ /obj/item/hand_labeler = 1,
+ /obj/item/paper = 6,
+ /obj/item/pen = 5,
+ /obj/item/reagent_containers/spray/pestspray = 1,
+ /obj/item/reagent_containers/rag = 3,
+ /obj/item/stock_parts/cell = 3,
+ /obj/item/storage/belt/utility = 2,
+ /obj/item/storage/box = 4,
+ /obj/item/reagent_containers/food/drinks/sillycup = 1,
+ /obj/item/storage/box/donkpockets = 1,
+ /obj/item/storage/box/lights/mixed = 1,
+ /obj/item/storage/box/hug/medical = 1,
+ /obj/item/storage/fancy/cigarettes = 1,
+ /obj/item/storage/toolbox = 1,
+ /obj/item/screwdriver = 3,
+ /obj/item/tank/internals/emergency_oxygen = 2,
+ /obj/item/vending_refill/cola = 1,
+ /obj/item/weldingtool = 3,
+ /obj/item/wirecutters = 2,
+ /obj/item/wrench = 4,
+ /obj/item/weaponcrafting/receiver = 1,
+ /obj/item/geiger_counter = 3,
+ /obj/item/reagent_containers/food/snacks/grown/citrus/orange = 5,
+ /obj/item/assembly/infra = 1,
+ /obj/item/assembly/igniter = 2,
+ /obj/item/assembly/signaler = 2,
+ /obj/item/assembly/mousetrap = 5,
+ /obj/item/reagent_containers/syringe = 5,
+ /obj/item/clothing/gloves = 8,
+ /obj/item/storage/toolbox = 2,
+ /obj/item/reagent_containers/pill = 2,
+ /obj/item/clothing/shoes = 8,
+ /obj/item/clothing/head = 3,
+ /obj/item/reagent_containers/food/snacks = 3,
+ /obj/item/reagent_containers/syringe/dart = 2,
+ /obj/item/reagent_containers/food/drinks/soda_cans = 5)
+ if(length >= 5)
+ return TRUE
+ //var/metalist = pickweight(GLOB.maintenance_loot)
+ for(var/i = length, i <= 5, i+=1)
+ var/obj/item = pickweight(rand_items)
+ if(!item)
+ i-=1
+ continue
+ for(var/obj/item_dupe in items_list) //No duplicates
+ if(item_dupe == item)
+ i-=1
+ continue
+ items_list += item
+ return TRUE
+
+/obj/item/pinpointer/jacq
+ name = "The Jacq-Tracq"
+ desc = "A handheld tracking device that locks onto witchy signals."
+
+/obj/item/pinpointer/jacq/attack_self(mob/living/user)
+ for(var/mob/living/simple_animal/jacq/J in GLOB.simple_animals[1])
+ target = J
+ ..()
diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween/halloween.dm
similarity index 92%
rename from code/modules/holiday/halloween.dm
rename to code/modules/holiday/halloween/halloween.dm
index a27db8dd38..5635994a7a 100644
--- a/code/modules/holiday/halloween.dm
+++ b/code/modules/holiday/halloween/halloween.dm
@@ -5,19 +5,27 @@
//spooky recipes
-/datum/recipe/sugarcookie/spookyskull
- reagents = list("flour" = 5, "sugar" = 5, "milk" = 5)
- items = list(
- /obj/item/reagent_containers/food/snacks/egg,
+/datum/crafting_recipe/food/sugarcookie/spookyskull
+ time = 15
+ name = "Sugar cookie"
+ reqs = list(
+ /datum/reagent/consumable/sugar = 5,
+ /obj/item/reagent_containers/food/snacks/pastrybase = 1
)
result = /obj/item/reagent_containers/food/snacks/sugarcookie/spookyskull
+ subcategory = CAT_PASTRY
-/datum/recipe/sugarcookie/spookycoffin
- reagents = list("flour" = 5, "sugar" = 5, "coffee" = 5)
- items = list(
- /obj/item/reagent_containers/food/snacks/egg,
+/datum/crafting_recipe/food/sugarcookie/spookycoffin
+ time = 15
+ name = "Sugar cookie"
+ reqs = list(
+ /datum/reagent/consumable/sugar = 5,
+ /datum/reagent/consumable/coffee = 5,
+ /obj/item/reagent_containers/food/snacks/pastrybase = 1
)
result = /obj/item/reagent_containers/food/snacks/sugarcookie/spookycoffin
+ subcategory = CAT_PASTRY
+
//////////////////////////////
//Spookoween trapped closets//
@@ -34,12 +42,12 @@
var/trapped = 0
var/mob/trapped_mob
-/obj/structure/closet/initialize()
+/obj/structure/closet/Initialize()
..()
if(prob(30))
set_spooky_trap()
-/obj/structure/closet/dump_contents()
+/obj/structure/closet/dump_contents(var/override = TRUE)
..()
trigger_spooky_trap()
@@ -256,6 +264,7 @@
desc = "A standard miniature energy crossbow that uses a hard-light projector to transform bolts into candy corn. Happy Halloween!"
category = "Holiday"
item = /obj/item/gun/energy/kinetic_accelerator/crossbow/halloween
+ cost = 12
surplus = 0
/datum/uplink_item/device_tools/emag/hack_o_lantern
diff --git a/code/modules/holiday/halloween/jacqueen.dm b/code/modules/holiday/halloween/jacqueen.dm
new file mode 100644
index 0000000000..d71e7c0f6a
--- /dev/null
+++ b/code/modules/holiday/halloween/jacqueen.dm
@@ -0,0 +1,471 @@
+//Conversation
+#define JACQ_HELLO (1<<0)
+#define JACQ_CANDIES (1<<1)
+#define JACQ_HEAD (1<<2)
+#define JACQ_FAR (1<<3)
+#define JACQ_WITCH (1<<4)
+#define JACQ_EXPELL (1<<5)
+#define JACQ_DATE (1<<6)
+
+/////// EVENT
+/datum/round_event_control/jacqueen
+ name = "Jacqueline's visit"
+ holidayID = "jacqueen"
+ typepath = /datum/round_event/jacqueen
+ weight = -1 //forces it to be called, regardless of weight
+ max_occurrences = 1
+ earliest_start = 0 MINUTES
+
+/datum/round_event/jacqueen/start()
+ ..()
+
+ for(var/mob/living/carbon/human/H in GLOB.carbon_list)
+ playsound(H, 'sound/spookoween/ahaha.ogg', 100, 0.25)
+
+ for(var/obj/effect/landmark/barthpot/bp in GLOB.landmarks_list)
+ new /obj/item/barthpot(bp.loc)
+ new /mob/living/simple_animal/jacq(bp.loc)
+
+/////// MOBS
+
+//Whacha doing in here like? Yae wan tae ruin ta magicks?
+/mob/living/simple_animal/jacq
+ name = "Jacqueline the Pumpqueen"
+ real_name = "Jacqueline"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "jacqueline"
+ maxHealth = 25
+ health = 25
+ density = FALSE
+ speech_span = "spooky"
+ friendly = "pets"
+ response_help = "chats with"
+ light_range = 3
+ light_color = "#ff9842"
+ var/last_poof
+ var/progression = list() //Keep track of where people are in the story.
+ var/active = TRUE //Turn this to false to keep normal mob behavour
+ var/cached_z
+
+/mob/living/simple_animal/jacq/Initialize()
+ ..()
+ cached_z = z
+ poof()
+
+/mob/living/simple_animal/jacq/Life()
+ ..()
+ if(!ckey)
+ if((last_poof+3 MINUTES) < world.realtime)
+ poof()
+
+/mob/living/simple_animal/jacq/Destroy() //I.e invincible
+ visible_message("[src] cackles, \"You'll nae get rid a me that easily!\" ")
+ playsound(loc, 'sound/spookoween/ahaha.ogg', 100, 0.25)
+ var/mob/living/simple_animal/jacq/Jacq = new src.type(loc)
+ Jacq.progression = progression
+ ..()
+
+/mob/living/simple_animal/jacq/death() //What is alive may never die
+ visible_message("[src] cackles, \"You'll nae get rid a me that easily!\" ")
+ playsound(loc, 'sound/spookoween/ahaha.ogg', 100, 0.25)
+ health = 25
+ poof()
+
+/mob/living/simple_animal/jacq/attack_hand(mob/living/carbon/human/M)
+ if(!active)
+ say("Hello there [gender_check(M)]!")
+ return ..()
+ if(!ckey)
+ canmove = FALSE
+ chit_chat(M)
+ canmove = TRUE
+ ..()
+
+/mob/living/simple_animal/jacq/attack_paw(mob/living/carbon/monkey/M)
+ if(!active)
+ say("Hello there [gender_check(M)]!")
+ return ..()
+ if(!ckey)
+ canmove = FALSE
+ chit_chat(M)
+ canmove = TRUE
+ ..()
+
+/mob/living/simple_animal/jacq/proc/poof()
+ last_poof = world.realtime
+ var/datum/reagents/R = new/datum/reagents(100)//Hey, just in case.
+ var/datum/effect_system/smoke_spread/chem/s = new()
+ R.add_reagent("secretcatchem", 10)
+ s.set_up(R, 0, loc)
+ s.start()
+ visible_message("[src] disappears in a puff of smoke!")
+ canmove = TRUE
+ health = 25
+
+ //Try to go to populated areas
+ var/list/pop_areas = list()
+ for(var/mob/living/L in GLOB.player_list)
+ var/area/A = get_area(L)
+ pop_areas += A
+
+ var/list/targets = list()
+ for(var/H in GLOB.network_holopads)
+ var/area/A = get_area(H)
+ if(!A || findtextEx(A.name, "AI") || !(A in pop_areas) || !is_station_level(H))
+ continue
+ targets += H
+
+ if(!targets)
+ targets = GLOB.generic_event_spawns
+
+ for(var/i in 1 to 6) //Attempts a jump up to 6 times.
+ var/atom/A = pick(targets)
+ if(do_teleport(src, A, channel = TELEPORT_CHANNEL_MAGIC))
+ return TRUE
+ targets -= A
+ return FALSE
+
+/mob/living/simple_animal/jacq/proc/gender_check(mob/living/carbon/C)
+ var/gender = "lamb"
+ if(C)
+ if(C.gender == MALE)
+ gender = "laddie"
+ if(C.gender == FEMALE)
+ gender = "lassie"
+ return gender
+
+//Ye wee bugger, gerrout of it. Ye've nae tae enjoy reading the code fer mae secrets like.
+/mob/living/simple_animal/jacq/proc/chit_chat(mob/living/carbon/C)
+ //Very important
+ var/gender = gender_check(C)
+ if(C)
+ if(C.gender == MALE)
+ gender = "laddie"
+ if(C.gender == FEMALE)
+ gender = "lassie"
+
+ if(!progression["[C.real_name]"] || !(progression["[C.real_name]"] & JACQ_HELLO))
+ visible_message("[src] smiles ominously at [C], \"Well halo there [gender]! Ah'm Jacqueline, tae great Pumpqueen, great tae meet ye.\" ")
+ sleep(20)
+ visible_message("[src] continues, \"Ah'm sure yae well stunned, but ah've got nae taem fer that. Ah'm after the candies around this station. If yae get mae enoof o the wee buggers, Ah'll give ye a treat, or if yae feeling bold, Ah ken trick ye instead. \" giving [C] a wide grin.")
+ if(!progression["[C.real_name]"])
+ progression["[C.real_name]"] = NONE //TO MAKE SURE THAT THE LIST ENTRY EXISTS.
+
+ progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_HELLO
+
+ var/choices = list("Trick", "Treat", "How do I get candies?")
+ var/choice = input(C, "Trick or Treat?", "Trick or Treat?") in choices
+ switch(choice)
+ if("Trick")
+ trick(C)
+ return
+ if("Treat")
+ if(check_candies(C))
+ treat(C, gender)
+ else
+ visible_message("[src] raises an eyebrow, \"You've nae got any candies Ah want! They're the orange round ones, now bugger off an go get em first.\" ")
+ return
+ if("How do I get candies?")
+ visible_message("[src] says, \"Gae find my familiar; Bartholomew. Ee's tendin the cauldron which ken bring oot t' magic energy in items scattered aroond. Knowing him, ee's probably gone tae somewhere with books.\" ")
+ return
+
+/mob/living/simple_animal/jacq/proc/treat(mob/living/carbon/C, gender)
+ visible_message("[src] gives off a glowing smile, \"What ken Ah offer ye? I can magic up an object, a potion or a plushie fer ye.\" ")
+ var/choices_reward = list("Object - 3 candies", "Potion - 2 candies", "Jacqueline Tracker - 2 candies", "Plushie - 1 candy", "Can I get to know you instead?", "Become a pumpkinhead dullahan (perma) - 4 candies")
+ var/choice_reward = input(usr, "Trick or Treat?", "Trick or Treat?") in choices_reward
+
+ //rewards
+ switch(choice_reward)
+ if("Become a pumpkinhead dullahan (perma) - 4 candies")
+ if(!take_candies(C, 4))
+ visible_message("[src] raises an eyebrown, \"It's 4 candies for that [gender]! Thems the rules!\" ")
+ return
+ visible_message("[src] waves their arms around, \"Off comes your head, a pumpkin taking it's stead!\" ")
+ C.reagents.add_reagent("pumpkinmutationtoxin", 5)
+ sleep(20)
+ poof()
+ return
+
+ if("Object - 3 candies")
+ if(!take_candies(C, 3))
+ visible_message("[src] raises an eyebrown, \"It's 3 candies per trinket [gender]! Thems the rules!\" ")
+ return
+
+ var/new_obj = pick(subtypesof(/obj))
+ //for(var/item in blacklist)
+ // if(new_obj == item)
+ // panic()
+ var/reward = new new_obj(C.loc)
+ C.put_in_hands(reward)
+ visible_message("[src] waves her hands, magicking up a [reward] from thin air, \"There ye are [gender], enjoy! \" ")
+ sleep(20)
+ poof()
+ return
+ if("Potion - 2 candies")
+ if(!take_candies(C, 2))
+ visible_message("[src] raises an eyebrow, \"It's 2 candies per potion [gender]! Thems the rules!\" ")
+ return
+
+ var/reward = new /obj/item/reagent_containers/potion_container(C.loc)
+ C.put_in_hands(reward)
+ visible_message("[src] waves her hands, magicking up a [reward] from thin air, \"There ye are [gender], enjoy! \" ")
+ sleep(20)
+ poof()
+ return
+ if("Plushie - 1 candy")
+ if(!take_candies(C, 1))
+ visible_message("[src] raises an eyebrow, \"It's 1 candy per plushie [gender]! Thems the rules!\" ")
+ return
+
+ new /obj/item/toy/plush/random(C.loc)
+ visible_message("[src] waves her hands, magicking up a plushie from thin air, \"There ye are [gender], enjoy! \" ")
+ sleep(20)
+ poof()
+ return
+ if("Jacqueline Tracker - 2 candies")
+ if(!take_candies(C, 2))
+ visible_message("[src] raises an eyebrow, \"It's 1 candy per plushie [gender]! Thems the rules!\" ")
+ return
+ new /obj/item/pinpointer/jacq(C.loc)
+ visible_message("[src] waves her hands, magicking up a tracker from thin air, \"Feels weird to magic up a tracker fer meself but, here ye are [gender], enjoy! \" ")
+ sleep(20)
+ poof()
+ return
+
+ //chitchats!
+ if("Can I get to know you instead?")
+ var/choices = list()
+ //Figure out where the C is in the story
+ if(!progression["[C.real_name]"]) //I really don't want to get here withoot a hello, but just to be safe
+ progression["[C.real_name]"] = NONE
+ if(!(progression["[C.real_name]"] & JACQ_FAR))
+ if(progression["[C.real_name]"] & JACQ_CANDIES)
+ choices += "You really came all this way for candy?"
+ else
+ choices += "Why do you want the candies?"
+ if(!(progression["[C.real_name]"] & JACQ_HEAD))
+ choices += "What is that on your head?"
+ if(!(progression["[C.real_name]"] & JACQ_EXPELL))
+ if(progression["[C.real_name]"] & JACQ_WITCH)
+ choices += "So you got ex-spell-ed?"
+ else
+ choices += "Are you a witch?"
+
+ //for Kepler, delete this, or just delete the whole story aspect if you want.
+ //If fully completed
+ /*
+ if(progression["[C.real_name]"] & JACQ_FAR)//Damnit this is a pain
+ if(progression["[C.real_name]"] & JACQ_EXPELL) //I give up
+ if(progression["[C.real_name]"] & JACQ_HEAD) //This is only an event thing
+ choices += "Can I take you out on a date?"
+ */
+ if(progression["[C.real_name]"] == 63)//Damnit this is a pain
+ choices += "Can I take you out on a date?"
+
+ //If you've nothing to ask
+ if(!LAZYLEN(choices))
+ visible_message("[src] sighs, \"Ah'm all questioned oot fer noo, [gender].\" ")
+ return
+ //Otherwise, lets go!
+ visible_message("[src] says, \"A question? Sure, it'll cost you a candy though!\" ")
+ choices += "Nevermind"
+ //Candies for chitchats
+ var/choice = input(C, "What do you want to ask?", "What do you want to ask?") in choices
+ if(!take_candies(C, 1))
+ visible_message("[src] raises an eyebrow, \"It's a candy per question [gender]! Thems the rules!\" ")
+ return
+ //Talking
+ switch(choice)
+ if("Why do you want the candies?")
+ visible_message("[src] says, \"Ave ye tried them? They're full of all sorts of reagents. Ah'm after them so ah ken magic em up an hopefully find rare stuff fer me brews. Honestly it's a lot easier magicking up tatt fer ye lot than runnin aroond on me own like. I'd ask me familiars but most a my familiars are funny fellows 'n constantly bugger off on adventures when given simple objectives like; Go grab me a tea cake or watch over me cauldron. Ah mean, ye might run into Bartholomew my cat. Ee's supposed tae be tending my cauldron, but I've nae idea where ee's got tae.\" ")
+ progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_CANDIES
+ sleep(30)
+
+ if("You really came all this way for candy?")
+ visible_message("[src] l ooks tae the side sheepishly, \"Aye, well, tae be honest, Ah'm here tae see me sis, but dunnae let her knew that. She's an alchemist too like, but she dunnae use a caldron like mae, she buggered off like tae her posh ivory tower tae learn bloody chemistry instead!\" [src] scowls, \"She's tae black sheep o' the family too, so we dunnae see eye tae eye sometimes on alchemy. Ah mean, she puts moles in her brews! Ye dunnae put moles in yer brews! Yae threw your brews at tae wee bastards an blew em up!\" [src] sighs, \"But she's a heart o gold so.. Ah wanted tae see her an check up oon her, make sure she's okay.\" ")
+ progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_FAR
+ sleep(30)
+
+ if("What is that on your head?")
+ visible_message("[src] pats the pumpkin atop her head, \"This thing? This ain't nae ordinary pumpkin! Me Ma grew this monster ooer a year o love, dedication an hard work. Honestly it felt like she loved this thing more than any of us, which Ah knew ain't true an it's not like she was hartless or anything but.. well, we had a falling oot when Ah got back home with all me stuff in tow. An all she had done is sent me owl after owl over t' last year aboot this bloody pumpkin and ah had enough. So ah took it, an put it on me head. You know, as ye do. Ah am the great Pumpqueen after all, Ah deserve this.\" ")
+ progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_HEAD
+ sleep(30)
+
+ if("Are you a witch?")
+ visible_message("[src] grumbles, \"If ye must know, Ah got kicked oot of the witch academy fer being too much of a \"loose cannon\". A bloody loose cannon? Nae they were just pissed off Ah had the brass tae proclaim myself as the Pumpqueen! And also maybe the time Ah went and blew up one of the towers by trying tae make a huge batch of astrogen might've had something tae do with it. Ah mean it would've worked fine if the cauldrons weren't so shite and were actually upgraded by the faculty. So technically no, I'm not a witch.\" ")
+ progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_WITCH
+ sleep(30)
+
+ if("So you got ex-spell-ed?")
+ visible_message("[src] Gives you a blank look at the pun, before continuing, \"Not quite, Ah know Ah ken get back into the academy, it's only an explosion, they happen all the time, but, tae be fair it's my fault that things came tae their explosive climax. You don't know what it's like when you're after a witch doctorate, everyone else is doing well, everyone's making new spells and the like, and I'm just good at making explosions really, or fireworks. So, Ah did something Ah knew was dangerous, because Ah had tae do something tae stand oot, but Ah know this life ain't fer me, Ah don't want tae be locked up in dusty towers, grinding reagent after reagent together, trying tae find new reactions, some of the wizards in there haven't left fer years. Ah want tae live, Ah want tae fly around on a broom, turn people into cats fer a day and disappear cackling! That's what got me into witchcraft!\" she throws her arms up in the arm, spinning the pumpkin upon her head slightly. She carefully spins it back to face you, giving oot a soft sigh, \"Ah know my mother's obsession with this dumb thing on my head is just her trying tae fill the void of me and my sis moving oot, and it really shouldn't be on my head. And Ah know that I'm really here tae get help from my sis.. She's the sensible one, and she gives good hugs.\" ")
+ sleep(30)
+ visible_message("[src] says, \"Thanks [C], Ah guess Ah didn't realise Ah needed someone tae talk tae but, I'm glad ye spent all your candies talking tae me. Funny how things seem much worse in yer head.\" ")
+ progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_EXPELL
+ sleep(30)
+
+ if("Can I take you out on a date?")
+ visible_message("[src] blushes, \"...You want tae ask me oot on a date? Me? After all that nonsense Ah just said? It seems a waste of a candy honestly.\" ")
+ //progression["[C.real_name]"] = progression["[C.real_name]"] | JACQ_DATE
+ visible_message("[src] looks to the side, deep in thought. ")
+ dating_start(C, gender)
+
+ if("Nevermind")
+ visible_message("
[src] shrugs,
\"Suit yerself then, here's your candy back.\" ")
+ new /obj/item/reagent_containers/food/snacks/special_candy(loc)
+
+
+/mob/living/simple_animal/jacq/proc/trick(mob/living/carbon/C, gender)
+ var/option
+ if(ishuman(C))
+ option = rand(1,6)
+ else
+ option = rand(1,5)
+ switch(option)
+ if(1)
+ visible_message("
[src] waves their arms around,
\"Hocus pocus, making friends is now your focus!\" ")
+ var/message = pick("make a tasty sandwich for", "compose a poem for", "aquire a nice outfit to give to", "strike up a conversation about pumpkins with", "write a letter and deliver it to", "give a nice hat to")
+ var/mob/living/L2 = pick(GLOB.player_list)
+ message += " [L2.name]."
+ to_chat(C, "
You feel an overwhelming desire to [message]")
+ if(2)
+ visible_message("[src] waves their arms around, \"If only you had a better upbringing, your ears are now full of my singing!\" ")
+ var/client/C2 = C.client
+ C2.chatOutput.sendMusic("https://puu.sh/ExBbv.mp4", 1)//I hope this works!
+ if(3)
+ visible_message("[src] waves their arms around, \"You're cute little bumpkin, On your head is a pumpkin!\" ")
+ if(C.head)
+ var/obj/item/W = C.head
+ C.dropItemToGround(W, TRUE)
+ var/jaqc_latern = new /obj/item/clothing/head/hardhat/pumpkinhead/jaqc
+ C.equip_to_slot(jaqc_latern, SLOT_HEAD, 1, 1)
+ if(4)
+ visible_message("[src] waves their arms around, \"In your body there's something amiss, you'll find it's a chem made by my sis!\" ")
+ C.reagents.add_reagent("eigenstate", 30)
+ if(5)
+ visible_message("[src] waves their arms around, \"A new familiar for me, and you'll see it's thee!\" ")
+ C.reagents.add_reagent("secretcatchem", 30)
+ if(6)
+ visible_message("[src] waves their arms around, \"While you may not be a ghost, for this sheet you'll always be it's host.\" ")
+ var/mob/living/carbon/human/H = C
+ if(H.wear_suit)
+ var/obj/item/W = H.wear_suit
+ H.dropItemToGround(W, TRUE)
+ var/ghost = new /obj/item/clothing/suit/ghost_sheet/sticky
+ H.equip_to_slot(ghost, SLOT_WEAR_SUIT, 1, 1)
+ poof()
+
+//Blame Fel
+/mob/living/simple_animal/jacq/proc/dating_start(mob/living/carbon/C, gender)
+ var/candies = pollGhostCandidates("Do you want to go on a date with [C] as Jacqueline the great pumpqueen?")
+ //sleep(30) //If the poll doesn't autopause.
+ if(candies)
+ candies = shuffle(candies)//Shake those ghosts up!
+ for(var/mob/dead/observer/C2 in candies)
+ if(C2.key && C2)
+ key = C2.key
+ message_admins("[C2]/[C2.key] has agreed to go on a date with [C] as Jacqueline.")
+ log_game("HALLOWEEN: [C2]/[C2.key] has agreed to go on a date with [C] as Jacqueline")
+ to_chat(src, "You are Jacqueline the great pumpqueen, witch Extraordinaire! You're a very Scottish lass with a kind heart, but also a little crazy. You also blew up the wizarding school and you're suspended for a while, so you visited the station before heading home. On your head lies the prize pumpkin of your Mother's pumpkin patch. You're currently on a date with [C] and well, I didn't think anyone would get this far. Please be good so I can do events like this in the future. ")
+ return
+ else
+ candies =- C2
+ visible_message("[src] looks to the side, \"Look, Ah like ye but, Ah don't think Ah can right now. If ye can't tell, the stations covered in volatile candies, I've a few other laddies and lassies running after me treats, and tae top it all off, I've the gods breathing down me neck, watching every treat Ah make fer the lot of yous.\" she sighs, \"But that's not a no, right? That's.. just a nae right noo.\" ")
+ sleep(20)
+ visible_message("[src] takes off the pumpkin on her head, a rich blush on her cheeks. She leans over planting a kiss upon your forehead quickly befere popping the pumpkin back on her head.")
+ sleep(10)
+ visible_message("[src] waves their arms around, \"There, that aught tae be worth a candy.\" ")
+ sleep(20)
+ poof()
+
+/obj/item/clothing/head/hardhat/pumpkinhead/jaqc
+ name = "Jacq o' latern"
+ desc = "A jacqueline o' lantern! You can't seem to get rid of it."
+ icon_state = "hardhat0_pumpkin_j"
+ item_state = "hardhat0_pumpkin_j"
+ item_color = "pumpkin_j"
+ brightness_on = 4
+
+/obj/item/clothing/head/hardhat/pumpkinhead/jaqc/Initialize()
+ . = ..()
+ ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT)
+
+/obj/item/clothing/suit/ghost_sheet/sticky
+
+/obj/item/clothing/suit/ghost_sheet/sticky/Initialize()
+ . = ..()
+ ADD_TRAIT(src, TRAIT_NODROP, GLUED_ITEM_TRAIT)
+
+/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user)
+ if(iscarbon(user))
+ to_chat(user, "Boooooo~! ")
+ return
+ else
+ ..()
+
+/obj/item/clothing/suit/ghost_sheet/sticky/attack_hand(mob/user)
+ if(iscarbon(user))
+ to_chat(user, "Boooooo~! ")
+ return
+ else
+ ..()
+
+/datum/reagent/mutationtoxin/pumpkinhead
+ name = "Pumpkin head mutation toxin"
+ id = "pumpkinmutationtoxin"
+ race = /datum/species/dullahan/pumpkin
+ mutationtext = "The pain subsides. You feel your head roll off your shoulders... and you smell pumpkin."
+ //I couldn't get the replace head sprite with a pumpkin to work so, it is what it is.
+
+/mob/living/simple_animal/jacq/proc/check_candies(mob/living/carbon/C)
+ var/invs = C.get_contents()
+ var/candy_count = 0
+ for(var/item in invs)
+ if(istype(item, /obj/item/reagent_containers/food/snacks/special_candy))
+ candy_count++
+ return candy_count
+
+/mob/living/simple_animal/jacq/proc/take_candies(mob/living/carbon/C, candy_amount = 1)
+ var/inv = C.get_contents()
+ var/candies = list()
+ for(var/item in inv)
+ if(istype(item, /obj/item/reagent_containers/food/snacks/special_candy))
+ candies += item
+ if(LAZYLEN(candies) == candy_amount)
+ break
+ if(LAZYLEN(candies) == candy_amount) //I know it's a double check but eh, to be safe.
+ for(var/candy in candies)
+ qdel(candy)
+ return TRUE
+ return FALSE
+
+//Potions
+/obj/item/reagent_containers/potion_container
+ name = "potion"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "jacq_potion"
+ desc = "A potion with a strange concoction within. Be careful, as if it's thrown it explodes in a puff of smoke like Jacqueline."
+
+/obj/item/reagent_containers/potion_container/Initialize()
+ .=..()
+ var/R = get_random_reagent_id()
+ reagents.add_reagent(R, 30)
+ name = "[R] Potion"
+
+/obj/item/reagent_containers/potion_container/throw_impact(atom/target)
+ ..()
+ sleep(20)
+ var/datum/effect_system/smoke_spread/chem/s = new()
+ s.set_up(src.reagents, 3, src.loc)
+ s.start()
+ qdel(src)
+
+//Candies
+/obj/item/reagent_containers/food/snacks/special_candy
+ name = "Magic candy"
+ icon = 'icons/obj/halloween_items.dmi'
+ icon_state = "jacq_candy"
+ desc = "A candy with strange magic within. Be careful, as the magic isn't always helpful."
+
+/obj/item/reagent_containers/food/snacks/special_candy/Initialize()
+ .=..()
+ reagents.add_reagent(get_random_reagent_id(), 5)
diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm
index 7d1e25235d..9d075857a7 100644
--- a/code/modules/holiday/holidays.dm
+++ b/code/modules/holiday/holidays.dm
@@ -333,6 +333,16 @@
/datum/holiday/halloween/getStationPrefix()
return pick("Bone-Rattling","Mr. Bones' Own","2SPOOKY","Spooky","Scary","Skeletons")
+/datum/holiday/jacqueen //Subset of halloween
+ name = "jacqueen"
+ begin_day = 27
+ begin_month = OCTOBER
+ end_day = 2
+ end_month = NOVEMBER
+
+/datum/holiday/jacqueen/greet()
+ return "Jacqueline the great Pumpqueen has come to visit!"
+
/datum/holiday/vegan
name = "Vegan Day"
begin_day = 1
diff --git a/code/modules/holodeck/computer.dm b/code/modules/holodeck/computer.dm
index 6cc11afdf5..889706744a 100644
--- a/code/modules/holodeck/computer.dm
+++ b/code/modules/holodeck/computer.dm
@@ -111,6 +111,11 @@
if(A)
load_program(A)
if("safety")
+ if(!issilicon(usr) && !IsAdminGhost(usr))
+ var/msg = "[key_name(usr)] attempted to emag the holodeck using a href they shouldn't have!"
+ message_admins(msg)
+ log_admin(msg)
+ return
obj_flags ^= EMAGGED
if((obj_flags & EMAGGED) && program && emag_programs[program.name])
emergency_shutdown()
diff --git a/code/modules/hydroponics/beekeeping/beekeeper_suit.dm b/code/modules/hydroponics/beekeeping/beekeeper_suit.dm
index 7fa1a0dd2c..fd9f879f5e 100644
--- a/code/modules/hydroponics/beekeeping/beekeeper_suit.dm
+++ b/code/modules/hydroponics/beekeeping/beekeeper_suit.dm
@@ -4,7 +4,7 @@
desc = "Keeps the lil buzzing buggers out of your eyes."
icon_state = "beekeeper"
item_state = "beekeeper"
- clothing_flags = THICKMATERIAL
+ clothing_flags = THICKMATERIAL | SNUG_FIT
/obj/item/clothing/suit/beekeeper_suit
diff --git a/code/modules/hydroponics/grown/banana.dm b/code/modules/hydroponics/grown/banana.dm
index 251d9de5c0..b25f76c1c8 100644
--- a/code/modules/hydroponics/grown/banana.dm
+++ b/code/modules/hydroponics/grown/banana.dm
@@ -11,7 +11,7 @@
growing_icon = 'icons/obj/hydroponics/growing_fruits.dmi'
icon_dead = "banana-dead"
genes = list(/datum/plant_gene/trait/slip, /datum/plant_gene/trait/repeated_harvest)
- mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace)
+ mutatelist = list(/obj/item/seeds/banana/mime, /obj/item/seeds/banana/bluespace, /obj/item/seeds/banana/exotic_banana)
reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02)
/obj/item/reagent_containers/food/snacks/grown/banana
@@ -120,6 +120,41 @@
desc = "A peel from a bluespace banana."
icon_state = "banana_peel_blue"
+//Banana Spider.
+/obj/item/seeds/banana/exotic_banana
+ name = "pack of exotic banana seeds"
+ desc = "They're seeds that grow into banana trees. However, those bananas might be alive."
+ icon_state = "seed_exoticbanana"
+ species = "exoticbanana"
+ icon_grow = "banana-grow"
+ plantname = "Exotic Banana Tree"
+ product = /obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable
+ mutatelist = list()
+ genes = list(/datum/plant_gene/trait/slip)
+
+/obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable
+ seed = /obj/item/seeds/banana/exotic_banana
+ name = "banana spider"
+ desc = "You do not know what it is, but you can bet the clown would love it."
+ icon_state = "exoticbanana"
+ list_reagents = list("nutriment" = 3, "vitamin" = 2)
+ foodtype = GROSS | MEAT | RAW | FRUIT
+ grind_results = list("blood" = 20, "liquidgibs" = 5)
+ var/awakening = 0
+
+/obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable/attack_self(mob/user)
+ if(awakening || isspaceturf(user.loc))
+ return
+ to_chat(user, "You decide to wake up the banana spider... ")
+ awakening = 1
+
+ spawn(30)
+ if(!QDELETED(src))
+ var/mob/living/simple_animal/banana_spider/S = new /mob/living/simple_animal/banana_spider(get_turf(src.loc))
+ S.speed += round(10 / seed.potency)
+ S.visible_message("The banana spider chitters as it stretches its legs. ")
+ qdel(src)
+
// Other
/obj/item/grown/bananapeel/specialpeel //used by /obj/item/clothing/shoes/clown_shoes/banana_shoes
name = "synthesized banana peel"
diff --git a/code/modules/hydroponics/grown/corn.dm b/code/modules/hydroponics/grown/corn.dm
index c259baaf2d..0e5b5272ed 100644
--- a/code/modules/hydroponics/grown/corn.dm
+++ b/code/modules/hydroponics/grown/corn.dm
@@ -40,7 +40,7 @@
throw_range = 7
/obj/item/grown/corncob/attackby(obj/item/grown/W, mob/user, params)
- if(W.is_sharp())
+ if(W.get_sharpness())
to_chat(user, "You use [W] to fashion a pipe out of the corn cob! ")
new /obj/item/clothing/mask/cigarette/pipe/cobpipe (user.loc)
qdel(src)
diff --git a/code/modules/hydroponics/grown/flowers.dm b/code/modules/hydroponics/grown/flowers.dm
index f1aea5706a..af5919969c 100644
--- a/code/modules/hydroponics/grown/flowers.dm
+++ b/code/modules/hydroponics/grown/flowers.dm
@@ -37,7 +37,7 @@
species = "lily"
plantname = "Lily Plants"
product = /obj/item/reagent_containers/food/snacks/grown/poppy/lily
- mutatelist = list()
+ mutatelist = list(/obj/item/seeds/bee_balm)
/obj/item/reagent_containers/food/snacks/grown/poppy/lily
seed = /obj/item/seeds/poppy/lily
@@ -221,3 +221,61 @@
if(!user.gloves)
to_chat(user, "The [name] burns your bare hand! ")
user.adjustFireLoss(rand(1, 5))
+
+// Beebalm
+/obj/item/seeds/bee_balm
+ name = "pack of Bee Balm seeds"
+ desc = "These seeds grow into Bee Balms."
+ icon_state = "seed-bee_balm"
+ species = "bee_balm"
+ plantname = "Bee Balm Buds"
+ product = /obj/item/reagent_containers/food/snacks/grown/bee_balm
+ endurance = 10
+ maturation = 8
+ yield = 3
+ potency = 30
+ growthstages = 3
+ growing_icon = 'icons/obj/hydroponics/growing_flowers.dmi'
+ icon_grow = "bee_balm-grow"
+ icon_dead = "bee_balm-dead"
+ mutatelist = list(/obj/item/seeds/poppy/geranium, /obj/item/seeds/bee_balm/honey) //Lower odds of becoming honey
+ reagents_add = list("spaceacillin" = 0.1, "sterilizine" = 0.05)
+
+/obj/item/reagent_containers/food/snacks/grown/bee_balm
+ seed = /obj/item/seeds/bee_balm
+ name = "bee balm"
+ desc = "A flower used for medical antiseptic in history."
+ icon_state = "bee_balm"
+ filling_color = "#FF6347"
+ bitesize_mod = 8
+ tastes = list("strong antiseptic " = 1)
+ foodtype = GROSS
+
+// Beebalm
+/obj/item/seeds/bee_balm/honey
+ name = "pack of Honey Balm seeds"
+ desc = "These seeds grow into Honey Balms."
+ icon_state = "seed-bee_balmalt"
+ species = "seed-bee_balm_alt"
+ plantname = "Honey Balm Pods"
+ product = /obj/item/reagent_containers/food/snacks/grown/bee_balm/honey
+ endurance = 1
+ maturation = 10
+ yield = 1
+ potency = 1
+ growthstages = 3
+ growing_icon = 'icons/obj/hydroponics/growing_flowers.dmi'
+ icon_grow = "bee_balmalt-grow"
+ icon_dead = "bee_balmalt-dead"
+ reagents_add = list("honey" = 0.1, "lye" = 0.3) //To make wax
+ rarity = 30
+
+/obj/item/reagent_containers/food/snacks/grown/bee_balm/honey
+ seed = /obj/item/seeds/bee_balm/honey
+ name = "honey balm"
+ desc = "A large honey filled pod of a flower."
+ icon_state = "bee_balmalt"
+ filling_color = "#FF6347"
+ bitesize_mod = 8
+ tastes = list("wax" = 1)
+ foodtype = SUGAR
\ No newline at end of file
diff --git a/code/modules/hydroponics/grown/melon.dm b/code/modules/hydroponics/grown/melon.dm
index 29691c3289..87db12d892 100644
--- a/code/modules/hydroponics/grown/melon.dm
+++ b/code/modules/hydroponics/grown/melon.dm
@@ -58,6 +58,20 @@
wine_power = 70 //Water to wine, baby.
wine_flavor = "divinity"
+/*
/obj/item/reagent_containers/food/snacks/grown/holymelon/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE) //deliver us from evil o melon god
+ var/uses = 1
+ if(seed)
+ uses = round(seed.potency / 20)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, ITEM_SLOT_HANDS, uses, TRUE, CALLBACK(src, .proc/block_magic), CALLBACK(src, .proc/expire)) //deliver us from evil o melon god
+
+/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/block_magic(mob/user, major)
+ if(major)
+ to_chat(user, "[src] hums slightly, and seems to decay a bit. ")
+
+/obj/item/reagent_containers/food/snacks/grown/holymelon/proc/expire(mob/user)
+ to_chat(user, "[src] rapidly turns into ash! ")
+ qdel(src)
+ new /obj/effect/decal/cleanable/ash(drop_location())
+*/
\ No newline at end of file
diff --git a/code/modules/hydroponics/grown/potato.dm b/code/modules/hydroponics/grown/potato.dm
index 15378b368e..50341dfa3a 100644
--- a/code/modules/hydroponics/grown/potato.dm
+++ b/code/modules/hydroponics/grown/potato.dm
@@ -38,7 +38,7 @@
/obj/item/reagent_containers/food/snacks/grown/potato/attackby(obj/item/W, mob/user, params)
- if(W.is_sharp())
+ if(W.get_sharpness())
to_chat(user, "You cut the potato into wedges with [W]. ")
var/obj/item/reagent_containers/food/snacks/grown/potato/wedges/Wedges = new /obj/item/reagent_containers/food/snacks/grown/potato/wedges
remove_item_from_storage(user)
diff --git a/code/modules/hydroponics/grown/pumpkin.dm b/code/modules/hydroponics/grown/pumpkin.dm
index 644dedff3d..02bc776b78 100644
--- a/code/modules/hydroponics/grown/pumpkin.dm
+++ b/code/modules/hydroponics/grown/pumpkin.dm
@@ -28,7 +28,7 @@
wine_power = 20
/obj/item/reagent_containers/food/snacks/grown/pumpkin/attackby(obj/item/W as obj, mob/user as mob, params)
- if(W.is_sharp())
+ if(W.get_sharpness())
user.show_message("You carve a face into [src]! ", 1)
new /obj/item/clothing/head/hardhat/pumpkinhead(user.loc)
qdel(src)
diff --git a/code/modules/hydroponics/grown/root.dm b/code/modules/hydroponics/grown/root.dm
index 090809ca88..e28043e4b1 100644
--- a/code/modules/hydroponics/grown/root.dm
+++ b/code/modules/hydroponics/grown/root.dm
@@ -26,7 +26,7 @@
wine_power = 30
/obj/item/reagent_containers/food/snacks/grown/carrot/attackby(obj/item/I, mob/user, params)
- if(I.is_sharp())
+ if(I.get_sharpness())
to_chat(user, "You sharpen the carrot into a shiv with [I]. ")
var/obj/item/kitchen/knife/carrotshiv/Shiv = new /obj/item/kitchen/knife/carrotshiv
remove_item_from_storage(user)
diff --git a/code/modules/hydroponics/grown/tea_coffee.dm b/code/modules/hydroponics/grown/tea_coffee.dm
index 06cbb1df0c..bdb5bdb3f9 100644
--- a/code/modules/hydroponics/grown/tea_coffee.dm
+++ b/code/modules/hydroponics/grown/tea_coffee.dm
@@ -51,7 +51,6 @@
desc = "Long stocks with flowering tips that has a chemical to make feline attracted to it."
species = "catnip"
plantname = "Catnip Plant"
- growthstages = 3
product = /obj/item/reagent_containers/food/snacks/grown/tea/catnip
reagents_add = list("catnip" = 0.1, "vitamin" = 0.06, "teapowder" = 0.3)
rarity = 50
@@ -59,7 +58,7 @@
/obj/item/reagent_containers/food/snacks/grown/tea/catnip
seed = /obj/item/seeds/tea/catnip
name = "Catnip buds"
- icon_state = "catnip_leaves"
+ icon_state = "catnip"
filling_color = "#4582B4"
grind_results = list("catnp" = 2, "water" = 1)
diff --git a/code/modules/hydroponics/grown/towercap.dm b/code/modules/hydroponics/grown/towercap.dm
index 23f178edc9..9a660ac282 100644
--- a/code/modules/hydroponics/grown/towercap.dm
+++ b/code/modules/hydroponics/grown/towercap.dm
@@ -120,7 +120,7 @@
/obj/structure/bonfire/prelit/Initialize()
. = ..()
StartBurning()
-
+
/obj/structure/bonfire/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSTABLE))
return TRUE
@@ -148,7 +148,7 @@
add_overlay("bonfire_grill")
else
return ..()
- if(W.is_hot())
+ if(W.get_temperature())
StartBurning()
if(grill)
if(user.a_intent != INTENT_HARM && !(W.item_flags & ABSTRACT))
diff --git a/code/modules/hydroponics/seed_extractor.dm b/code/modules/hydroponics/seed_extractor.dm
index ffa9e2e21d..d9bea64411 100644
--- a/code/modules/hydroponics/seed_extractor.dm
+++ b/code/modules/hydroponics/seed_extractor.dm
@@ -174,7 +174,7 @@
to_chat(usr, "\The [src] is full. ")
return FALSE
- GET_COMPONENT_FROM(STR, /datum/component/storage, O.loc)
+ var/datum/component/storage/STR = O.loc.GetComponent(/datum/component/storage)
if(STR)
if(!STR.remove_from_storage(O,src))
return FALSE
diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm
index b258a15972..b7feedd312 100644
--- a/code/modules/integrated_electronics/subtypes/input.dm
+++ b/code/modules/integrated_electronics/subtypes/input.dm
@@ -893,7 +893,7 @@
return FALSE
var/ignore_bags = get_pin_data(IC_INPUT, 1)
if(ignore_bags)
- GET_COMPONENT_FROM(STR, /datum/component/storage, A)
+ var/datum/component/storage/STR = A.GetComponent(/datum/component/storage)
if(STR)
return FALSE
set_pin_data(IC_OUTPUT, 1, WEAKREF(A))
@@ -1104,7 +1104,7 @@
/obj/item/integrated_circuit/input/matscan/do_work()
var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
var/turf/T = get_turf(src)
- GET_COMPONENT_FROM(mt, /datum/component/material_container, H)
+ var/datum/component/material_container/mt = H.GetComponent(/datum/component/material_container)
if(!mt) //Invalid input
return
if(H in view(T)) // This is a camera. It can't examine thngs,that it can't see.
diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm
index 682e76a46e..fb00897eec 100644
--- a/code/modules/integrated_electronics/subtypes/manipulation.dm
+++ b/code/modules/integrated_electronics/subtypes/manipulation.dm
@@ -339,7 +339,7 @@
assembly.visible_message("[assembly] has thrown [A]! ")
log_attack("[assembly] [REF(assembly)] has thrown [A] with non-lethal force.")
A.forceMove(drop_location())
- A.throw_at(locate(x_abs, y_abs, T.z), range, 3, , , , CALLBACK(src, .proc/post_throw, A))
+ A.throw_at(locate(x_abs, y_abs, T.z), range, 3, null, null, null, CALLBACK(src, .proc/post_throw, A))
// If the item came from a grabber now we can update the outputs since we've thrown it.
if(istype(G))
@@ -411,7 +411,7 @@
.=..()
/obj/item/integrated_circuit/manipulation/matman/proc/AfterMaterialInsert(type_inserted, id_inserted, amount_inserted)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
set_pin_data(IC_OUTPUT, 2, materials.total_amount)
for(var/I in 1 to mtypes.len)
var/datum/material/M = materials.materials[mtypes[I]]
@@ -423,7 +423,7 @@
return TRUE
/obj/item/integrated_circuit/manipulation/matman/do_work(ord)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/atom/movable/H = get_pin_data_as_type(IC_INPUT, 1, /atom/movable)
if(!check_target(H))
activate_pin(4)
@@ -441,7 +441,7 @@
else
activate_pin(4)
if(2)
- GET_COMPONENT_FROM(mt, /datum/component/material_container, H)
+ var/datum/component/material_container/mt = H.GetComponent(/datum/component/material_container)
var/suc
for(var/I in 1 to mtypes.len)
var/datum/material/M = materials.materials[mtypes[I]]
@@ -467,7 +467,7 @@
activate_pin(6)
/obj/item/integrated_circuit/manipulation/matman/Destroy()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
.=..()
@@ -509,14 +509,14 @@
if(!container || !istype(container,/obj/item/storage) || !Adjacent(container))
return
- GET_COMPONENT_FROM(STR, /datum/component/storage, container)
+ var/datum/component/storage/STR = container.GetComponent(/datum/component/storage)
if(!STR)
return
STR.attackby(src, target_obj)
else
- GET_COMPONENT_FROM(STR, /datum/component/storage, target_obj.loc)
+ var/datum/component/storage/STR = target_obj.loc.GetComponent(/datum/component/storage)
if(!STR)
return
diff --git a/code/modules/jobs/access.dm b/code/modules/jobs/access.dm
index e88a80514a..2119baf1a5 100644
--- a/code/modules/jobs/access.dm
+++ b/code/modules/jobs/access.dm
@@ -1,368 +1,372 @@
-
-//returns TRUE if this mob has sufficient access to use this object
-/obj/proc/allowed(mob/M)
- //check if it doesn't require any access at all
- if(src.check_access(null))
- return TRUE
- if(issilicon(M))
- if(ispAI(M))
- return FALSE
- return TRUE //AI can do whatever it wants
- if(IsAdminGhost(M))
- //Access can't stop the abuse
- return TRUE
- else if(istype(M) && SEND_SIGNAL(M, COMSIG_MOB_ALLOWED, src))
- return TRUE
- else if(ishuman(M))
- var/mob/living/carbon/human/H = M
- //if they are holding or wearing a card that has access, that works
- if(check_access(H.get_active_held_item()) || src.check_access(H.wear_id))
- return TRUE
- else if(ismonkey(M) || isalienadult(M))
- var/mob/living/carbon/george = M
- //they can only hold things :(
- if(check_access(george.get_active_held_item()))
- return TRUE
- else if(isanimal(M))
- var/mob/living/simple_animal/A = M
- if(check_access(A.get_active_held_item()) || check_access(A.access_card))
- return TRUE
- return FALSE
-
-/obj/item/proc/GetAccess()
- return list()
-
-/obj/item/proc/GetID()
- return null
-
-/obj/proc/text2access(access_text)
- . = list()
- if(!access_text)
- return
- var/list/split = splittext(access_text,";")
- for(var/x in split)
- var/n = text2num(x)
- if(n)
- . += n
-
-//Call this before using req_access or req_one_access directly
-/obj/proc/gen_access()
- //These generations have been moved out of /obj/New() because they were slowing down the creation of objects that never even used the access system.
- if(!req_access)
- req_access = list()
- for(var/a in text2access(req_access_txt))
- req_access += a
- if(!req_one_access)
- req_one_access = list()
- for(var/b in text2access(req_one_access_txt))
- req_one_access += b
-
-// Check if an item has access to this object
-/obj/proc/check_access(obj/item/I)
- return check_access_list(I ? I.GetAccess() : null)
-
-/obj/proc/check_access_list(list/access_list)
- gen_access()
-
- if(!islist(req_access)) //something's very wrong
- return TRUE
-
- if(!req_access.len && !length(req_one_access))
- return TRUE
-
- if(!length(access_list) || !islist(access_list))
- return FALSE
-
- for(var/req in req_access)
- if(!(req in access_list)) //doesn't have this access
- return FALSE
-
- if(length(req_one_access))
- for(var/req in req_one_access)
- if(req in access_list) //has an access from the single access list
- return TRUE
- return FALSE
- return TRUE
-
-/obj/proc/check_access_ntnet(datum/netdata/data)
- return check_access_list(data.passkey)
-
-/proc/get_centcom_access(job)
- switch(job)
- if("VIP Guest")
- return list(ACCESS_CENT_GENERAL)
- if("Custodian")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE)
- if("Thunderdome Overseer")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_THUNDER)
- if("CentCom Official")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING)
- if("Medical Officer")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_MEDICAL)
- if("Death Commando")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE)
- if("Research Officer")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_MEDICAL, ACCESS_CENT_TELEPORTER, ACCESS_CENT_STORAGE)
- if("Special Ops Officer")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_THUNDER, ACCESS_CENT_SPECOPS, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE)
- if("Admiral")
- return get_all_centcom_access()
- if("CentCom Commander")
- return get_all_centcom_access()
- if("Emergency Response Team Commander")
- return get_ert_access("commander")
- if("Security Response Officer")
- return get_ert_access("sec")
- if("Engineer Response Officer")
- return get_ert_access("eng")
- if("Medical Response Officer")
- return get_ert_access("med")
- if("CentCom Bartender")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_BAR)
-
-/proc/get_all_accesses()
- return list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT,
- ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_MORGUE, ACCESS_RD,
- ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_CHEMISTRY, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_MAINT_TUNNELS,
- ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD,
- ACCESS_TELEPORTER, ACCESS_EVA, ACCESS_HEADS, ACCESS_CAPTAIN, ACCESS_ALL_PERSONAL_LOCKERS,
- ACCESS_TECH_STORAGE, ACCESS_CHAPEL_OFFICE, ACCESS_ATMOSPHERICS, ACCESS_KITCHEN,
- ACCESS_BAR, ACCESS_JANITOR, ACCESS_CREMATORIUM, ACCESS_ROBOTICS, ACCESS_CARGO, ACCESS_CONSTRUCTION,
- ACCESS_HYDROPONICS, ACCESS_LIBRARY, ACCESS_LAWYER, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_QM, ACCESS_SURGERY,
- ACCESS_THEATRE, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_MAILSORTING, ACCESS_WEAPONS,
- ACCESS_VAULT, ACCESS_MINING_STATION, ACCESS_XENOBIOLOGY, ACCESS_CE, ACCESS_HOP, ACCESS_HOS, ACCESS_RC_ANNOUNCE,
- ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM, ACCESS_MINISAT, ACCESS_NETWORK, ACCESS_CLONING)
-
-/proc/get_all_centcom_access()
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_THUNDER, ACCESS_CENT_SPECOPS, ACCESS_CENT_MEDICAL, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE, ACCESS_CENT_TELEPORTER, ACCESS_CENT_CAPTAIN)
-
-/proc/get_ert_access(class)
- switch(class)
- if("commander")
- return get_all_centcom_access()
- if("sec")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_LIVING)
- if("eng")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE)
- if("med")
- return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_MEDICAL, ACCESS_CENT_LIVING)
-
-/proc/get_all_syndicate_access()
- return list(ACCESS_SYNDICATE, ACCESS_SYNDICATE)
-
-/proc/get_region_accesses(code)
- switch(code)
- if(0)
- return get_all_accesses()
- if(1) //station general
- return list(ACCESS_KITCHEN,ACCESS_BAR, ACCESS_HYDROPONICS, ACCESS_JANITOR, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_LIBRARY, ACCESS_THEATRE, ACCESS_LAWYER)
- if(2) //security
- return list(ACCESS_SEC_DOORS, ACCESS_WEAPONS, ACCESS_SECURITY, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_HOS)
- if(3) //medbay
- return list(ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_SURGERY, ACCESS_CMO)
- if(4) //research
- return list(ACCESS_RESEARCH, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_GENETICS, ACCESS_ROBOTICS, ACCESS_XENOBIOLOGY, ACCESS_MINISAT, ACCESS_RD, ACCESS_NETWORK)
- if(5) //engineering and maintenance
- return list(ACCESS_CONSTRUCTION, ACCESS_MAINT_TUNNELS, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_TECH_STORAGE, ACCESS_ATMOSPHERICS, ACCESS_TCOMSAT, ACCESS_MINISAT, ACCESS_CE)
- if(6) //supply
- return list(ACCESS_MAILSORTING, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_CARGO, ACCESS_QM, ACCESS_VAULT)
- if(7) //command
- return list(ACCESS_HEADS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_TELEPORTER, ACCESS_EVA, ACCESS_GATEWAY, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_HOP, ACCESS_CAPTAIN, ACCESS_VAULT)
-
-/proc/get_region_accesses_name(code)
- switch(code)
- if(0)
- return "All"
- if(1) //station general
- return "General"
- if(2) //security
- return "Security"
- if(3) //medbay
- return "Medbay"
- if(4) //research
- return "Research"
- if(5) //engineering and maintenance
- return "Engineering"
- if(6) //supply
- return "Supply"
- if(7) //command
- return "Command"
-
-/proc/get_access_desc(A)
- switch(A)
- if(ACCESS_CARGO)
- return "Cargo Bay"
- if(ACCESS_CARGO_BOT)
- return "Delivery Chutes"
- if(ACCESS_SECURITY)
- return "Security"
- if(ACCESS_BRIG)
- return "Holding Cells"
- if(ACCESS_COURT)
- return "Courtroom"
- if(ACCESS_FORENSICS_LOCKERS)
- return "Forensics"
- if(ACCESS_MEDICAL)
- return "Medical"
- if(ACCESS_GENETICS)
- return "Genetics Lab"
- if(ACCESS_MORGUE)
- return "Morgue"
- if(ACCESS_TOX)
- return "R&D Lab"
- if(ACCESS_TOX_STORAGE)
- return "Toxins Lab"
- if(ACCESS_CHEMISTRY)
- return "Chemistry Lab"
- if(ACCESS_RD)
- return "RD Office"
- if(ACCESS_BAR)
- return "Bar"
- if(ACCESS_JANITOR)
- return "Custodial Closet"
- if(ACCESS_ENGINE)
- return "Engineering"
- if(ACCESS_ENGINE_EQUIP)
- return "Power and Engineering Equipment"
- if(ACCESS_MAINT_TUNNELS)
- return "Maintenance"
- if(ACCESS_EXTERNAL_AIRLOCKS)
- return "External Airlocks"
- if(ACCESS_EMERGENCY_STORAGE)
- return "Emergency Storage"
- if(ACCESS_CHANGE_IDS)
- return "ID Console"
- if(ACCESS_AI_UPLOAD)
- return "AI Chambers"
- if(ACCESS_TELEPORTER)
- return "Teleporter"
- if(ACCESS_EVA)
- return "EVA"
- if(ACCESS_HEADS)
- return "Bridge"
- if(ACCESS_CAPTAIN)
- return "Captain"
- if(ACCESS_ALL_PERSONAL_LOCKERS)
- return "Personal Lockers"
- if(ACCESS_CHAPEL_OFFICE)
- return "Chapel Office"
- if(ACCESS_TECH_STORAGE)
- return "Technical Storage"
- if(ACCESS_ATMOSPHERICS)
- return "Atmospherics"
- if(ACCESS_CREMATORIUM)
- return "Crematorium"
- if(ACCESS_ARMORY)
- return "Armory"
- if(ACCESS_CONSTRUCTION)
- return "Construction"
- if(ACCESS_KITCHEN)
- return "Kitchen"
- if(ACCESS_HYDROPONICS)
- return "Hydroponics"
- if(ACCESS_LIBRARY)
- return "Library"
- if(ACCESS_LAWYER)
- return "Law Office"
- if(ACCESS_ROBOTICS)
- return "Robotics"
- if(ACCESS_VIROLOGY)
- return "Virology"
- if(ACCESS_CMO)
- return "CMO Office"
- if(ACCESS_QM)
- return "Quartermaster"
- if(ACCESS_SURGERY)
- return "Surgery"
- if(ACCESS_THEATRE)
- return "Theatre"
- if(ACCESS_MANUFACTURING)
- return "Manufacturing"
- if(ACCESS_RESEARCH)
- return "Science"
- if(ACCESS_MINING)
- return "Mining"
- if(ACCESS_MINING_OFFICE)
- return "Mining Office"
- if(ACCESS_MAILSORTING)
- return "Cargo Office"
- if(ACCESS_MINT)
- return "Mint"
- if(ACCESS_MINT_VAULT)
- return "Mint Vault"
- if(ACCESS_VAULT)
- return "Main Vault"
- if(ACCESS_MINING_STATION)
- return "Mining EVA"
- if(ACCESS_XENOBIOLOGY)
- return "Xenobiology Lab"
- if(ACCESS_HOP)
- return "HoP Office"
- if(ACCESS_HOS)
- return "HoS Office"
- if(ACCESS_CE)
- return "CE Office"
- if(ACCESS_RC_ANNOUNCE)
- return "RC Announcements"
- if(ACCESS_KEYCARD_AUTH)
- return "Keycode Auth."
- if(ACCESS_TCOMSAT)
- return "Telecommunications"
- if(ACCESS_GATEWAY)
- return "Gateway"
- if(ACCESS_SEC_DOORS)
- return "Brig"
- if(ACCESS_MINERAL_STOREROOM)
- return "Mineral Storage"
- if(ACCESS_MINISAT)
- return "AI Satellite"
- if(ACCESS_WEAPONS)
- return "Weapon Permit"
- if(ACCESS_NETWORK)
- return "Network Access"
- if(ACCESS_CLONING)
- return "Cloning Room"
-
-/proc/get_centcom_access_desc(A)
- switch(A)
- if(ACCESS_CENT_GENERAL)
- return "Code Grey"
- if(ACCESS_CENT_THUNDER)
- return "Code Yellow"
- if(ACCESS_CENT_STORAGE)
- return "Code Orange"
- if(ACCESS_CENT_LIVING)
- return "Code Green"
- if(ACCESS_CENT_MEDICAL)
- return "Code White"
- if(ACCESS_CENT_TELEPORTER)
- return "Code Blue"
- if(ACCESS_CENT_SPECOPS)
- return "Code Black"
- if(ACCESS_CENT_CAPTAIN)
- return "Code Gold"
- if(ACCESS_CENT_BAR)
- return "Code Scotch"
-
-/proc/get_all_jobs()
- return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Cook", "Botanist", "Quartermaster", "Cargo Technician",
- "Shaft Miner", "Clown", "Mime", "Janitor", "Curator", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer",
- "Atmospheric Technician", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist",
- "Research Director", "Scientist", "Roboticist", "Head of Security", "Warden", "Detective", "Security Officer")
-
-/proc/get_all_job_icons() //For all existing HUD icons
- return get_all_jobs() + list("Prisoner")
-
-/proc/get_all_centcom_jobs()
- return list("VIP Guest","Custodian","Thunderdome Overseer","CentCom Official","Medical Officer","Death Commando","Research Officer","Special Ops Officer","Admiral","CentCom Commander","Emergency Response Team Commander","Security Response Officer","Engineer Response Officer", "Medical Response Officer","CentCom Bartender")
-
-/obj/item/proc/GetJobName() //Used in secHUD icon generation
- var/obj/item/card/id/I = GetID()
- if(!I)
- return
- var/jobName = I.assignment
- if(jobName in get_all_job_icons()) //Check if the job has a hud icon
- return jobName
- if(jobName in get_all_centcom_jobs()) //Return with the NT logo if it is a CentCom job
- return "CentCom"
- return "Unknown" //Return unknown if none of the above apply
+
+//returns TRUE if this mob has sufficient access to use this object
+/obj/proc/allowed(mob/M)
+ //check if it doesn't require any access at all
+ if(src.check_access(null))
+ return TRUE
+ if(issilicon(M))
+ if(ispAI(M))
+ return FALSE
+ return TRUE //AI can do whatever it wants
+ if(IsAdminGhost(M))
+ //Access can't stop the abuse
+ return TRUE
+ else if(istype(M) && SEND_SIGNAL(M, COMSIG_MOB_ALLOWED, src))
+ return TRUE
+ else if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ //if they are holding or wearing a card that has access, that works
+ if(check_access(H.get_active_held_item()) || src.check_access(H.wear_id))
+ return TRUE
+ else if(ismonkey(M) || isalienadult(M))
+ var/mob/living/carbon/george = M
+ //they can only hold things :(
+ if(check_access(george.get_active_held_item()))
+ return TRUE
+ else if(isanimal(M))
+ var/mob/living/simple_animal/A = M
+ if(check_access(A.get_active_held_item()) || check_access(A.access_card))
+ return TRUE
+ return FALSE
+
+/obj/item/proc/GetAccess()
+ return list()
+
+/obj/item/proc/GetID()
+ return null
+
+/obj/proc/text2access(access_text)
+ . = list()
+ if(!access_text)
+ return
+ var/list/split = splittext(access_text,";")
+ for(var/x in split)
+ var/n = text2num(x)
+ if(n)
+ . += n
+
+//Call this before using req_access or req_one_access directly
+/obj/proc/gen_access()
+ //These generations have been moved out of /obj/New() because they were slowing down the creation of objects that never even used the access system.
+ if(!req_access)
+ req_access = list()
+ for(var/a in text2access(req_access_txt))
+ req_access += a
+ if(!req_one_access)
+ req_one_access = list()
+ for(var/b in text2access(req_one_access_txt))
+ req_one_access += b
+
+// Check if an item has access to this object
+/obj/proc/check_access(obj/item/I)
+ return check_access_list(I ? I.GetAccess() : null)
+
+/obj/proc/check_access_list(list/access_list)
+ gen_access()
+
+ if(!islist(req_access)) //something's very wrong
+ return TRUE
+
+ if(!req_access.len && !length(req_one_access))
+ return TRUE
+
+ if(!length(access_list) || !islist(access_list))
+ return FALSE
+
+ for(var/req in req_access)
+ if(!(req in access_list)) //doesn't have this access
+ return FALSE
+
+ if(length(req_one_access))
+ for(var/req in req_one_access)
+ if(req in access_list) //has an access from the single access list
+ return TRUE
+ return FALSE
+ return TRUE
+
+/obj/proc/check_access_ntnet(datum/netdata/data)
+ return check_access_list(data.passkey)
+
+/proc/get_centcom_access(job)
+ switch(job)
+ if("VIP Guest")
+ return list(ACCESS_CENT_GENERAL)
+ if("Custodian")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE)
+ if("Thunderdome Overseer")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_THUNDER)
+ if("CentCom Official")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING)
+ if("Medical Officer")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_MEDICAL)
+ if("Death Commando")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE)
+ if("Research Officer")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_MEDICAL, ACCESS_CENT_TELEPORTER, ACCESS_CENT_STORAGE)
+ if("Special Ops Officer")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_THUNDER, ACCESS_CENT_SPECOPS, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE)
+ if("Admiral")
+ return get_all_centcom_access()
+ if("CentCom Commander")
+ return get_all_centcom_access()
+ if("Emergency Response Team Commander")
+ return get_ert_access("commander")
+ if("Security Response Officer")
+ return get_ert_access("sec")
+ if("Engineer Response Officer")
+ return get_ert_access("eng")
+ if("Medical Response Officer")
+ return get_ert_access("med")
+ if("CentCom Bartender")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_LIVING, ACCESS_CENT_BAR)
+
+/proc/get_all_accesses()
+ return list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
+ ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_MORGUE, ACCESS_RD,
+ ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_CHEMISTRY, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_MAINT_TUNNELS,
+ ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD,
+ ACCESS_TELEPORTER, ACCESS_EVA, ACCESS_HEADS, ACCESS_CAPTAIN, ACCESS_ALL_PERSONAL_LOCKERS,
+ ACCESS_TECH_STORAGE, ACCESS_CHAPEL_OFFICE, ACCESS_ATMOSPHERICS, ACCESS_KITCHEN,
+ ACCESS_BAR, ACCESS_JANITOR, ACCESS_CREMATORIUM, ACCESS_ROBOTICS, ACCESS_CARGO, ACCESS_CONSTRUCTION,
+ ACCESS_HYDROPONICS, ACCESS_LIBRARY, ACCESS_LAWYER, ACCESS_VIROLOGY, ACCESS_CMO, ACCESS_QM, ACCESS_SURGERY,
+ ACCESS_THEATRE, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_MAILSORTING, ACCESS_WEAPONS,
+ ACCESS_VAULT, ACCESS_MINING_STATION, ACCESS_XENOBIOLOGY, ACCESS_CE, ACCESS_HOP, ACCESS_HOS, ACCESS_RC_ANNOUNCE,
+ ACCESS_KEYCARD_AUTH, ACCESS_TCOMSAT, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM, ACCESS_MINISAT, ACCESS_NETWORK, ACCESS_CLONING)
+
+/proc/get_all_centcom_access()
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_THUNDER, ACCESS_CENT_SPECOPS, ACCESS_CENT_MEDICAL, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE, ACCESS_CENT_TELEPORTER, ACCESS_CENT_CAPTAIN)
+
+/proc/get_ert_access(class)
+ switch(class)
+ if("commander")
+ return get_all_centcom_access()
+ if("sec")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_LIVING)
+ if("eng")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_LIVING, ACCESS_CENT_STORAGE)
+ if("med")
+ return list(ACCESS_CENT_GENERAL, ACCESS_CENT_SPECOPS, ACCESS_CENT_MEDICAL, ACCESS_CENT_LIVING)
+
+/proc/get_all_syndicate_access()
+ return list(ACCESS_SYNDICATE, ACCESS_SYNDICATE)
+
+/proc/get_region_accesses(code)
+ switch(code)
+ if(0)
+ return get_all_accesses()
+ if(1) //station general
+ return list(ACCESS_KITCHEN,ACCESS_BAR, ACCESS_HYDROPONICS, ACCESS_JANITOR, ACCESS_CHAPEL_OFFICE, ACCESS_CREMATORIUM, ACCESS_LIBRARY, ACCESS_THEATRE, ACCESS_LAWYER)
+ if(2) //security
+ return list(ACCESS_SEC_DOORS, ACCESS_WEAPONS, ACCESS_SECURITY, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_FORENSICS_LOCKERS, ACCESS_COURT, ACCESS_HOS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,)
+ if(3) //medbay
+ return list(ACCESS_MEDICAL, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MORGUE, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_SURGERY, ACCESS_CMO)
+ if(4) //research
+ return list(ACCESS_RESEARCH, ACCESS_TOX, ACCESS_TOX_STORAGE, ACCESS_GENETICS, ACCESS_ROBOTICS, ACCESS_XENOBIOLOGY, ACCESS_MINISAT, ACCESS_RD, ACCESS_NETWORK)
+ if(5) //engineering and maintenance
+ return list(ACCESS_CONSTRUCTION, ACCESS_MAINT_TUNNELS, ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_TECH_STORAGE, ACCESS_ATMOSPHERICS, ACCESS_TCOMSAT, ACCESS_MINISAT, ACCESS_CE)
+ if(6) //supply
+ return list(ACCESS_MAILSORTING, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_CARGO, ACCESS_QM, ACCESS_VAULT)
+ if(7) //command
+ return list(ACCESS_HEADS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_TELEPORTER, ACCESS_EVA, ACCESS_GATEWAY, ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_HOP, ACCESS_CAPTAIN, ACCESS_VAULT)
+
+/proc/get_region_accesses_name(code)
+ switch(code)
+ if(0)
+ return "All"
+ if(1) //station general
+ return "General"
+ if(2) //security
+ return "Security"
+ if(3) //medbay
+ return "Medbay"
+ if(4) //research
+ return "Research"
+ if(5) //engineering and maintenance
+ return "Engineering"
+ if(6) //supply
+ return "Supply"
+ if(7) //command
+ return "Command"
+
+/proc/get_access_desc(A)
+ switch(A)
+ if(ACCESS_CARGO)
+ return "Cargo Bay"
+ if(ACCESS_CARGO_BOT)
+ return "Delivery Chutes"
+ if(ACCESS_SECURITY)
+ return "Security Equipment"
+ if(ACCESS_BRIG)
+ return "Holding Cells and Prisoner Management"
+ if(ACCESS_COURT)
+ return "Courtroom"
+ if(ACCESS_FORENSICS_LOCKERS)
+ return "Forensics Lockers"
+ if(ACCESS_MEDICAL)
+ return "Medical"
+ if(ACCESS_GENETICS)
+ return "Genetics Lab"
+ if(ACCESS_MORGUE)
+ return "Morgue"
+ if(ACCESS_TOX)
+ return "R&D Lab"
+ if(ACCESS_TOX_STORAGE)
+ return "Toxins Lab"
+ if(ACCESS_CHEMISTRY)
+ return "Chemistry Lab"
+ if(ACCESS_RD)
+ return "RD Office"
+ if(ACCESS_BAR)
+ return "Bar"
+ if(ACCESS_JANITOR)
+ return "Custodial Closet"
+ if(ACCESS_ENGINE)
+ return "Engineering"
+ if(ACCESS_ENGINE_EQUIP)
+ return "Power and Engineering Equipment"
+ if(ACCESS_MAINT_TUNNELS)
+ return "Maintenance"
+ if(ACCESS_EXTERNAL_AIRLOCKS)
+ return "External Airlocks"
+ if(ACCESS_EMERGENCY_STORAGE)
+ return "Emergency Storage"
+ if(ACCESS_CHANGE_IDS)
+ return "ID Console"
+ if(ACCESS_AI_UPLOAD)
+ return "AI Chambers"
+ if(ACCESS_TELEPORTER)
+ return "Teleporter"
+ if(ACCESS_EVA)
+ return "EVA"
+ if(ACCESS_HEADS)
+ return "Bridge and Command Equipment"
+ if(ACCESS_CAPTAIN)
+ return "Captain"
+ if(ACCESS_ALL_PERSONAL_LOCKERS)
+ return "Personal Lockers"
+ if(ACCESS_CHAPEL_OFFICE)
+ return "Chapel Office"
+ if(ACCESS_TECH_STORAGE)
+ return "Technical Storage"
+ if(ACCESS_ATMOSPHERICS)
+ return "Atmospherics"
+ if(ACCESS_CREMATORIUM)
+ return "Crematorium"
+ if(ACCESS_ARMORY)
+ return "Armory"
+ if(ACCESS_CONSTRUCTION)
+ return "Construction"
+ if(ACCESS_KITCHEN)
+ return "Kitchen"
+ if(ACCESS_HYDROPONICS)
+ return "Hydroponics"
+ if(ACCESS_LIBRARY)
+ return "Library"
+ if(ACCESS_LAWYER)
+ return "Law Office"
+ if(ACCESS_ROBOTICS)
+ return "Robotics"
+ if(ACCESS_VIROLOGY)
+ return "Virology"
+ if(ACCESS_CMO)
+ return "CMO Office"
+ if(ACCESS_QM)
+ return "Quartermaster"
+ if(ACCESS_SURGERY)
+ return "Surgery"
+ if(ACCESS_THEATRE)
+ return "Theatre"
+ if(ACCESS_MANUFACTURING)
+ return "Manufacturing"
+ if(ACCESS_RESEARCH)
+ return "Science"
+ if(ACCESS_MINING)
+ return "Mining"
+ if(ACCESS_MINING_OFFICE)
+ return "Mining Office"
+ if(ACCESS_MAILSORTING)
+ return "Cargo Office"
+ if(ACCESS_MINT)
+ return "Mint"
+ if(ACCESS_MINT_VAULT)
+ return "Mint Vault"
+ if(ACCESS_VAULT)
+ return "Main Vault"
+ if(ACCESS_MINING_STATION)
+ return "Mining EVA"
+ if(ACCESS_XENOBIOLOGY)
+ return "Xenobiology Lab"
+ if(ACCESS_HOP)
+ return "HoP Office"
+ if(ACCESS_HOS)
+ return "HoS Office"
+ if(ACCESS_CE)
+ return "CE Office"
+ if(ACCESS_RC_ANNOUNCE)
+ return "RC Announcements"
+ if(ACCESS_KEYCARD_AUTH)
+ return "Keycode Auth."
+ if(ACCESS_TCOMSAT)
+ return "Telecommunications"
+ if(ACCESS_GATEWAY)
+ return "Gateway"
+ if(ACCESS_SEC_DOORS)
+ return "Security SubDepartment Doors"
+ if(ACCESS_ENTER_GENPOP)
+ return "Prison Turnstile Entrance"
+ if(ACCESS_LEAVE_GENPOP)
+ return "Prison Turnstile Exit"
+ if(ACCESS_MINERAL_STOREROOM)
+ return "Mineral Storage"
+ if(ACCESS_MINISAT)
+ return "AI Satellite"
+ if(ACCESS_WEAPONS)
+ return "Weapon Permit"
+ if(ACCESS_NETWORK)
+ return "Network Access"
+ if(ACCESS_CLONING)
+ return "Cloning Room"
+
+/proc/get_centcom_access_desc(A)
+ switch(A)
+ if(ACCESS_CENT_GENERAL)
+ return "Code Grey"
+ if(ACCESS_CENT_THUNDER)
+ return "Code Yellow"
+ if(ACCESS_CENT_STORAGE)
+ return "Code Orange"
+ if(ACCESS_CENT_LIVING)
+ return "Code Green"
+ if(ACCESS_CENT_MEDICAL)
+ return "Code White"
+ if(ACCESS_CENT_TELEPORTER)
+ return "Code Blue"
+ if(ACCESS_CENT_SPECOPS)
+ return "Code Black"
+ if(ACCESS_CENT_CAPTAIN)
+ return "Code Gold"
+ if(ACCESS_CENT_BAR)
+ return "Code Scotch"
+
+/proc/get_all_jobs()
+ return list("Assistant", "Captain", "Head of Personnel", "Bartender", "Cook", "Botanist", "Quartermaster", "Cargo Technician",
+ "Shaft Miner", "Clown", "Mime", "Janitor", "Curator", "Lawyer", "Chaplain", "Chief Engineer", "Station Engineer",
+ "Atmospheric Technician", "Chief Medical Officer", "Medical Doctor", "Chemist", "Geneticist", "Virologist",
+ "Research Director", "Scientist", "Roboticist", "Head of Security", "Warden", "Detective", "Security Officer")
+
+/proc/get_all_job_icons() //For all existing HUD icons
+ return get_all_jobs() + list("Prisoner")
+
+/proc/get_all_centcom_jobs()
+ return list("VIP Guest","Custodian","Thunderdome Overseer","CentCom Official","Medical Officer","Death Commando","Research Officer","Special Ops Officer","Admiral","CentCom Commander","Emergency Response Team Commander","Security Response Officer","Engineer Response Officer", "Medical Response Officer","CentCom Bartender")
+
+/obj/item/proc/GetJobName() //Used in secHUD icon generation
+ var/obj/item/card/id/I = GetID()
+ if(!I)
+ return
+ var/jobName = I.assignment
+ if(jobName in get_all_job_icons()) //Check if the job has a hud icon
+ return jobName
+ if(jobName in get_all_centcom_jobs()) //Return with the NT logo if it is a CentCom job
+ return "CentCom"
+ return "Unknown" //Return unknown if none of the above apply
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index 2eeffa8b7a..a52b8589c3 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -61,6 +61,9 @@
var/display_order = JOB_DISPLAY_ORDER_DEFAULT
+ //If a job complies with dresscodes, loadout items will not be equipped instead of the job's outfit, instead placing the items into the player's backpack.
+ var/dresscodecompliant = TRUE
+
//Only override this proc
//H is usually a human unless an /equip override transformed it
/datum/job/proc/after_spawn(mob/living/H, mob/M, latejoin = FALSE)
diff --git a/code/modules/jobs/job_types/assistant.dm b/code/modules/jobs/job_types/assistant.dm
index c04560f849..da8c2aa3b9 100644
--- a/code/modules/jobs/job_types/assistant.dm
+++ b/code/modules/jobs/job_types/assistant.dm
@@ -15,6 +15,7 @@ Assistant
outfit = /datum/outfit/job/assistant
antag_rep = 7
display_order = JOB_DISPLAY_ORDER_ASSISTANT
+ dresscodecompliant = FALSE
/datum/job/assistant/get_access()
if(CONFIG_GET(flag/assistants_have_maint_access) || !CONFIG_GET(flag/jobs_have_minimal_access)) //Config has assistant maint access set
diff --git a/code/modules/jobs/job_types/atmospheric_technician.dm b/code/modules/jobs/job_types/atmospheric_technician.dm
index 93775beca9..300fcc7109 100644
--- a/code/modules/jobs/job_types/atmospheric_technician.dm
+++ b/code/modules/jobs/job_types/atmospheric_technician.dm
@@ -15,7 +15,8 @@
access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS,
ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM)
+ minimal_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_ENGINE,
+ ACCESS_ENGINE_EQUIP, ACCESS_EMERGENCY_STORAGE, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM)
display_order = JOB_DISPLAY_ORDER_ATMOSPHERIC_TECHNICIAN
/datum/outfit/job/atmos
diff --git a/code/modules/jobs/job_types/captain.dm b/code/modules/jobs/job_types/captain.dm
index 7e832d6975..c6342e2154 100644
--- a/code/modules/jobs/job_types/captain.dm
+++ b/code/modules/jobs/job_types/captain.dm
@@ -10,9 +10,9 @@
supervisors = "Nanotrasen officials and Space law"
selection_color = "#aac1ee"
req_admin_notify = 1
- minimal_player_age = 14
+ minimal_player_age = 20
exp_requirements = 180
- exp_type = EXP_TYPE_CREW
+ exp_type = EXP_TYPE_COMMAND
exp_type_department = EXP_TYPE_COMMAND
outfit = /datum/outfit/job/captain
@@ -63,4 +63,4 @@
mask = /obj/item/clothing/mask/gas/sechailer
suit = /obj/item/clothing/suit/space/hardsuit/captain
- suit_store = /obj/item/tank/internals/oxygen
+ suit_store = /obj/item/tank/internals/oxygen
\ No newline at end of file
diff --git a/code/modules/jobs/job_types/cargo_technician.dm b/code/modules/jobs/job_types/cargo_technician.dm
index 3ceb29bae2..d6fbe5551f 100644
--- a/code/modules/jobs/job_types/cargo_technician.dm
+++ b/code/modules/jobs/job_types/cargo_technician.dm
@@ -11,7 +11,8 @@
outfit = /datum/outfit/job/cargo_tech
- access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
+ access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINING,
+ ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_CARGO, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
display_order = JOB_DISPLAY_ORDER_CARGO_TECHNICIAN
diff --git a/code/modules/jobs/job_types/chaplain.dm b/code/modules/jobs/job_types/chaplain.dm
index f6648fdf86..97b1edc8c2 100644
--- a/code/modules/jobs/job_types/chaplain.dm
+++ b/code/modules/jobs/job_types/chaplain.dm
@@ -72,7 +72,7 @@
B.name = "Fluorescent Incandescence"
if("lol", "wtf", "gay", "penis", "ass", "poo", "badmin", "shitmin", "deadmin", "cock", "cocks", "meme", "memes")
B.name = pick("Woodys Got Wood: The Aftermath", "War of the Cocks", "Sweet Bro and Hella Jef: Expanded Edition","F.A.T.A.L. Rulebook")
- H.adjustBrainLoss(100) // starts off retarded as fuck
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 100) // starts off retarded as fuck
if("monkeyism","apism","gorillism","primatism")
B.name = pick("Going Bananas", "Bananas Out For Harambe")
if("mormonism")
@@ -118,4 +118,4 @@
uniform = /obj/item/clothing/under/rank/chaplain
backpack_contents = list(/obj/item/camera/spooky = 1)
backpack = /obj/item/storage/backpack/cultpack
- satchel = /obj/item/storage/backpack/cultpack
\ No newline at end of file
+ satchel = /obj/item/storage/backpack/cultpack
diff --git a/code/modules/jobs/job_types/chemist.dm b/code/modules/jobs/job_types/chemist.dm
index a915d261ed..4614feba8d 100644
--- a/code/modules/jobs/job_types/chemist.dm
+++ b/code/modules/jobs/job_types/chemist.dm
@@ -32,5 +32,7 @@
satchel = /obj/item/storage/backpack/satchel/chem
duffelbag = /obj/item/storage/backpack/duffelbag/med
+ backpack_contents = list(/obj/item/storage/hypospraykit/regular)
+
chameleon_extras = /obj/item/gun/syringe
diff --git a/code/modules/jobs/job_types/chief_engineer.dm b/code/modules/jobs/job_types/chief_engineer.dm
index da3f281267..f6505a4e2a 100644
--- a/code/modules/jobs/job_types/chief_engineer.dm
+++ b/code/modules/jobs/job_types/chief_engineer.dm
@@ -11,7 +11,7 @@
supervisors = "the captain"
selection_color = "#ee7400"
req_admin_notify = 1
- minimal_player_age = 7
+ minimal_player_age = 10
exp_requirements = 180
exp_type = EXP_TYPE_CREW
exp_type_department = EXP_TYPE_ENGINEERING
diff --git a/code/modules/jobs/job_types/chief_medical_officer.dm b/code/modules/jobs/job_types/chief_medical_officer.dm
index 4c7249f048..69eead70f7 100644
--- a/code/modules/jobs/job_types/chief_medical_officer.dm
+++ b/code/modules/jobs/job_types/chief_medical_officer.dm
@@ -11,7 +11,7 @@
supervisors = "the captain"
selection_color = "#509ed1"
req_admin_notify = 1
- minimal_player_age = 7
+ minimal_player_age = 10
exp_requirements = 180
exp_type = EXP_TYPE_CREW
exp_type_department = EXP_TYPE_MEDICAL
diff --git a/code/modules/jobs/job_types/head_of_personnel.dm b/code/modules/jobs/job_types/head_of_personnel.dm
index e320ce20b4..2b757872d9 100644
--- a/code/modules/jobs/job_types/head_of_personnel.dm
+++ b/code/modules/jobs/job_types/head_of_personnel.dm
@@ -11,7 +11,7 @@
supervisors = "the captain"
selection_color = "#3a8529"
req_admin_notify = 1
- minimal_player_age = 10
+ minimal_player_age = 20
exp_requirements = 180
exp_type = EXP_TYPE_CREW
exp_type_department = EXP_TYPE_SERVICE
@@ -21,13 +21,13 @@
access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
- ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_CARGO, ACCESS_MAILSORTING, ACCESS_QM, ACCESS_HYDROPONICS, ACCESS_LAWYER,
+ ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER,
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
- ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_CARGO, ACCESS_MAILSORTING, ACCESS_QM, ACCESS_HYDROPONICS, ACCESS_LAWYER,
+ ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER,
ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM)
diff --git a/code/modules/jobs/job_types/head_of_security.dm b/code/modules/jobs/job_types/head_of_security.dm
index f6b5dbd3ef..c190d88bc7 100644
--- a/code/modules/jobs/job_types/head_of_security.dm
+++ b/code/modules/jobs/job_types/head_of_security.dm
@@ -11,7 +11,7 @@
supervisors = "the captain"
selection_color = "#b90000"
req_admin_notify = 1
- minimal_player_age = 14
+ minimal_player_age = 10
exp_requirements = 300
exp_type = EXP_TYPE_CREW
exp_type_department = EXP_TYPE_SECURITY
@@ -19,11 +19,11 @@
outfit = /datum/outfit/job/hos
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
- access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS,
+ access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS,
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS,
+ minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP,
ACCESS_FORENSICS_LOCKERS, ACCESS_MORGUE, ACCESS_MAINT_TUNNELS, ACCESS_ALL_PERSONAL_LOCKERS,
ACCESS_RESEARCH, ACCESS_ENGINE, ACCESS_MINING, ACCESS_MEDICAL, ACCESS_CONSTRUCTION, ACCESS_MAILSORTING,
ACCESS_HEADS, ACCESS_HOS, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MAINT_TUNNELS, ACCESS_MINERAL_STOREROOM)
diff --git a/code/modules/jobs/job_types/medical_doctor.dm b/code/modules/jobs/job_types/medical_doctor.dm
index 19fa1c7158..2a8814f29c 100644
--- a/code/modules/jobs/job_types/medical_doctor.dm
+++ b/code/modules/jobs/job_types/medical_doctor.dm
@@ -32,4 +32,6 @@
satchel = /obj/item/storage/backpack/satchel/med
duffelbag = /obj/item/storage/backpack/duffelbag/med
+ backpack_contents = list(/obj/item/storage/hypospraykit/regular)
+
chameleon_extras = /obj/item/gun/syringe
diff --git a/code/modules/jobs/job_types/quartermaster.dm b/code/modules/jobs/job_types/quartermaster.dm
index 49a93026ba..ad57d05cdc 100644
--- a/code/modules/jobs/job_types/quartermaster.dm
+++ b/code/modules/jobs/job_types/quartermaster.dm
@@ -11,17 +11,19 @@
supervisors = "the captain"
selection_color = "#a06121"
req_admin_notify = 1
- minimal_player_age = 7
+ minimal_player_age = 10
exp_requirements = 180
exp_type = EXP_TYPE_CREW
exp_type_department = EXP_TYPE_SUPPLY
outfit = /datum/outfit/job/quartermaster
- access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION,
- ACCESS_MINERAL_STOREROOM, ACCESS_VAULT)
- minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_QM, ACCESS_MINING,
- ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_VAULT)
+ access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING,
+ ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE,
+ ACCESS_SEC_DOORS, ACCESS_HEADS)
+ minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING,
+ ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE,
+ ACCESS_SEC_DOORS, ACCESS_HEADS)
display_order = JOB_DISPLAY_ORDER_QUARTERMASTER
blacklisted_quirks = list(/datum/quirk/mute, /datum/quirk/brainproblems, /datum/quirk/insanity)
@@ -31,11 +33,13 @@
jobtype = /datum/job/qm
belt = /obj/item/pda/quartermaster
- ears = /obj/item/radio/headset/headset_cargo
+ ears = /obj/item/radio/headset/heads/qm
uniform = /obj/item/clothing/under/rank/cargo
shoes = /obj/item/clothing/shoes/sneakers/brown
glasses = /obj/item/clothing/glasses/sunglasses
l_hand = /obj/item/clipboard
+ id = /obj/item/card/id/silver
+ backpack_contents = list(/obj/item/melee/classic_baton/telescopic = 1, /obj/item/modular_computer/tablet/preset/advanced = 1)
chameleon_extras = /obj/item/stamp/qm
diff --git a/code/modules/jobs/job_types/research_director.dm b/code/modules/jobs/job_types/research_director.dm
index 5368ceee64..a90c5cea6c 100644
--- a/code/modules/jobs/job_types/research_director.dm
+++ b/code/modules/jobs/job_types/research_director.dm
@@ -11,7 +11,7 @@
supervisors = "the captain"
selection_color = "#7544cc"
req_admin_notify = 1
- minimal_player_age = 7
+ minimal_player_age = 10
exp_type_department = EXP_TYPE_SCIENCE
exp_requirements = 180
exp_type = EXP_TYPE_CREW
diff --git a/code/modules/jobs/job_types/security_officer.dm b/code/modules/jobs/job_types/security_officer.dm
index 4f12d6a19c..ae50f71c0c 100644
--- a/code/modules/jobs/job_types/security_officer.dm
+++ b/code/modules/jobs/job_types/security_officer.dm
@@ -15,8 +15,8 @@
outfit = /datum/outfit/job/security
- access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) // See /datum/job/officer/get_access()
+ access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM)
+ minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_MINERAL_STOREROOM) // See /datum/job/officer/get_access()
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
diff --git a/code/modules/jobs/job_types/shaft_miner.dm b/code/modules/jobs/job_types/shaft_miner.dm
index ef16d8e53f..771fc02862 100644
--- a/code/modules/jobs/job_types/shaft_miner.dm
+++ b/code/modules/jobs/job_types/shaft_miner.dm
@@ -13,7 +13,8 @@
outfit = /datum/outfit/job/miner
- access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
+ access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINING,
+ ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MAILSORTING, ACCESS_MINERAL_STOREROOM)
display_order = JOB_DISPLAY_ORDER_SHAFT_MINER
@@ -47,7 +48,7 @@
name = "Shaft Miner (Asteroid)"
uniform = /obj/item/clothing/under/rank/miner
shoes = /obj/item/clothing/shoes/workboots
-
+
/datum/outfit/job/miner/equipped
name = "Shaft Miner (Lavaland + Equipment)"
suit = /obj/item/clothing/suit/hooded/explorer/standard
diff --git a/code/modules/jobs/job_types/warden.dm b/code/modules/jobs/job_types/warden.dm
index a5c16ab5cf..9c529f45f3 100644
--- a/code/modules/jobs/job_types/warden.dm
+++ b/code/modules/jobs/job_types/warden.dm
@@ -15,8 +15,8 @@
outfit = /datum/outfit/job/warden
- access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM) // See /datum/job/warden/get_access()
+ access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_MAINT_TUNNELS, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_FORENSICS_LOCKERS, ACCESS_MINERAL_STOREROOM)
+ minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_BRIG, ACCESS_ARMORY, ACCESS_COURT, ACCESS_WEAPONS, ACCESS_ENTER_GENPOP, ACCESS_LEAVE_GENPOP, ACCESS_MINERAL_STOREROOM) // See /datum/job/warden/get_access()
mind_traits = list(TRAIT_LAW_ENFORCEMENT_METABOLISM)
@@ -42,7 +42,7 @@
glasses = /obj/item/clothing/glasses/hud/security/sunglasses
r_pocket = /obj/item/assembly/flash/handheld
l_pocket = /obj/item/restraints/handcuffs
- suit_store = /obj/item/gun/energy/e_gun/advtaser
+ suit_store = /obj/item/gun/energy/pumpaction/defender
backpack_contents = list(/obj/item/melee/baton/loaded=1)
backpack = /obj/item/storage/backpack/security
diff --git a/code/modules/library/lib_codex_gigas.dm b/code/modules/library/lib_codex_gigas.dm
index d3d95db974..57bf37d528 100644
--- a/code/modules/library/lib_codex_gigas.dm
+++ b/code/modules/library/lib_codex_gigas.dm
@@ -50,8 +50,8 @@
if(U.job in list("Curator")) // the curator is both faster, and more accurate than normal crew members at research
speed = 100
correctness = 100
- correctness -= U.getBrainLoss() *0.5 //Brain damage makes researching hard.
- speed += U.getBrainLoss() * 3
+ correctness -= U.getOrganLoss(ORGAN_SLOT_BRAIN) *0.5 //Brain damage makes researching hard.
+ speed += U.getOrganLoss(ORGAN_SLOT_BRAIN) * 3
if(do_after(user, speed, 0, user))
var/usedName = devilName
if(!prob(correctness))
diff --git a/code/modules/library/lib_items.dm b/code/modules/library/lib_items.dm
index ee563f3100..7dc4fd17b9 100644
--- a/code/modules/library/lib_items.dm
+++ b/code/modules/library/lib_items.dm
@@ -78,7 +78,7 @@
state = 0
if(2)
- GET_COMPONENT_FROM(STR, /datum/component/storage, I)
+ var/datum/component/storage/STR = I.GetComponent(/datum/component/storage)
if(is_type_in_list(I, allowed_books))
if(!user.transferItemToLoc(I, src))
return
diff --git a/code/modules/lighting/lighting_object.dm b/code/modules/lighting/lighting_object.dm
index c0c5a411e7..9ceb341f91 100644
--- a/code/modules/lighting/lighting_object.dm
+++ b/code/modules/lighting/lighting_object.dm
@@ -5,7 +5,7 @@
icon = LIGHTING_ICON
icon_state = "transparent"
- color = LIGHTING_BASE_MATRIX
+ color = null //we manually set color in init instead
plane = LIGHTING_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = LIGHTING_LAYER
@@ -17,6 +17,9 @@
/atom/movable/lighting_object/Initialize(mapload)
. = ..()
verbs.Cut()
+ //We avoid setting this in the base as if we do then the parent atom handling will add_atom_color it and that
+ //is totally unsuitable for this object, as we are always changing its colour manually
+ color = LIGHTING_BASE_MATRIX
myturf = loc
if (myturf.lighting_object)
diff --git a/code/modules/mapping/mapping_helpers.dm b/code/modules/mapping/mapping_helpers.dm
index 7a875ccf9f..e2459d780a 100644
--- a/code/modules/mapping/mapping_helpers.dm
+++ b/code/modules/mapping/mapping_helpers.dm
@@ -213,4 +213,4 @@ INITIALIZE_IMMEDIATE(/obj/effect/mapping_helpers/no_lava)
if(!ispath(disease_type,/datum/disease))
CRASH("Wrong disease type passed in.")
var/datum/disease/D = new disease_type()
- return list(component_type,D)
\ No newline at end of file
+ return list(component_type,D)
diff --git a/code/modules/mining/equipment/explorer_gear.dm b/code/modules/mining/equipment/explorer_gear.dm
index 23ec02976d..559ffc0673 100644
--- a/code/modules/mining/equipment/explorer_gear.dm
+++ b/code/modules/mining/equipment/explorer_gear.dm
@@ -11,6 +11,7 @@
heat_protection = CHEST|GROIN|LEGS|ARMS
hoodtype = /obj/item/clothing/head/hooded/explorer
armor = list("melee" = 30, "bullet" = 20, "laser" = 20, "energy" = 20, "bomb" = 50, "bio" = 100, "rad" = 50, "fire" = 50, "acid" = 50)
+ flags_inv = HIDEJUMPSUIT|HIDETAUR
allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator, /obj/item/pickaxe)
resistance_flags = FIRE_PROOF
tauric = TRUE //Citadel Add for tauric hardsuits
@@ -129,7 +130,7 @@
/obj/item/clothing/suit/hooded/explorer/seva
name = "SEVA Suit"
- desc = "A fire-proof suit for exploring hot environments."
+ desc = "A fire-proof suit for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer."
icon_state = "seva"
item_state = "seva"
w_class = WEIGHT_CLASS_BULKY
@@ -141,7 +142,7 @@
/obj/item/clothing/head/hooded/explorer/seva
name = "SEVA Hood"
- desc = "A fire-proof hood for exploring hot environments."
+ desc = "A fire-proof hood for exploring hot environments. Its design and material make it easier for a Goliath to keep their grip on the wearer."
icon_state = "seva"
item_state = "seva"
max_heat_protection_temperature = FIRE_IMMUNITY_MAX_TEMP_PROTECT
@@ -159,7 +160,7 @@
/obj/item/clothing/suit/hooded/explorer/exo
name = "Exo-suit"
- desc = "A robust suit for exploring dangerous environments."
+ desc = "A robust suit for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer."
icon_state = "exo"
item_state = "exo"
w_class = WEIGHT_CLASS_BULKY
@@ -170,7 +171,7 @@
/obj/item/clothing/head/hooded/explorer/exo
name = "Exo-hood"
- desc = "A robust helmet for exploring dangerous environments."
+ desc = "A robust helmet for fighting dangerous animals. Its design and material make it harder for a Goliath to keep their grip on the wearer."
icon_state = "exo"
item_state = "exo"
armor = list("melee" = 65, "bullet" = 5, "laser" = 5, "energy" = 5, "bomb" = 60, "bio" = 25, "rad" = 10, "fire" = 0, "acid" = 0)
diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm
index b4afaac17f..ab8aa3e2fd 100644
--- a/code/modules/mining/equipment/kinetic_crusher.dm
+++ b/code/modules/mining/equipment/kinetic_crusher.dm
@@ -1,50 +1,51 @@
/*********************Mining Hammer****************/
-/obj/item/twohanded/required/kinetic_crusher
+/obj/item/twohanded/kinetic_crusher
icon = 'icons/obj/mining.dmi'
- icon_state = "mining_hammer1"
- item_state = "mining_hammer1"
+ icon_state = "crusher"
+ item_state = "crusher0"
lefthand_file = 'icons/mob/inhands/weapons/hammers_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/hammers_righthand.dmi'
name = "proto-kinetic crusher"
desc = "An early design of the proto-kinetic accelerator, it is little more than an combination of various mining tools cobbled together, forming a high-tech club. \
While it is an effective mining tool, it did little to aid any but the most skilled and/or suicidal miners against local fauna."
- force = 20 //As much as a bone spear, but this is significantly more annoying to carry around due to requiring the use of both hands at all times
+ force = 0 //You can't hit stuff unless wielded
w_class = WEIGHT_CLASS_BULKY
slot_flags = ITEM_SLOT_BACK
- force_unwielded = 20 //It's never not wielded so these are the same
+ force_unwielded = 0
force_wielded = 20
throwforce = 5
throw_speed = 4
- light_range = 7
- light_power = 2
armour_penetration = 10
materials = list(MAT_METAL=1150, MAT_GLASS=2075)
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("smashed", "crushed", "cleaved", "chopped", "pulped")
sharpness = IS_SHARP
+ actions_types = list(/datum/action/item_action/toggle_light)
var/list/trophies = list()
var/charged = TRUE
var/charge_time = 15
var/detonation_damage = 50
var/backstab_bonus = 30
+ var/light_on = FALSE
+ var/brightness_on = 7
-/obj/item/twohanded/required/kinetic_crusher/Initialize()
+/obj/item/twohanded/kinetic_crusher/Initialize()
. = ..()
AddComponent(/datum/component/butchering, 60, 110) //technically it's huge and bulky, but this provides an incentive to use it
-/obj/item/twohanded/required/kinetic_crusher/Destroy()
+/obj/item/twohanded/kinetic_crusher/Destroy()
QDEL_LIST(trophies)
return ..()
-/obj/item/twohanded/required/kinetic_crusher/examine(mob/living/user)
+/obj/item/twohanded/kinetic_crusher/examine(mob/living/user)
..()
- to_chat(user, "Mark a large creature with the destabilizing force, then hit them in melee to do [force + detonation_damage] damage. ")
- to_chat(user, "Does [force + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force + detonation_damage] . ")
+ to_chat(user, "Mark a large creature with the destabilizing force, then hit them in melee to do [force_wielded + detonation_damage] damage. ")
+ to_chat(user, "Does [force_wielded + detonation_damage + backstab_bonus] damage if the target is backstabbed, instead of [force_wielded + detonation_damage] . ")
for(var/t in trophies)
var/obj/item/crusher_trophy/T = t
to_chat(user, "It has \a [T] attached, which causes [T.effect_desc()]. ")
-/obj/item/twohanded/required/kinetic_crusher/attackby(obj/item/I, mob/living/user)
+/obj/item/twohanded/kinetic_crusher/attackby(obj/item/I, mob/living/user)
if(istype(I, /obj/item/crowbar))
if(LAZYLEN(trophies))
to_chat(user, "You remove [src]'s trophies. ")
@@ -60,7 +61,11 @@
else
return ..()
-/obj/item/twohanded/required/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
+/obj/item/twohanded/kinetic_crusher/attack(mob/living/target, mob/living/carbon/user)
+ if(!wielded)
+ to_chat(user, "[src] is too heavy to use with one hand. You fumble and drop everything.")
+ user.drop_all_held_items()
+ return
var/datum/status_effect/crusher_damage/C = target.has_status_effect(STATUS_EFFECT_CRUSHERDAMAGETRACKING)
var/target_health = target.health
..()
@@ -71,11 +76,13 @@
if(!QDELETED(C) && !QDELETED(target))
C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did
-/obj/item/twohanded/required/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams)
+/obj/item/twohanded/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams)
. = ..()
if(istype(target, /obj/item/crusher_trophy))
var/obj/item/crusher_trophy/T = target
T.add_to(src, user)
+ if(!wielded)
+ return
if(!proximity_flag && charged)//Mark a target, or mine a tile.
var/turf/proj_turf = user.loc
if(!isturf(proj_turf))
@@ -90,7 +97,7 @@
playsound(user, 'sound/weapons/plasma_cutter.ogg', 100, 1)
D.fire()
charged = FALSE
- icon_state = "mining_hammer1_uncharged"
+ update_icon()
addtimer(CALLBACK(src, .proc/Recharge), charge_time)
return
if(proximity_flag && isliving(target))
@@ -122,12 +129,37 @@
if(user && lavaland_equipment_pressure_check(get_turf(user))) //CIT CHANGE - makes sure below only happens in low pressure environments
user.adjustStaminaLoss(-30)//CIT CHANGE - makes crushers heal stamina
-/obj/item/twohanded/required/kinetic_crusher/proc/Recharge()
+/obj/item/twohanded/kinetic_crusher/proc/Recharge()
if(!charged)
charged = TRUE
- icon_state = "mining_hammer1"
+ update_icon()
playsound(src.loc, 'sound/weapons/kenetic_reload.ogg', 60, 1)
+/obj/item/twohanded/kinetic_crusher/ui_action_click(mob/user, actiontype)
+ light_on = !light_on
+ playsound(user, 'sound/weapons/empty.ogg', 100, TRUE)
+ update_brightness(user)
+ update_icon()
+
+/obj/item/twohanded/kinetic_crusher/proc/update_brightness(mob/user = null)
+ if(light_on)
+ set_light(brightness_on)
+ else
+ set_light(0)
+
+/obj/item/twohanded/kinetic_crusher/update_icon()
+ ..()
+ cut_overlays()
+ if(!charged)
+ add_overlay("[icon_state]_uncharged")
+ if(light_on)
+ add_overlay("[icon_state]_lit")
+ spawn(1)
+ for(var/X in actions)
+ var/datum/action/A = X
+ A.UpdateButtonIcon()
+ item_state = "crusher[wielded]"
+
//destablizing force
/obj/item/projectile/destabilizer
name = "destabilizing force"
@@ -138,7 +170,7 @@
flag = "bomb"
range = 6
log_override = TRUE
- var/obj/item/twohanded/required/kinetic_crusher/hammer_synced
+ var/obj/item/twohanded/kinetic_crusher/hammer_synced
/obj/item/projectile/destabilizer/Destroy()
hammer_synced = null
@@ -177,12 +209,12 @@
return "errors"
/obj/item/crusher_trophy/attackby(obj/item/A, mob/living/user)
- if(istype(A, /obj/item/twohanded/required/kinetic_crusher))
+ if(istype(A, /obj/item/twohanded/kinetic_crusher))
add_to(A, user)
else
..()
-/obj/item/crusher_trophy/proc/add_to(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
+/obj/item/crusher_trophy/proc/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
for(var/t in H.trophies)
var/obj/item/crusher_trophy/T = t
if(istype(T, denied_type) || istype(src, T.denied_type))
@@ -194,7 +226,7 @@
to_chat(user, "You attach [src] to [H]. ")
return TRUE
-/obj/item/crusher_trophy/proc/remove_from(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
+/obj/item/crusher_trophy/proc/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
forceMove(get_turf(H))
H.trophies -= src
return TRUE
@@ -281,12 +313,12 @@
/obj/item/crusher_trophy/legion_skull/effect_desc()
return "a kinetic crusher to recharge [bonus_value*0.1] second\s faster"
-/obj/item/crusher_trophy/legion_skull/add_to(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
+/obj/item/crusher_trophy/legion_skull/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.charge_time -= bonus_value
-/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
+/obj/item/crusher_trophy/legion_skull/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.charge_time += bonus_value
@@ -339,7 +371,7 @@
/obj/item/crusher_trophy/demon_claws/effect_desc()
return "melee hits to do [bonus_value * 0.2] more damage and heal you for [bonus_value * 0.1] , with 5X effect on mark detonation"
-/obj/item/crusher_trophy/demon_claws/add_to(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
+/obj/item/crusher_trophy/demon_claws/add_to(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.force += bonus_value * 0.2
@@ -347,7 +379,7 @@
H.force_wielded += bonus_value * 0.2
H.detonation_damage += bonus_value * 0.8
-/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/twohanded/required/kinetic_crusher/H, mob/living/user)
+/obj/item/crusher_trophy/demon_claws/remove_from(obj/item/twohanded/kinetic_crusher/H, mob/living/user)
. = ..()
if(.)
H.force -= bonus_value * 0.2
diff --git a/code/modules/mining/lavaland/necropolis_chests.dm b/code/modules/mining/lavaland/necropolis_chests.dm
index 5990c70813..fde856c4fb 100644
--- a/code/modules/mining/lavaland/necropolis_chests.dm
+++ b/code/modules/mining/lavaland/necropolis_chests.dm
@@ -205,7 +205,7 @@
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/mob/living/carbon/human/active_owner
-/obj/item/clothing/neck/necklace/memento_mori/item_action_slot_check(slot)
+/obj/item/clothing/neck/necklace/memento_mori/item_action_slot_check(slot, mob/user, datum/action/A)
return slot == SLOT_NECK
/obj/item/clothing/neck/necklace/memento_mori/dropped(mob/user)
@@ -453,7 +453,7 @@
/obj/item/immortality_talisman/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, TRUE)
/datum/action/item_action/immortality
name = "Immortality"
@@ -796,21 +796,21 @@
/obj/item/melee/ghost_sword/proc/ghost_check()
var/list/mob/dead/observer/current_spirits = list()
-
+
recursive_orbit_collect(src, current_spirits)
recursive_orbit_collect(loc, current_spirits) //anything holding us
-
+
for(var/i in spirits - current_spirits)
var/mob/dead/observer/G = i
G.invisibility = GLOB.observer_default_invisibility
-
+
for(var/i in current_spirits)
var/mob/dead/observer/G = i
G.invisibility = 0
-
+
spirits = current_spirits
return length(spirits)
-
+
/obj/item/melee/ghost_sword/attack(mob/living/target, mob/living/carbon/human/user)
force = 0
var/ghost_counter = ghost_check()
@@ -1022,21 +1022,10 @@
message_admins("[ADMIN_LOOKUPFLW(L)] has been marked for death by [ADMIN_LOOKUPFLW(user)]! ")
- var/datum/objective/survive/survive = new
- survive.owner = L.mind
- L.mind.objectives += survive
+ var/datum/antagonist/blood_contract/A = new
+ L.mind.add_antag_datum(A)
+
log_combat(user, L, "took out a blood contract on", src)
- to_chat(L, "You've been marked for death! Don't let the demons get you! KILL THEM ALL! ")
- L.add_atom_colour("#FF0000", ADMIN_COLOUR_PRIORITY)
- var/obj/effect/mine/pickup/bloodbath/B = new(L)
- INVOKE_ASYNC(B, /obj/effect/mine/pickup/bloodbath/.proc/mineEffect, L)
-
- for(var/mob/living/carbon/human/H in GLOB.player_list)
- if(H == L)
- continue
- to_chat(H, "You have an overwhelming desire to kill [L]. [L.p_theyve(TRUE)] been marked red! Whoever [L.p_they()] [L.p_were()], friend or foe, go kill [L.p_them()]! ")
- H.put_in_hands(new /obj/item/kitchen/knife/butcher(H), TRUE)
-
qdel(src)
//Colossus
diff --git a/code/modules/mining/machine_processing.dm b/code/modules/mining/machine_processing.dm
index a004a6ae0d..4d8624864e 100644
--- a/code/modules/mining/machine_processing.dm
+++ b/code/modules/mining/machine_processing.dm
@@ -95,7 +95,7 @@
process_ore(AM)
/obj/machinery/mineral/processing_unit/proc/process_ore(obj/item/stack/ore/O)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/material_amount = materials.get_item_material_amount(O)
if(!materials.has_space(material_amount))
unload_mineral(O)
@@ -107,7 +107,7 @@
/obj/machinery/mineral/processing_unit/proc/get_machine_data()
var/dat = "Smelter control console "
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
dat += "[M.name]: [M.amount] cm³"
@@ -152,7 +152,7 @@
CONSOLE.updateUsrDialog()
/obj/machinery/mineral/processing_unit/proc/smelt_ore()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/datum/material/mat = materials.materials[selected_material]
if(mat)
var/sheets_to_remove = (mat.amount >= (MINERAL_MATERIAL_AMOUNT * SMELT_AMOUNT) ) ? SMELT_AMOUNT : round(mat.amount / MINERAL_MATERIAL_AMOUNT)
@@ -175,7 +175,7 @@
on = FALSE
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.use_amount(alloy.materials, amount)
generate_mineral(alloy.build_path)
@@ -186,7 +186,7 @@
var/build_amount = SMELT_AMOUNT
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in D.materials)
var/M = D.materials[mat_id]
@@ -204,7 +204,7 @@
unload_mineral(O)
/obj/machinery/mineral/processing_unit/on_deconstruction()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
..()
diff --git a/code/modules/mining/machine_redemption.dm b/code/modules/mining/machine_redemption.dm
index 6c1a00b020..c13408b24f 100644
--- a/code/modules/mining/machine_redemption.dm
+++ b/code/modules/mining/machine_redemption.dm
@@ -304,7 +304,9 @@
return
var/alloy_id = params["id"]
var/datum/design/alloy = stored_research.isDesignResearchedID(alloy_id)
- if((check_access(inserted_scan_id) || allowed(usr)) && alloy)
+ var/mob/M = usr
+ var/obj/item/card/id/I = M.get_idcard(TRUE)
+ if((check_access(I) || allowed(usr)) && alloy)
var/smelt_amount = can_smelt_alloy(alloy)
var/desired = 0
if (params["sheets"])
diff --git a/code/modules/mining/machine_silo.dm b/code/modules/mining/machine_silo.dm
index 8fdc50d2ac..c42f1b9f4e 100644
--- a/code/modules/mining/machine_silo.dm
+++ b/code/modules/mining/machine_silo.dm
@@ -34,13 +34,13 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
var/datum/component/remote_materials/mats = C
mats.disconnect_from(src)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
return ..()
/obj/machinery/ore_silo/proc/remote_attackby(obj/machinery/M, mob/user, obj/item/stack/I)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
// stolen from /datum/component/material_container/proc/OnAttackBy
if(user.a_intent != INTENT_HELP)
return
@@ -71,7 +71,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
popup.open()
/obj/machinery/ore_silo/proc/generate_ui()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/list/ui = list("Ore Silo Stored Material: ")
var/any = FALSE
for(var/M in materials.materials)
@@ -149,7 +149,7 @@ GLOBAL_LIST_EMPTY(silo_access_logs)
return TRUE
else if(href_list["ejectsheet"])
var/eject_sheet = href_list["ejectsheet"]
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/count = materials.retrieve_sheets(text2num(href_list["eject_amt"]), eject_sheet, drop_location())
var/list/matlist = list()
matlist[eject_sheet] = MINERAL_MATERIAL_AMOUNT
diff --git a/code/modules/mining/machine_vending.dm b/code/modules/mining/machine_vending.dm
index 38d2e3e100..5a48538161 100644
--- a/code/modules/mining/machine_vending.dm
+++ b/code/modules/mining/machine_vending.dm
@@ -30,7 +30,7 @@
new /datum/data/mining_equipment("500 Point Transfer Card", /obj/item/card/mining_point_card/mp500, 500),
new /datum/data/mining_equipment("Tracking Implant Kit", /obj/item/storage/box/minertracker, 600),
new /datum/data/mining_equipment("Jaunter", /obj/item/wormhole_jaunter, 750),
- new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/required/kinetic_crusher, 750),
+ new /datum/data/mining_equipment("Kinetic Crusher", /obj/item/twohanded/kinetic_crusher, 750),
new /datum/data/mining_equipment("Kinetic Accelerator", /obj/item/gun/energy/kinetic_accelerator, 750),
new /datum/data/mining_equipment("Survival Medipen", /obj/item/reagent_containers/hypospray/medipen/survival, 750),
new /datum/data/mining_equipment("Brute First-Aid Kit", /obj/item/storage/firstaid/brute, 800),
@@ -172,7 +172,7 @@
new /obj/item/stack/marker_beacon/thirty(drop_location)
if("Crusher Kit")
new /obj/item/extinguisher/mini(drop_location)
- new /obj/item/twohanded/required/kinetic_crusher(drop_location)
+ new /obj/item/twohanded/kinetic_crusher(drop_location)
if("Mining Conscription Kit")
new /obj/item/storage/backpack/duffelbag/mining_conscript(drop_location)
diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm
index 15ff372c47..997b117b25 100644
--- a/code/modules/mining/minebot.dm
+++ b/code/modules/mining/minebot.dm
@@ -49,7 +49,7 @@
toggle_mode_action.Grant(src)
var/datum/action/innate/minedrone/dump_ore/dump_ore_action = new()
dump_ore_action.Grant(src)
- var/obj/item/implant/radio/mining/imp = new(src)
+ var/obj/item/implant/radio/mining/imp = new
imp.implant(src)
access_card = new /obj/item/card/id(src)
diff --git a/code/modules/mining/mint.dm b/code/modules/mining/mint.dm
index 6b03be610d..8204977058 100644
--- a/code/modules/mining/mint.dm
+++ b/code/modules/mining/mint.dm
@@ -22,7 +22,7 @@
if(!T)
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/obj/item/stack/sheet/O in T)
materials.insert_stack(O, O.amount)
@@ -32,7 +32,7 @@
return
var/dat = "
Coin Press "
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
if(!M.amount && chosen != mat_id)
@@ -65,7 +65,7 @@
if(processing==1)
to_chat(usr, "
The machine is processing. ")
return
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(href_list["choose"])
if(materials.materials[href_list["choose"]])
chosen = href_list["choose"]
diff --git a/code/modules/mining/money_bag.dm b/code/modules/mining/money_bag.dm
index f567bd1daf..fd5997d3c4 100644
--- a/code/modules/mining/money_bag.dm
+++ b/code/modules/mining/money_bag.dm
@@ -11,7 +11,7 @@
/obj/item/storage/bag/money/Initialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.max_items = 40
STR.max_combined_w_class = 40
diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm
index c780d57810..ee89167f29 100644
--- a/code/modules/mob/camera/camera.dm
+++ b/code/modules/mob/camera/camera.dm
@@ -30,5 +30,8 @@
loc = destination
Moved(oldloc, NONE, TRUE)
+/mob/camera/canUseStorage()
+ return FALSE
+
/mob/camera/emote(act, m_type=1, message = null, intentional = FALSE)
return
diff --git a/code/modules/mob/dead/dead.dm b/code/modules/mob/dead/dead.dm
index 381dc131e7..35dbe0828f 100644
--- a/code/modules/mob/dead/dead.dm
+++ b/code/modules/mob/dead/dead.dm
@@ -20,6 +20,9 @@ INITIALIZE_IMMEDIATE(/mob/dead)
set_focus(src)
return INITIALIZE_HINT_NORMAL
+/mob/dead/canUseStorage()
+ return FALSE
+
/mob/dead/dust(just_ash, drop_items, force) //ghosts can't be vaporised.
return
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 1cd32d43ac..4d253a4693 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -1,623 +1,633 @@
-#define LINKIFY_READY(string, value) "
[string] "
-
-/mob/dead/new_player
- var/ready = 0
- var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
-
- flags_1 = NONE
-
- invisibility = INVISIBILITY_ABSTRACT
-
- density = FALSE
- stat = DEAD
- canmove = FALSE
-
- anchored = TRUE // don't get pushed around
-
- var/mob/living/new_character //for instant transfer once the round is set up
-
- //Used to make sure someone doesn't get spammed with messages if they're ineligible for roles
- var/ineligible_for_roles = FALSE
-
-/mob/dead/new_player/Initialize()
- if(client && SSticker.state == GAME_STATE_STARTUP)
- var/obj/screen/splash/S = new(client, TRUE, TRUE)
- S.Fade(TRUE)
-
- if(length(GLOB.newplayer_start))
- forceMove(pick(GLOB.newplayer_start))
- else
- forceMove(locate(1,1,1))
-
- ComponentInitialize()
-
- . = ..()
-
-/mob/dead/new_player/prepare_huds()
- return
-
-/mob/dead/new_player/proc/new_player_panel()
- var/output = "
Welcome, [client ? client.prefs.real_name : "Unknown User"]
"
- output += "Setup Character
"
-
- if(SSticker.current_state <= GAME_STATE_PREGAME)
- switch(ready)
- if(PLAYER_NOT_READY)
- output += "\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | Not Ready | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]
"
- if(PLAYER_READY_TO_PLAY)
- output += "\[ Ready | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]
"
- if(PLAYER_READY_TO_OBSERVE)
- output += "\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | Observe \]
"
- else
- output += "View the Crew Manifest
"
- output += "Join Game!
"
- output += "[LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)]
"
-
- if(!IsGuestKey(src.key))
- if (SSdbcore.Connect())
- var/isadmin = 0
- if(src.client && src.client.holder)
- isadmin = 1
- var/datum/DBQuery/query_get_new_polls = SSdbcore.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[sanitizeSQL(ckey)]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[sanitizeSQL(ckey)]\")")
- var/rs = REF(src)
- if(query_get_new_polls.Execute())
- var/newpoll = 0
- if(query_get_new_polls.NextRow())
- newpoll = 1
-
- if(newpoll)
- output += "Show Player Polls (NEW!)
"
- else
- output += "Show Player Polls
"
- qdel(query_get_new_polls)
- if(QDELETED(src))
- return
-
- output += " "
-
- //src << browse(output,"window=playersetup;size=210x240;can_close=0")
- var/datum/browser/popup = new(src, "playersetup", "New Player Options
", 250, 265)
- popup.set_window_options("can_close=0")
- popup.set_content(output)
- popup.open(FALSE)
-
-/mob/dead/new_player/Topic(href, href_list[])
- if(src != usr)
- return 0
-
- if(!client)
- return 0
-
- //Determines Relevent Population Cap
- var/relevant_cap
- var/hpc = CONFIG_GET(number/hard_popcap)
- var/epc = CONFIG_GET(number/extreme_popcap)
- if(hpc && epc)
- relevant_cap = min(hpc, epc)
- else
- relevant_cap = max(hpc, epc)
-
- if(href_list["show_preferences"])
- client.prefs.ShowChoices(src)
- return 1
-
- if(href_list["ready"])
- var/tready = text2num(href_list["ready"])
- //Avoid updating ready if we're after PREGAME (they should use latejoin instead)
- //This is likely not an actual issue but I don't have time to prove that this
- //no longer is required
- if(SSticker.current_state <= GAME_STATE_PREGAME)
- ready = tready
- //if it's post initialisation and they're trying to observe we do the needful
- if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE)
- ready = tready
- make_me_an_observer()
- return
-
- if(href_list["refresh"])
- src << browse(null, "window=playersetup") //closes the player setup window
- new_player_panel()
-
- if(href_list["late_join"])
- if(!SSticker || !SSticker.IsRoundInProgress())
- to_chat(usr, "The round is either not ready, or has already finished... ")
- return
-
- if(href_list["late_join"] == "override")
- LateChoices()
- return
-
- if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums)))
- to_chat(usr, "[CONFIG_GET(string/hard_popcap_message)] ")
-
- var/queue_position = SSticker.queued_players.Find(usr)
- if(queue_position == 1)
- to_chat(usr, "You are next in line to join the game. You will be notified when a slot opens up. ")
- else if(queue_position)
- to_chat(usr, "There are [queue_position-1] players in front of you in the queue to join the game. ")
- else
- SSticker.queued_players += usr
- to_chat(usr, "You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len]. ")
- return
- LateChoices()
-
- if(href_list["manifest"])
- ViewManifest()
-
- if(href_list["SelectedJob"])
-
- if(!GLOB.enter_allowed)
- to_chat(usr, "There is an administrative lock on entering the game! ")
- return
-
- if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
- if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
- to_chat(usr, "Server is full. ")
- return
-
- AttemptLateSpawn(href_list["SelectedJob"])
- return
-
- if(href_list["JoinAsGhostRole"])
- if(!GLOB.enter_allowed)
- to_chat(usr, " There is an administrative lock on entering the game! ")
-
- if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
- if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
- to_chat(usr, "Server is full. ")
- return
-
- var/obj/effect/mob_spawn/MS = pick(GLOB.mob_spawners[href_list["JoinAsGhostRole"]])
- if(MS.attack_ghost(src, latejoinercalling = TRUE))
- SSticker.queued_players -= src
- SSticker.queue_delay = 4
- qdel(src)
-
- if(!ready && href_list["preference"])
- if(client)
- client.prefs.process_link(src, href_list)
- else if(!href_list["late_join"])
- new_player_panel()
-
- if(href_list["showpoll"])
- handle_player_polling()
- return
-
- if(href_list["pollid"])
- var/pollid = href_list["pollid"]
- if(istext(pollid))
- pollid = text2num(pollid)
- if(isnum(pollid) && ISINTEGER(pollid))
- src.poll_player(pollid)
- return
-
- if(href_list["votepollid"] && href_list["votetype"])
- var/pollid = text2num(href_list["votepollid"])
- var/votetype = href_list["votetype"]
- //lets take data from the user to decide what kind of poll this is, without validating it
- //what could go wrong
- switch(votetype)
- if(POLLTYPE_OPTION)
- var/optionid = text2num(href_list["voteoptionid"])
- if(vote_on_poll(pollid, optionid))
- to_chat(usr, "Vote successful. ")
- else
- to_chat(usr, "Vote failed, please try again or contact an administrator. ")
- if(POLLTYPE_TEXT)
- var/replytext = href_list["replytext"]
- if(log_text_poll_reply(pollid, replytext))
- to_chat(usr, "Feedback logging successful. ")
- else
- to_chat(usr, "Feedback logging failed, please try again or contact an administrator. ")
- if(POLLTYPE_RATING)
- var/id_min = text2num(href_list["minid"])
- var/id_max = text2num(href_list["maxid"])
-
- if( (id_max - id_min) > 100 ) //Basic exploit prevention
- //(protip, this stops no exploits)
- to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
- return
-
- for(var/optionid = id_min; optionid <= id_max; optionid++)
- if(!isnull(href_list["o[optionid]"])) //Test if this optionid was replied to
- var/rating
- if(href_list["o[optionid]"] == "abstain")
- rating = null
- else
- rating = text2num(href_list["o[optionid]"])
- if(!isnum(rating) || !ISINTEGER(rating))
- return
-
- if(!vote_on_numval_poll(pollid, optionid, rating))
- to_chat(usr, "Vote failed, please try again or contact an administrator. ")
- return
- to_chat(usr, "Vote successful. ")
- if(POLLTYPE_MULTI)
- var/id_min = text2num(href_list["minoptionid"])
- var/id_max = text2num(href_list["maxoptionid"])
-
- if( (id_max - id_min) > 100 ) //Basic exploit prevention
- to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
- return
-
- for(var/optionid = id_min; optionid <= id_max; optionid++)
- if(!isnull(href_list["option_[optionid]"])) //Test if this optionid was selected
- var/i = vote_on_multi_poll(pollid, optionid)
- switch(i)
- if(0)
- continue
- if(1)
- to_chat(usr, "Vote failed, please try again or contact an administrator. ")
- return
- if(2)
- to_chat(usr, "Maximum replies reached. ")
- break
- to_chat(usr, "Vote successful. ")
- if(POLLTYPE_IRV)
- if (!href_list["IRVdata"])
- to_chat(src, "No ordering data found. Please try again or contact an administrator. ")
- return
- var/list/votelist = splittext(href_list["IRVdata"], ",")
- if (!vote_on_irv_poll(pollid, votelist))
- to_chat(src, "Vote failed, please try again or contact an administrator. ")
- return
- to_chat(src, "Vote successful. ")
-
-//When you cop out of the round (NB: this HAS A SLEEP FOR PLAYER INPUT IN IT)
-/mob/dead/new_player/proc/make_me_an_observer()
- if(QDELETED(src) || !src.client)
- ready = PLAYER_NOT_READY
- return FALSE
-
- var/this_is_like_playing_right = alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No")
-
- if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
- ready = PLAYER_NOT_READY
- src << browse(null, "window=playersetup") //closes the player setup window
- new_player_panel()
- return FALSE
-
- var/mob/dead/observer/observer = new()
- spawning = TRUE
-
- observer.started_as_observer = TRUE
- close_spawn_windows()
- var/obj/effect/landmark/observer_start/O = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list
- to_chat(src, "Now teleporting. ")
- if (O)
- observer.forceMove(O.loc)
- else
- to_chat(src, "Teleporting failed. Ahelp an admin please ")
- stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised")
- observer.key = key
- observer.client = client
- observer.set_ghost_appearance()
- if(observer.client && observer.client.prefs)
- observer.real_name = observer.client.prefs.real_name
- observer.name = observer.real_name
- observer.update_icon()
- observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
- QDEL_NULL(mind)
- qdel(src)
- return TRUE
-
-/proc/get_job_unavailable_error_message(retval, jobtitle)
- switch(retval)
- if(JOB_AVAILABLE)
- return "[jobtitle] is available."
- if(JOB_UNAVAILABLE_GENERIC)
- return "[jobtitle] is unavailable."
- if(JOB_UNAVAILABLE_BANNED)
- return "You are currently banned from [jobtitle]."
- if(JOB_UNAVAILABLE_PLAYTIME)
- return "You do not have enough relevant playtime for [jobtitle]."
- if(JOB_UNAVAILABLE_ACCOUNTAGE)
- return "Your account is not old enough for [jobtitle]."
- if(JOB_UNAVAILABLE_SLOTFULL)
- return "[jobtitle] is already filled to capacity."
- return "Error: Unknown job availability."
-
-/mob/dead/new_player/proc/IsJobUnavailable(rank, latejoin = FALSE)
- var/datum/job/job = SSjob.GetJob(rank)
- if(!job)
- return JOB_UNAVAILABLE_GENERIC
- if((job.current_positions >= job.total_positions) && job.total_positions != -1)
- if(job.title == "Assistant")
- if(isnum(client.player_age) && client.player_age <= 14) //Newbies can always be assistants
- return JOB_AVAILABLE
- for(var/datum/job/J in SSjob.occupations)
- if(J && J.current_positions < J.total_positions && J.title != job.title)
- return JOB_UNAVAILABLE_SLOTFULL
- else
- return JOB_UNAVAILABLE_SLOTFULL
- if(jobban_isbanned(src,rank))
- return JOB_UNAVAILABLE_BANNED
- if(QDELETED(src))
- return JOB_UNAVAILABLE_GENERIC
- if(!job.player_old_enough(client))
- return JOB_UNAVAILABLE_ACCOUNTAGE
- if(job.required_playtime_remaining(client))
- return JOB_UNAVAILABLE_PLAYTIME
- if(latejoin && !job.special_check_latejoin(client))
- return JOB_UNAVAILABLE_GENERIC
- return JOB_AVAILABLE
-
-/mob/dead/new_player/proc/AttemptLateSpawn(rank)
- var/error = IsJobUnavailable(rank)
- if(error != JOB_AVAILABLE)
- alert(src, get_job_unavailable_error_message(error, rank))
- return FALSE
-
- if(SSticker.late_join_disabled)
- alert(src, "An administrator has disabled late join spawning.")
- return FALSE
-
- var/arrivals_docked = TRUE
- if(SSshuttle.arrivals)
- close_spawn_windows() //In case we get held up
- if(SSshuttle.arrivals.damaged && CONFIG_GET(flag/arrivals_shuttle_require_safe_latejoin))
- src << alert("The arrivals shuttle is currently malfunctioning! You cannot join.")
- return FALSE
-
- if(CONFIG_GET(flag/arrivals_shuttle_require_undocked))
- SSshuttle.arrivals.RequireUndocked(src)
- arrivals_docked = SSshuttle.arrivals.mode != SHUTTLE_CALL
-
- //Remove the player from the join queue if he was in one and reset the timer
- SSticker.queued_players -= src
- SSticker.queue_delay = 4
-
- SSjob.AssignRole(src, rank, 1)
-
- var/mob/living/character = create_character(TRUE) //creates the human and transfers vars and mind
- var/equip = SSjob.EquipRank(character, rank, TRUE)
- if(isliving(equip)) //Borgs get borged in the equip, so we need to make sure we handle the new mob.
- character = equip
-
- var/datum/job/job = SSjob.GetJob(rank)
-
- if(job && !job.override_latejoin_spawn(character))
- SSjob.SendToLateJoin(character)
- if(!arrivals_docked)
- var/obj/screen/splash/Spl = new(character.client, TRUE)
- Spl.Fade(TRUE)
- character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25)
-
- character.update_parallax_teleport()
-
- SSticker.minds += character.mind
-
- var/mob/living/carbon/human/humanc
- if(ishuman(character))
- humanc = character //Let's retypecast the var to be human,
-
- if(humanc) //These procs all expect humans
- GLOB.data_core.manifest_inject(humanc)
- if(SSshuttle.arrivals)
- SSshuttle.arrivals.QueueAnnounce(humanc, rank)
- else
- AnnounceArrival(humanc, rank)
- AddEmploymentContract(humanc)
- if(GLOB.highlander)
- to_chat(humanc, "THERE CAN BE ONLY ONE!!! ")
- humanc.make_scottish()
-
- if(GLOB.summon_guns_triggered)
- give_guns(humanc)
- if(GLOB.summon_magic_triggered)
- give_magic(humanc)
-
- GLOB.joined_player_list += character.ckey
- GLOB.latejoiners += character
-
- if(CONFIG_GET(flag/allow_latejoin_antagonists) && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais.
- if(SSshuttle.emergency)
- switch(SSshuttle.emergency.mode)
- if(SHUTTLE_RECALL, SHUTTLE_IDLE)
- SSticker.mode.make_antag_chance(humanc)
- if(SHUTTLE_CALL)
- if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5)
- SSticker.mode.make_antag_chance(humanc)
-
- if(humanc && CONFIG_GET(flag/roundstart_traits))
- SSquirks.AssignQuirks(humanc, humanc.client, TRUE, FALSE, job, FALSE)
-
- log_manifest(character.mind.key,character.mind,character,latejoin = TRUE)
-
-/mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee)
- //TODO: figure out a way to exclude wizards/nukeops/demons from this.
- for(var/C in GLOB.employmentCabinets)
- var/obj/structure/filingcabinet/employment/employmentCabinet = C
- if(!employmentCabinet.virgin)
- employmentCabinet.addFile(employee)
-
-
-/mob/dead/new_player/proc/LateChoices()
-
- var/level = "green"
- switch(GLOB.security_level)
- if(SEC_LEVEL_GREEN)
- level = "green"
- if(SEC_LEVEL_BLUE)
- level = "blue"
- if(SEC_LEVEL_AMBER)
- level = "amber"
- if(SEC_LEVEL_RED)
- level = "red"
- if(SEC_LEVEL_DELTA)
- level = "delta"
-
- var/dat = "Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)] Alert Level: [capitalize(level)]
"
- if(SSshuttle.emergency)
- switch(SSshuttle.emergency.mode)
- if(SHUTTLE_ESCAPE)
- dat += "The station has been evacuated.
"
- if(SHUTTLE_CALL)
- if(!SSshuttle.canRecall())
- dat += "The station is currently undergoing evacuation procedures.
"
- for(var/datum/job/prioritized_job in SSjob.prioritized_jobs)
- if(prioritized_job.current_positions >= prioritized_job.total_positions)
- SSjob.prioritized_jobs -= prioritized_job
- dat += ""
- var/column_counter = 0
- var/free_space = 0
- for(var/list/category in list(GLOB.command_positions) + list(GLOB.supply_positions) + list(GLOB.engineering_positions) + list(GLOB.nonhuman_positions - "pAI") + list(GLOB.civilian_positions) + list(GLOB.medical_positions) + list(GLOB.science_positions) + list(GLOB.security_positions))
- var/cat_color = "fff" //random default
- if(SSjob.name_occupations && SSjob.name_occupations[category[1]])
- cat_color = SSjob.name_occupations[category[1]].selection_color //use the color of the first job in the category (the department head) as the category color
- else
- cat_color = SSjob.occupations[category[1]].selection_color
- dat += ""
- dat += "[SSjob.name_occupations[category[1]].exp_type_department] "
-
- var/list/dept_dat = list()
- for(var/job in category)
- var/datum/job/job_datum = SSjob.name_occupations[job]
- if(job_datum && IsJobUnavailable(job_datum.title, TRUE) == JOB_AVAILABLE)
- var/command_bold = ""
- if(job in GLOB.command_positions)
- command_bold = " command"
- if(job_datum in SSjob.prioritized_jobs)
- dept_dat += "[job_datum.title] ([job_datum.current_positions]) "
- else
- dept_dat += "[job_datum.title] ([job_datum.current_positions]) "
- if(!dept_dat.len)
- dept_dat += "No positions open. "
- dat += jointext(dept_dat, "")
- dat += " "
- column_counter++
- if(free_space <=4)
- free_space++
- if(column_counter > 0 && (column_counter % 3 == 0))
- dat += " "
- if(free_space >= 5 && (free_space % 5 == 0) && (column_counter % 3 != 0))
- free_space = 0
- column_counter = 0
- dat += " "
-
- dat += "
"
-
- var/available_ghosts = 0
- for(var/spawner in GLOB.mob_spawners)
- if(!LAZYLEN(spawner))
- continue
- var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner])
- if(!istype(S) || !S.can_latejoin())
- continue
- available_ghosts++
- break
-
- if(!available_ghosts)
- dat += "
There are currently no open ghost spawners.
"
- else
- var/list/categorizedJobs = list("Ghost Role" = list(jobs = list(), titles = GLOB.mob_spawners, color = "#ffffff"))
- for(var/spawner in GLOB.mob_spawners)
- if(!LAZYLEN(spawner))
- continue
- var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner])
- if(!istype(S) || !S.can_latejoin())
- continue
- categorizedJobs["Ghost Role"]["jobs"] += spawner
-
- dat += "
"
- for(var/jobcat in categorizedJobs)
- if(!length(categorizedJobs[jobcat]["jobs"]))
- continue
- var/color = categorizedJobs[jobcat]["color"]
- dat += ""
- dat += "[jobcat] "
- for(var/spawner in categorizedJobs[jobcat]["jobs"])
- dat += "[spawner] "
-
- dat += " "
- dat += "
"
- dat += "
"
-
- var/datum/browser/popup = new(src, "latechoices", "Choose Profession", 720, 600)
- popup.add_stylesheet("playeroptions", 'html/browser/playeroptions.css')
- popup.set_content(jointext(dat, ""))
- popup.open(FALSE) // FALSE is passed to open so that it doesn't use the onclose() proc
-
-/mob/dead/new_player/proc/create_character(transfer_after)
- spawning = 1
- close_spawn_windows()
-
- var/mob/living/carbon/human/H = new(loc)
-
- var/frn = CONFIG_GET(flag/force_random_names)
- if(!frn)
- frn = jobban_isbanned(src, "appearance")
- if(QDELETED(src))
- return
- if(frn)
- client.prefs.random_character()
- client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
- client.prefs.copy_to(H)
- H.dna.update_dna_identity()
- if(mind)
- if(transfer_after)
- mind.late_joiner = TRUE
- mind.active = 0 //we wish to transfer the key manually
- mind.transfer_to(H) //won't transfer key since the mind is not active
-
- H.name = real_name
-
- . = H
- new_character = .
- if(transfer_after)
- transfer_character()
-
-/mob/dead/new_player/proc/transfer_character()
- . = new_character
- if(.)
- new_character.key = key //Manually transfer the key to log them in
- new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC)
- new_character = null
- qdel(src)
-
-/mob/dead/new_player/proc/ViewManifest()
- var/dat = ""
- dat += "Crew Manifest "
- dat += GLOB.data_core.get_manifest(OOC = 1)
-
- src << browse(dat, "window=manifest;size=387x420;can_close=1")
-
-/mob/dead/new_player/Move()
- return 0
-
-
-/mob/dead/new_player/proc/close_spawn_windows()
-
- src << browse(null, "window=latechoices") //closes late choices window
- src << browse(null, "window=playersetup") //closes the player setup window
- src << browse(null, "window=preferences") //closes job selection
- src << browse(null, "window=mob_occupation")
- src << browse(null, "window=latechoices") //closes late job selection
-
-/* Used to make sure that a player has a valid job preference setup, used to knock players out of eligibility for anything if their prefs don't make sense.
- A "valid job preference setup" in this situation means at least having one job set to low, or not having "return to lobby" enabled
- Prevents "antag rolling" by setting antag prefs on, all jobs to never, and "return to lobby if preferences not availible"
- Doing so would previously allow you to roll for antag, then send you back to lobby if you didn't get an antag role
- This also does some admin notification and logging as well, as well as some extra logic to make sure things don't go wrong
-*/
-
-/mob/dead/new_player/proc/check_preferences()
- if(!client)
- return FALSE //Not sure how this would get run without the mob having a client, but let's just be safe.
- if(client.prefs.joblessrole != RETURNTOLOBBY)
- return TRUE
- // If they have antags enabled, they're potentially doing this on purpose instead of by accident. Notify admins if so.
- var/has_antags = FALSE
- if(client.prefs.be_special.len > 0)
- has_antags = TRUE
- if(client.prefs.job_preferences.len == 0)
- if(!ineligible_for_roles)
- to_chat(src, "You have no jobs enabled, along with return to lobby if job is unavailable. This makes you ineligible for any round start role, please update your job preferences. ")
- ineligible_for_roles = TRUE
- ready = PLAYER_NOT_READY
- if(has_antags)
- log_admin("[src.ckey] just got booted back to lobby with no jobs, but antags enabled.")
- message_admins("[src.ckey] just got booted back to lobby with no jobs enabled, but antag rolling enabled. Likely antag rolling abuse.")
-
- return FALSE //This is the only case someone should actually be completely blocked from antag rolling as well
- return TRUE
+#define LINKIFY_READY(string, value) "[string] "
+
+/mob/dead/new_player
+ var/ready = 0
+ var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
+
+ flags_1 = NONE
+
+ invisibility = INVISIBILITY_ABSTRACT
+
+ density = FALSE
+ stat = DEAD
+ canmove = FALSE
+
+ anchored = TRUE // don't get pushed around
+
+ var/mob/living/new_character //for instant transfer once the round is set up
+
+ //Used to make sure someone doesn't get spammed with messages if they're ineligible for roles
+ var/ineligible_for_roles = FALSE
+
+/mob/dead/new_player/Initialize()
+ if(client && SSticker.state == GAME_STATE_STARTUP)
+ var/obj/screen/splash/S = new(client, TRUE, TRUE)
+ S.Fade(TRUE)
+
+ if(length(GLOB.newplayer_start))
+ forceMove(pick(GLOB.newplayer_start))
+ else
+ forceMove(locate(1,1,1))
+
+ ComponentInitialize()
+
+ . = ..()
+
+/mob/dead/new_player/prepare_huds()
+ return
+
+/mob/dead/new_player/proc/new_player_panel()
+ var/output = "Welcome, [client ? client.prefs.real_name : "Unknown User"]
"
+ output += "Setup Character
"
+
+ if(SSticker.current_state <= GAME_STATE_PREGAME)
+ switch(ready)
+ if(PLAYER_NOT_READY)
+ output += "\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | Not Ready | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]
"
+ if(PLAYER_READY_TO_PLAY)
+ output += "\[ Ready | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | [LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)] \]
"
+ if(PLAYER_READY_TO_OBSERVE)
+ output += "\[ [LINKIFY_READY("Ready", PLAYER_READY_TO_PLAY)] | [LINKIFY_READY("Not Ready", PLAYER_NOT_READY)] | Observe \]
"
+ else
+ output += "View the Crew Manifest
"
+ output += "Join Game!
"
+ output += "[LINKIFY_READY("Observe", PLAYER_READY_TO_OBSERVE)]
"
+
+ if(!IsGuestKey(src.key))
+ if (SSdbcore.Connect())
+ var/isadmin = 0
+ if(src.client && src.client.holder)
+ isadmin = 1
+ var/datum/DBQuery/query_get_new_polls = SSdbcore.NewQuery("SELECT id FROM [format_table_name("poll_question")] WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM [format_table_name("poll_vote")] WHERE ckey = \"[sanitizeSQL(ckey)]\") AND id NOT IN (SELECT pollid FROM [format_table_name("poll_textreply")] WHERE ckey = \"[sanitizeSQL(ckey)]\")")
+ var/rs = REF(src)
+ if(query_get_new_polls.Execute())
+ var/newpoll = 0
+ if(query_get_new_polls.NextRow())
+ newpoll = 1
+
+ if(newpoll)
+ output += "Show Player Polls (NEW!)
"
+ else
+ output += "Show Player Polls
"
+ qdel(query_get_new_polls)
+ if(QDELETED(src))
+ return
+
+ output += " "
+
+ //src << browse(output,"window=playersetup;size=210x240;can_close=0")
+ var/datum/browser/popup = new(src, "playersetup", "New Player Options
", 250, 265)
+ popup.set_window_options("can_close=0")
+ popup.set_content(output)
+ popup.open(FALSE)
+
+/mob/dead/new_player/Topic(href, href_list[])
+ if(src != usr)
+ return 0
+
+ if(!client)
+ return 0
+
+ //Determines Relevent Population Cap
+ var/relevant_cap
+ var/hpc = CONFIG_GET(number/hard_popcap)
+ var/epc = CONFIG_GET(number/extreme_popcap)
+ if(hpc && epc)
+ relevant_cap = min(hpc, epc)
+ else
+ relevant_cap = max(hpc, epc)
+
+ if(href_list["show_preferences"])
+ client.prefs.ShowChoices(src)
+ return 1
+
+ if(href_list["ready"])
+ var/tready = text2num(href_list["ready"])
+ //Avoid updating ready if we're after PREGAME (they should use latejoin instead)
+ //This is likely not an actual issue but I don't have time to prove that this
+ //no longer is required
+ if(SSticker.current_state <= GAME_STATE_PREGAME)
+ ready = tready
+ //if it's post initialisation and they're trying to observe we do the needful
+ if(!SSticker.current_state < GAME_STATE_PREGAME && tready == PLAYER_READY_TO_OBSERVE)
+ ready = tready
+ make_me_an_observer()
+ return
+
+ if(href_list["refresh"])
+ src << browse(null, "window=playersetup") //closes the player setup window
+ new_player_panel()
+
+ if(href_list["late_join"])
+ if(!SSticker || !SSticker.IsRoundInProgress())
+ to_chat(usr, "The round is either not ready, or has already finished... ")
+ return
+
+ if(href_list["late_join"] == "override")
+ LateChoices()
+ return
+
+ if(SSticker.queued_players.len || (relevant_cap && living_player_count() >= relevant_cap && !(ckey(key) in GLOB.admin_datums)))
+ to_chat(usr, "[CONFIG_GET(string/hard_popcap_message)] ")
+
+ var/queue_position = SSticker.queued_players.Find(usr)
+ if(queue_position == 1)
+ to_chat(usr, "You are next in line to join the game. You will be notified when a slot opens up. ")
+ else if(queue_position)
+ to_chat(usr, "There are [queue_position-1] players in front of you in the queue to join the game. ")
+ else
+ SSticker.queued_players += usr
+ to_chat(usr, "You have been added to the queue to join the game. Your position in queue is [SSticker.queued_players.len]. ")
+ return
+ LateChoices()
+
+ if(href_list["manifest"])
+ ViewManifest()
+
+ if(href_list["SelectedJob"])
+ if(!SSticker || !SSticker.IsRoundInProgress())
+ var/msg = "[key_name(usr)] attempted to join the round using a href that shouldn't be available at this moment!"
+ log_admin(msg)
+ message_admins(msg)
+ to_chat(usr, "The round is either not ready, or has already finished... ")
+ return
+
+ if(!GLOB.enter_allowed)
+ to_chat(usr, "There is an administrative lock on entering the game! ")
+ return
+
+ if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
+ if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
+ to_chat(usr, "Server is full. ")
+ return
+
+ AttemptLateSpawn(href_list["SelectedJob"])
+ return
+
+ if(href_list["JoinAsGhostRole"])
+ if(!GLOB.enter_allowed)
+ to_chat(usr, " There is an administrative lock on entering the game! ")
+
+ if(SSticker.queued_players.len && !(ckey(key) in GLOB.admin_datums))
+ if((living_player_count() >= relevant_cap) || (src != SSticker.queued_players[1]))
+ to_chat(usr, "Server is full. ")
+ return
+
+ var/obj/effect/mob_spawn/MS = pick(GLOB.mob_spawners[href_list["JoinAsGhostRole"]])
+ if(MS.attack_ghost(src, latejoinercalling = TRUE))
+ SSticker.queued_players -= src
+ SSticker.queue_delay = 4
+ qdel(src)
+
+ if(!ready && href_list["preference"])
+ if(client)
+ client.prefs.process_link(src, href_list)
+ else if(!href_list["late_join"])
+ new_player_panel()
+
+ if(href_list["showpoll"])
+ handle_player_polling()
+ return
+
+ if(href_list["pollid"])
+ var/pollid = href_list["pollid"]
+ if(istext(pollid))
+ pollid = text2num(pollid)
+ if(isnum(pollid) && ISINTEGER(pollid))
+ src.poll_player(pollid)
+ return
+
+ if(href_list["votepollid"] && href_list["votetype"])
+ var/pollid = text2num(href_list["votepollid"])
+ var/votetype = href_list["votetype"]
+ //lets take data from the user to decide what kind of poll this is, without validating it
+ //what could go wrong
+ switch(votetype)
+ if(POLLTYPE_OPTION)
+ var/optionid = text2num(href_list["voteoptionid"])
+ if(vote_on_poll(pollid, optionid))
+ to_chat(usr, "Vote successful. ")
+ else
+ to_chat(usr, "Vote failed, please try again or contact an administrator. ")
+ if(POLLTYPE_TEXT)
+ var/replytext = href_list["replytext"]
+ if(log_text_poll_reply(pollid, replytext))
+ to_chat(usr, "Feedback logging successful. ")
+ else
+ to_chat(usr, "Feedback logging failed, please try again or contact an administrator. ")
+ if(POLLTYPE_RATING)
+ var/id_min = text2num(href_list["minid"])
+ var/id_max = text2num(href_list["maxid"])
+
+ if( (id_max - id_min) > 100 ) //Basic exploit prevention
+ //(protip, this stops no exploits)
+ to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
+ return
+
+ for(var/optionid = id_min; optionid <= id_max; optionid++)
+ if(!isnull(href_list["o[optionid]"])) //Test if this optionid was replied to
+ var/rating
+ if(href_list["o[optionid]"] == "abstain")
+ rating = null
+ else
+ rating = text2num(href_list["o[optionid]"])
+ if(!isnum(rating) || !ISINTEGER(rating))
+ return
+
+ if(!vote_on_numval_poll(pollid, optionid, rating))
+ to_chat(usr, "Vote failed, please try again or contact an administrator. ")
+ return
+ to_chat(usr, "Vote successful. ")
+ if(POLLTYPE_MULTI)
+ var/id_min = text2num(href_list["minoptionid"])
+ var/id_max = text2num(href_list["maxoptionid"])
+
+ if( (id_max - id_min) > 100 ) //Basic exploit prevention
+ to_chat(usr, "The option ID difference is too big. Please contact administration or the database admin.")
+ return
+
+ for(var/optionid = id_min; optionid <= id_max; optionid++)
+ if(!isnull(href_list["option_[optionid]"])) //Test if this optionid was selected
+ var/i = vote_on_multi_poll(pollid, optionid)
+ switch(i)
+ if(0)
+ continue
+ if(1)
+ to_chat(usr, "Vote failed, please try again or contact an administrator. ")
+ return
+ if(2)
+ to_chat(usr, "Maximum replies reached. ")
+ break
+ to_chat(usr, "Vote successful. ")
+ if(POLLTYPE_IRV)
+ if (!href_list["IRVdata"])
+ to_chat(src, "No ordering data found. Please try again or contact an administrator. ")
+ return
+ var/list/votelist = splittext(href_list["IRVdata"], ",")
+ if (!vote_on_irv_poll(pollid, votelist))
+ to_chat(src, "Vote failed, please try again or contact an administrator. ")
+ return
+ to_chat(src, "Vote successful. ")
+
+//When you cop out of the round (NB: this HAS A SLEEP FOR PLAYER INPUT IN IT)
+/mob/dead/new_player/proc/make_me_an_observer()
+ if(QDELETED(src) || !src.client)
+ ready = PLAYER_NOT_READY
+ return FALSE
+
+ var/this_is_like_playing_right = alert(src,"Are you sure you wish to observe? You will not be able to play this round!","Player Setup","Yes","No")
+
+ if(QDELETED(src) || !src.client || this_is_like_playing_right != "Yes")
+ ready = PLAYER_NOT_READY
+ src << browse(null, "window=playersetup") //closes the player setup window
+ new_player_panel()
+ return FALSE
+
+ var/mob/dead/observer/observer = new()
+ spawning = TRUE
+
+ observer.started_as_observer = TRUE
+ close_spawn_windows()
+ var/obj/effect/landmark/observer_start/O = locate(/obj/effect/landmark/observer_start) in GLOB.landmarks_list
+ to_chat(src, "Now teleporting. ")
+ if (O)
+ observer.forceMove(O.loc)
+ else
+ to_chat(src, "Teleporting failed. Ahelp an admin please ")
+ stack_trace("There's no freaking observer landmark available on this map or you're making observers before the map is initialised")
+ transfer_ckey(observer, FALSE)
+ observer.client = client
+ observer.set_ghost_appearance()
+ if(observer.client && observer.client.prefs)
+ observer.real_name = observer.client.prefs.real_name
+ observer.name = observer.real_name
+ observer.update_icon()
+ observer.stop_sound_channel(CHANNEL_LOBBYMUSIC)
+ QDEL_NULL(mind)
+ qdel(src)
+ return TRUE
+
+/proc/get_job_unavailable_error_message(retval, jobtitle)
+ switch(retval)
+ if(JOB_AVAILABLE)
+ return "[jobtitle] is available."
+ if(JOB_UNAVAILABLE_GENERIC)
+ return "[jobtitle] is unavailable."
+ if(JOB_UNAVAILABLE_BANNED)
+ return "You are currently banned from [jobtitle]."
+ if(JOB_UNAVAILABLE_PLAYTIME)
+ return "You do not have enough relevant playtime for [jobtitle]."
+ if(JOB_UNAVAILABLE_ACCOUNTAGE)
+ return "Your account is not old enough for [jobtitle]."
+ if(JOB_UNAVAILABLE_SLOTFULL)
+ return "[jobtitle] is already filled to capacity."
+ if(JOB_UNAVAILABLE_SPECIESLOCK)
+ return "Your species cannot play as a [jobtitle]."
+ return "Error: Unknown job availability."
+
+/mob/dead/new_player/proc/IsJobUnavailable(rank, latejoin = FALSE)
+ var/datum/job/job = SSjob.GetJob(rank)
+ if(!job)
+ return JOB_UNAVAILABLE_GENERIC
+ if((job.current_positions >= job.total_positions) && job.total_positions != -1)
+ if(job.title == "Assistant")
+ if(isnum(client.player_age) && client.player_age <= 14) //Newbies can always be assistants
+ return JOB_AVAILABLE
+ for(var/datum/job/J in SSjob.occupations)
+ if(J && J.current_positions < J.total_positions && J.title != job.title)
+ return JOB_UNAVAILABLE_SLOTFULL
+ else
+ return JOB_UNAVAILABLE_SLOTFULL
+ if(jobban_isbanned(src,rank))
+ return JOB_UNAVAILABLE_BANNED
+ if(QDELETED(src))
+ return JOB_UNAVAILABLE_GENERIC
+ if(!job.player_old_enough(client))
+ return JOB_UNAVAILABLE_ACCOUNTAGE
+ if(job.required_playtime_remaining(client))
+ return JOB_UNAVAILABLE_PLAYTIME
+ if(latejoin && !job.special_check_latejoin(client))
+ return JOB_UNAVAILABLE_GENERIC
+ if(!client.prefs.pref_species.qualifies_for_rank(rank, client.prefs.features))
+ return JOB_UNAVAILABLE_SPECIESLOCK
+ return JOB_AVAILABLE
+
+/mob/dead/new_player/proc/AttemptLateSpawn(rank)
+ var/error = IsJobUnavailable(rank)
+ if(error != JOB_AVAILABLE)
+ alert(src, get_job_unavailable_error_message(error, rank))
+ return FALSE
+
+ if(SSticker.late_join_disabled)
+ alert(src, "An administrator has disabled late join spawning.")
+ return FALSE
+
+ var/arrivals_docked = TRUE
+ if(SSshuttle.arrivals)
+ close_spawn_windows() //In case we get held up
+ if(SSshuttle.arrivals.damaged && CONFIG_GET(flag/arrivals_shuttle_require_safe_latejoin))
+ src << alert("The arrivals shuttle is currently malfunctioning! You cannot join.")
+ return FALSE
+
+ if(CONFIG_GET(flag/arrivals_shuttle_require_undocked))
+ SSshuttle.arrivals.RequireUndocked(src)
+ arrivals_docked = SSshuttle.arrivals.mode != SHUTTLE_CALL
+
+ //Remove the player from the join queue if he was in one and reset the timer
+ SSticker.queued_players -= src
+ SSticker.queue_delay = 4
+
+ SSjob.AssignRole(src, rank, 1)
+
+ var/mob/living/character = create_character(TRUE) //creates the human and transfers vars and mind
+ var/equip = SSjob.EquipRank(character, rank, TRUE)
+ if(isliving(equip)) //Borgs get borged in the equip, so we need to make sure we handle the new mob.
+ character = equip
+
+ var/datum/job/job = SSjob.GetJob(rank)
+
+ if(job && !job.override_latejoin_spawn(character))
+ SSjob.SendToLateJoin(character)
+ if(!arrivals_docked)
+ var/obj/screen/splash/Spl = new(character.client, TRUE)
+ Spl.Fade(TRUE)
+ character.playsound_local(get_turf(character), 'sound/voice/ApproachingTG.ogg', 25)
+
+ character.update_parallax_teleport()
+
+ SSticker.minds += character.mind
+
+ var/mob/living/carbon/human/humanc
+ if(ishuman(character))
+ humanc = character //Let's retypecast the var to be human,
+
+ if(humanc) //These procs all expect humans
+ GLOB.data_core.manifest_inject(humanc)
+ if(SSshuttle.arrivals)
+ SSshuttle.arrivals.QueueAnnounce(humanc, rank)
+ else
+ AnnounceArrival(humanc, rank)
+ AddEmploymentContract(humanc)
+ if(GLOB.highlander)
+ to_chat(humanc, "THERE CAN BE ONLY ONE!!! ")
+ humanc.make_scottish()
+
+ if(GLOB.summon_guns_triggered)
+ give_guns(humanc)
+ if(GLOB.summon_magic_triggered)
+ give_magic(humanc)
+
+ GLOB.joined_player_list += character.ckey
+ GLOB.latejoiners += character
+
+ if(CONFIG_GET(flag/allow_latejoin_antagonists) && humanc) //Borgs aren't allowed to be antags. Will need to be tweaked if we get true latejoin ais.
+ if(SSshuttle.emergency)
+ switch(SSshuttle.emergency.mode)
+ if(SHUTTLE_RECALL, SHUTTLE_IDLE)
+ SSticker.mode.make_antag_chance(humanc)
+ if(SHUTTLE_CALL)
+ if(SSshuttle.emergency.timeLeft(1) > initial(SSshuttle.emergencyCallTime)*0.5)
+ SSticker.mode.make_antag_chance(humanc)
+
+ if(humanc && CONFIG_GET(flag/roundstart_traits))
+ SSquirks.AssignQuirks(humanc, humanc.client, TRUE, FALSE, job, FALSE)
+
+ log_manifest(character.mind.key,character.mind,character,latejoin = TRUE)
+
+/mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee)
+ //TODO: figure out a way to exclude wizards/nukeops/demons from this.
+ for(var/C in GLOB.employmentCabinets)
+ var/obj/structure/filingcabinet/employment/employmentCabinet = C
+ if(!employmentCabinet.virgin)
+ employmentCabinet.addFile(employee)
+
+
+/mob/dead/new_player/proc/LateChoices()
+
+ var/level = "green"
+ switch(GLOB.security_level)
+ if(SEC_LEVEL_GREEN)
+ level = "green"
+ if(SEC_LEVEL_BLUE)
+ level = "blue"
+ if(SEC_LEVEL_AMBER)
+ level = "amber"
+ if(SEC_LEVEL_RED)
+ level = "red"
+ if(SEC_LEVEL_DELTA)
+ level = "delta"
+
+ var/dat = "Round Duration: [DisplayTimeText(world.time - SSticker.round_start_time)] Alert Level: [capitalize(level)]
"
+ if(SSshuttle.emergency)
+ switch(SSshuttle.emergency.mode)
+ if(SHUTTLE_ESCAPE)
+ dat += "The station has been evacuated.
"
+ if(SHUTTLE_CALL)
+ if(!SSshuttle.canRecall())
+ dat += "The station is currently undergoing evacuation procedures.
"
+ for(var/datum/job/prioritized_job in SSjob.prioritized_jobs)
+ if(prioritized_job.current_positions >= prioritized_job.total_positions)
+ SSjob.prioritized_jobs -= prioritized_job
+ dat += ""
+ var/column_counter = 0
+ var/free_space = 0
+ for(var/list/category in list(GLOB.command_positions) + list(GLOB.supply_positions) + list(GLOB.engineering_positions) + list(GLOB.nonhuman_positions - "pAI") + list(GLOB.civilian_positions) + list(GLOB.medical_positions) + list(GLOB.science_positions) + list(GLOB.security_positions))
+ var/cat_color = "fff" //random default
+ if(SSjob.name_occupations && SSjob.name_occupations[category[1]])
+ cat_color = SSjob.name_occupations[category[1]].selection_color //use the color of the first job in the category (the department head) as the category color
+ else
+ cat_color = SSjob.occupations[category[1]].selection_color
+ dat += ""
+ dat += "[SSjob.name_occupations[category[1]].exp_type_department] "
+
+ var/list/dept_dat = list()
+ for(var/job in category)
+ var/datum/job/job_datum = SSjob.name_occupations[job]
+ if(job_datum && IsJobUnavailable(job_datum.title, TRUE) == JOB_AVAILABLE)
+ var/command_bold = ""
+ if(job in GLOB.command_positions)
+ command_bold = " command"
+ if(job_datum in SSjob.prioritized_jobs)
+ dept_dat += "[job_datum.title] ([job_datum.current_positions]) "
+ else
+ dept_dat += "[job_datum.title] ([job_datum.current_positions]) "
+ if(!dept_dat.len)
+ dept_dat += "No positions open. "
+ dat += jointext(dept_dat, "")
+ dat += " "
+ column_counter++
+ if(free_space <=4)
+ free_space++
+ if(column_counter > 0 && (column_counter % 3 == 0))
+ dat += " "
+ if(free_space >= 5 && (free_space % 5 == 0) && (column_counter % 3 != 0))
+ free_space = 0
+ column_counter = 0
+ dat += " "
+
+ dat += "
"
+
+ var/available_ghosts = 0
+ for(var/spawner in GLOB.mob_spawners)
+ if(!LAZYLEN(spawner))
+ continue
+ var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner])
+ if(!istype(S) || !S.can_latejoin())
+ continue
+ available_ghosts++
+ break
+
+ if(!available_ghosts)
+ dat += "There are currently no open ghost spawners.
"
+ else
+ var/list/categorizedJobs = list("Ghost Role" = list(jobs = list(), titles = GLOB.mob_spawners, color = "#ffffff"))
+ for(var/spawner in GLOB.mob_spawners)
+ if(!LAZYLEN(spawner))
+ continue
+ var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner])
+ if(!istype(S) || !S.can_latejoin())
+ continue
+ categorizedJobs["Ghost Role"]["jobs"] += spawner
+
+ dat += ""
+ for(var/jobcat in categorizedJobs)
+ if(!length(categorizedJobs[jobcat]["jobs"]))
+ continue
+ var/color = categorizedJobs[jobcat]["color"]
+ dat += ""
+ dat += "[jobcat] "
+ for(var/spawner in categorizedJobs[jobcat]["jobs"])
+ dat += "[spawner] "
+
+ dat += " "
+ dat += "
"
+ dat += ""
+
+ var/datum/browser/popup = new(src, "latechoices", "Choose Profession", 720, 600)
+ popup.add_stylesheet("playeroptions", 'html/browser/playeroptions.css')
+ popup.set_content(jointext(dat, ""))
+ popup.open(FALSE) // FALSE is passed to open so that it doesn't use the onclose() proc
+
+/mob/dead/new_player/proc/create_character(transfer_after)
+ spawning = 1
+ close_spawn_windows()
+
+ var/mob/living/carbon/human/H = new(loc)
+
+ var/frn = CONFIG_GET(flag/force_random_names)
+ if(!frn)
+ frn = jobban_isbanned(src, "appearance")
+ if(QDELETED(src))
+ return
+ if(frn)
+ client.prefs.random_character()
+ client.prefs.real_name = client.prefs.pref_species.random_name(gender,1)
+ client.prefs.copy_to(H)
+ H.dna.update_dna_identity()
+ if(mind)
+ if(transfer_after)
+ mind.late_joiner = TRUE
+ mind.active = 0 //we wish to transfer the key manually
+ mind.transfer_to(H) //won't transfer key since the mind is not active
+
+ H.name = real_name
+
+ . = H
+ new_character = .
+ if(transfer_after)
+ transfer_character()
+
+/mob/dead/new_player/proc/transfer_character()
+ . = new_character
+ if(.)
+ new_character.key = key //Manually transfer the key to log them in
+ new_character.stop_sound_channel(CHANNEL_LOBBYMUSIC)
+ new_character = null
+ qdel(src)
+
+/mob/dead/new_player/proc/ViewManifest()
+ var/dat = ""
+ dat += "Crew Manifest "
+ dat += GLOB.data_core.get_manifest(OOC = 1)
+
+ src << browse(dat, "window=manifest;size=387x420;can_close=1")
+
+/mob/dead/new_player/Move()
+ return 0
+
+
+/mob/dead/new_player/proc/close_spawn_windows()
+
+ src << browse(null, "window=latechoices") //closes late choices window
+ src << browse(null, "window=playersetup") //closes the player setup window
+ src << browse(null, "window=preferences") //closes job selection
+ src << browse(null, "window=mob_occupation")
+ src << browse(null, "window=latechoices") //closes late job selection
+
+/* Used to make sure that a player has a valid job preference setup, used to knock players out of eligibility for anything if their prefs don't make sense.
+ A "valid job preference setup" in this situation means at least having one job set to low, or not having "return to lobby" enabled
+ Prevents "antag rolling" by setting antag prefs on, all jobs to never, and "return to lobby if preferences not availible"
+ Doing so would previously allow you to roll for antag, then send you back to lobby if you didn't get an antag role
+ This also does some admin notification and logging as well, as well as some extra logic to make sure things don't go wrong
+*/
+
+/mob/dead/new_player/proc/check_preferences()
+ if(!client)
+ return FALSE //Not sure how this would get run without the mob having a client, but let's just be safe.
+ if(client.prefs.joblessrole != RETURNTOLOBBY)
+ return TRUE
+ // If they have antags enabled, they're potentially doing this on purpose instead of by accident. Notify admins if so.
+ var/has_antags = FALSE
+ if(client.prefs.be_special.len > 0)
+ has_antags = TRUE
+ if(client.prefs.job_preferences.len == 0)
+ if(!ineligible_for_roles)
+ to_chat(src, "You have no jobs enabled, along with return to lobby if job is unavailable. This makes you ineligible for any round start role, please update your job preferences. ")
+ ineligible_for_roles = TRUE
+ ready = PLAYER_NOT_READY
+ if(has_antags)
+ log_admin("[src.ckey] just got booted back to lobby with no jobs, but antags enabled.")
+ message_admins("[src.ckey] just got booted back to lobby with no jobs enabled, but antag rolling enabled. Likely antag rolling abuse.")
+
+ return FALSE //This is the only case someone should actually be completely blocked from antag rolling as well
+ return TRUE
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index 994d082585..d54b8256a9 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -17,6 +17,8 @@
hair_color = random_short_color()
facial_hair_color = hair_color
eye_color = random_eye_color()
+ horn_color = "85615a"
+ wing_color = "fff"
if(!pref_species)
var/rando_race = pick(GLOB.roundstart_races)
pref_species = new rando_race()
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm b/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm
index 2f1d48cfa7..156cc304a6 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/body_markings.dm
@@ -54,6 +54,10 @@
name = "Redpanda"
icon_state = "redpanda"
+/datum/sprite_accessory/mam_body_markings/bat
+ name = "Bat"
+ icon_state = "bat"
+
/datum/sprite_accessory/mam_body_markings/bee
name = "Bee"
icon_state = "bee"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
index 1496ca030a..ca1253feb1 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/ears.dm
@@ -176,6 +176,10 @@
name = "Axolotl"
icon_state = "axolotl"
+/datum/sprite_accessory/mam_ears/bat
+ name = "Bat"
+ icon_state = "bat"
+
/datum/sprite_accessory/mam_ears/bear
name = "Bear"
icon_state = "bear"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
index 7252f85324..be2ab152a8 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/snouts.dm
@@ -194,6 +194,10 @@
name = "Mammal, Short ALT"
icon_state = "scanidalt"
+/datum/sprite_accessory/mam_snouts/scanidalt2
+ name = "Mammal, Short ALT 2"
+ icon_state = "scanidalt2"
+
/datum/sprite_accessory/mam_snouts/wolf
name = "Mammal, Thick"
icon_state = "wolf"
@@ -306,6 +310,10 @@
name = "Mammal, Short ALT (Top)"
icon_state = "fscanidalt"
+/datum/sprite_accessory/mam_snouts/fscanidalt2
+ name = "Mammal, Short ALT 2 (Top)"
+ icon_state = "fscanidalt2"
+
/datum/sprite_accessory/mam_snouts/fwolf
name = "Mammal, Thick (Top)"
icon_state = "fwolf"
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
index 6042d97247..33b174afa4 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/tails.dm
@@ -114,6 +114,26 @@
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
color_src = MATRIXED
+/datum/sprite_accessory/mam_tails/batl
+ name = "Bat (Long)"
+ icon = 'modular_citadel/icons/mob/mam_tails.dmi'
+ icon_state = "batl"
+
+/datum/sprite_accessory/mam_tails_animated/batl
+ name = "Bat (Long)"
+ icon = 'modular_citadel/icons/mob/mam_tails.dmi'
+ icon_state = "batl"
+
+/datum/sprite_accessory/mam_tails/bats
+ name = "Bat (Short)"
+ icon = 'modular_citadel/icons/mob/mam_tails.dmi'
+ icon_state = "bats"
+
+/datum/sprite_accessory/mam_tails_animated/bats
+ name = "Bat (Short)"
+ icon = 'modular_citadel/icons/mob/mam_tails.dmi'
+ icon_state = "bats"
+
/datum/sprite_accessory/tails/human/bee
name = "Bee"
icon_state = "bee"
@@ -469,6 +489,22 @@
name = "Axolotl"
icon_state = "axolotl"
+/datum/sprite_accessory/mam_tails/batl
+ name = "Bat (Long)"
+ icon_state = "batl"
+
+/datum/sprite_accessory/mam_tails_animated/batl
+ name = "Bat (Long)"
+ icon_state = "batl"
+
+/datum/sprite_accessory/mam_tails/bats
+ name = "Bat (Short)"
+ icon_state = "bats"
+
+/datum/sprite_accessory/mam_tails_animated/bats
+ name = "Bat (Short)"
+ icon_state = "bats"
+
/datum/sprite_accessory/mam_tails/bee
name = "Bee"
icon_state = "bee"
@@ -558,7 +594,7 @@
/datum/sprite_accessory/mam_tails_animated/horse
name = "Horse"
- icon_state = "Horse"
+ icon_state = "horse"
color_src = HAIR
/datum/sprite_accessory/mam_tails/husky
diff --git a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
index dc0e0222bf..46a123c6bb 100644
--- a/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
+++ b/code/modules/mob/dead/new_player/sprite_accessories/wings.dm
@@ -27,39 +27,141 @@
dimension_y = 34
locked = TRUE
+// Decorative wings
+
+/datum/sprite_accessory/deco_wings
+ icon = 'icons/mob/wings.dmi'
+ color_src = WINGCOLOR
+
+/datum/sprite_accessory/deco_wings/none
+ name = "None"
+ icon_state = "none"
+
+/datum/sprite_accessory/deco_wings/angel
+ name = "Angel"
+ icon_state = "angel"
+ color_src = 0
+ dimension_x = 46
+ center = TRUE
+ dimension_y = 34
+
+/datum/sprite_accessory/deco_wings/bat
+ name = "Bat"
+ icon_state = "bat"
+
+/datum/sprite_accessory/deco_wings/bee
+ name = "Bee"
+ icon_state = "bee"
+
+/datum/sprite_accessory/deco_wings/fairy
+ name = "Fairy"
+ icon_state = "fairy"
+
+/datum/sprite_accessory/deco_wings/feathery
+ name = "Feathery"
+ icon_state = "feathery"
+
+/datum/sprite_accessory/deco_wings/atlas
+ name = "Atlas"
+ icon_state = "atlas"
+
+/datum/sprite_accessory/deco_wings/deathhead
+ name = "Deathshead"
+ icon_state = "deathhead"
+
+/datum/sprite_accessory/deco_wings/firewatch
+ name = "Firewatch"
+ icon_state = "firewatch"
+
+/datum/sprite_accessory/deco_wings/gothic
+ name = "Gothic"
+ icon_state = "gothic"
+
+/datum/sprite_accessory/deco_wings/lovers
+ name = "Lovers"
+ icon_state = "lovers"
+
+/datum/sprite_accessory/deco_wings/luna
+ name = "Luna"
+ icon_state = "luna"
+
+/datum/sprite_accessory/deco_wings/monarch
+ name = "Monarch"
+ icon_state = "monarch"
+
+/datum/sprite_accessory/deco_wings/moonfly
+ name = "Moon Fly"
+ icon_state = "moonfly"
+
+/datum/sprite_accessory/deco_wings/plain
+ name = "Plain"
+ icon_state = "plain"
+
+/datum/sprite_accessory/deco_wings/poison
+ name = "Poison"
+ icon_state = "poison"
+
+/datum/sprite_accessory/deco_wings/punished
+ name = "Burnt Off"
+ icon_state = "punished"
+
+/datum/sprite_accessory/deco_wings/ragged
+ name = "Ragged"
+ icon_state = "ragged"
+
+/datum/sprite_accessory/deco_wings/reddish
+ name = "Reddish"
+ icon_state = "redish"
+
+/datum/sprite_accessory/deco_wings/royal
+ name = "Royal"
+ icon_state = "royal"
+
+/datum/sprite_accessory/deco_wings/snow
+ name = "Snow"
+ icon_state = "snow"
+
+/datum/sprite_accessory/deco_wings/whitefly
+ name = "White Fly"
+ icon_state = "whitefly"
+
//INSECT WINGS
/datum/sprite_accessory/insect_wings
icon = 'icons/mob/wings.dmi'
- color_src = null
+ color_src = WINGCOLOR
/datum/sprite_accessory/insect_wings/none
name = "None"
icon_state = "none"
-/datum/sprite_accessory/insect_wings/plain
- name = "Plain"
- icon_state = "plain"
+/datum/sprite_accessory/insect_wings/bat
+ name = "Bat"
+ icon_state = "bat"
-/datum/sprite_accessory/insect_wings/monarch
- name = "Monarch"
- icon_state = "monarch"
+/datum/sprite_accessory/insect_wings/bee
+ name = "Bee"
+ icon_state = "bee"
-/datum/sprite_accessory/insect_wings/luna
- name = "Luna"
- icon_state = "luna"
+/datum/sprite_accessory/insect_wings/fairy
+ name = "Fairy"
+ icon_state = "fairy"
+
+/datum/sprite_accessory/insect_wings/feathery
+ name = "Feathery"
+ icon_state = "feathery"
/datum/sprite_accessory/insect_wings/atlas
name = "Atlas"
icon_state = "atlas"
-/datum/sprite_accessory/insect_wings/reddish
- name = "Reddish"
- icon_state = "redish"
+/datum/sprite_accessory/insect_wings/deathhead
+ name = "Deathshead"
+ icon_state = "deathhead"
-/datum/sprite_accessory/insect_wings/royal
- name = "Royal"
- icon_state = "royal"
+/datum/sprite_accessory/insect_wings/firewatch
+ name = "Firewatch"
+ icon_state = "firewatch"
/datum/sprite_accessory/insect_wings/gothic
name = "Gothic"
@@ -69,76 +171,46 @@
name = "Lovers"
icon_state = "lovers"
-/datum/sprite_accessory/insect_wings/whitefly
- name = "White Fly"
- icon_state = "whitefly"
+/datum/sprite_accessory/insect_wings/luna
+ name = "Luna"
+ icon_state = "luna"
-/datum/sprite_accessory/insect_wings/punished
- name = "Burnt Off"
- icon_state = "punished"
- locked = TRUE
-
-/datum/sprite_accessory/insect_wings/firewatch
- name = "Firewatch"
- icon_state = "firewatch"
-
-/datum/sprite_accessory/insect_wings/deathhead
- name = "Deathshead"
- icon_state = "deathhead"
-
-/datum/sprite_accessory/insect_wings/poison
- name = "Poison"
- icon_state = "poison"
-
-/datum/sprite_accessory/insect_wings/ragged
- name = "Ragged"
- icon_state = "ragged"
+/datum/sprite_accessory/insect_wings/monarch
+ name = "Monarch"
+ icon_state = "monarch"
/datum/sprite_accessory/insect_wings/moonfly
name = "Moon Fly"
icon_state = "moonfly"
+/datum/sprite_accessory/insect_wings/plain
+ name = "Plain"
+ icon_state = "plain"
+
+/datum/sprite_accessory/insect_wings/poison
+ name = "Poison"
+ icon_state = "poison"
+
+/datum/sprite_accessory/insect_wings/punished
+ name = "Burnt Off"
+ icon_state = "punished"
+
+/datum/sprite_accessory/insect_wings/ragged
+ name = "Ragged"
+ icon_state = "ragged"
+
+/datum/sprite_accessory/insect_wings/reddish
+ name = "Reddish"
+ icon_state = "redish"
+
+/datum/sprite_accessory/insect_wings/royal
+ name = "Royal"
+ icon_state = "royal"
+
/datum/sprite_accessory/insect_wings/snow
name = "Snow"
icon_state = "snow"
-/datum/sprite_accessory/insect_wings/colored
- name = "Colored (Hair)"
- icon_state = "snowplain"
- color_src = HAIR
-
-/datum/sprite_accessory/insect_fluff/colored1
- name = "Colored (Primary)"
- icon_state = "snowplain"
- color_src = MUTCOLORS
-
-/datum/sprite_accessory/insect_fluff/colored2
- name = "Colored (Secondary)"
- icon_state = "snowplain"
- color_src = MUTCOLORS2
-
-/datum/sprite_accessory/insect_fluff/colored3
- name = "Colored (Tertiary)"
- icon_state = "snowplain"
- color_src = MUTCOLORS3
-
-/datum/sprite_accessory/insect_wings/bee
- name = "Bee"
- icon_state = "bee"
-
-/datum/sprite_accessory/insect_wings/bee_color
- name = "Bee (Hair colored)"
- icon_state = "bee"
- color_src = HAIR
-
-/datum/sprite_accessory/insect_wings/fairy
- name = "Fairy"
- icon_state = "fairy"
-
-/datum/sprite_accessory/insect_wings/bat
- name = "Bat"
- icon_state = "bat"
-
-/datum/sprite_accessory/insect_wings/feathery
- name = "Feathery"
- icon_state = "feathery"
+/datum/sprite_accessory/insect_wings/whitefly
+ name = "White Fly"
+ icon_state = "whitefly"
\ No newline at end of file
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index fefa032e4f..ca149a39d8 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -260,16 +260,16 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
Works together with spawning an observer, noted above.
*/
-/mob/proc/ghostize(can_reenter_corpse = 1)
- if(key)
- if(!cmptext(copytext(key,1,2),"@")) // Skip aghosts.
- stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
- var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
- SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
- ghost.can_reenter_corpse = can_reenter_corpse
- ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
- ghost.key = key
- return ghost
+/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE)
+ if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special) & COMPONENT_BLOCK_GHOSTING))
+ return //mob has no key, is an aghost or some component hijacked.
+ stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
+ var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
+ SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
+ ghost.can_reenter_corpse = can_reenter_corpse
+ ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
+ transfer_ckey(ghost, FALSE)
+ return ghost
/*
This is the proc mobs get to turn into a ghost. Forked from ghostize due to compatibility issues.
@@ -280,12 +280,15 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
+ if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
+ return
+
// CITADEL EDIT
if(istype(loc, /obj/machinery/cryopod))
- var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
- if(response != "Ghost")//darn copypaste
- return
var/obj/machinery/cryopod/C = loc
+ var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
+ if(response != "Ghost" || QDELETED(C) || QDELETED(src) || loc != C)
+ return
C.despawn_occupant()
return
// END EDIT
@@ -306,6 +309,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
set name = "Ghost"
set desc = "Relinquish your life and enter the land of the dead."
+ if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
+ return
+
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
if(response != "Ghost")
return
@@ -348,7 +354,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
client.change_view(CONFIG_GET(string/default_view))
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
- mind.current.key = key
+ transfer_ckey(mind.current, FALSE)
return 1
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE)
@@ -628,7 +634,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
to_chat(src, "Someone has taken this body while you were choosing! ")
return 0
- target.key = key
+ transfer_ckey(target, FALSE)
target.faction = list("neutral")
return 1
diff --git a/code/modules/mob/emote.dm b/code/modules/mob/emote.dm
index 625a923fe1..41d3d4e158 100644
--- a/code/modules/mob/emote.dm
+++ b/code/modules/mob/emote.dm
@@ -40,7 +40,7 @@
if(iscyborg(user) && user.has_buckled_mobs())
var/mob/living/silicon/robot/R = user
- GET_COMPONENT_FROM(riding_datum, /datum/component/riding, R)
+ var/datum/component/riding/riding_datum = R.GetComponent(/datum/component/riding)
if(riding_datum)
for(var/mob/M in R.buckled_mobs)
riding_datum.force_dismount(M)
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 9569d4826c..e77a91332e 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -158,7 +158,7 @@
//Returns if a certain item can be equipped to a certain slot.
// Currently invalid for two-handed items - call obj/item/mob_can_equip() instead.
-/mob/proc/can_equip(obj/item/I, slot, disable_warning = 0)
+/mob/proc/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
return FALSE
/mob/proc/can_put_in_hand(I, hand_index)
@@ -468,3 +468,6 @@
bodyparts += BP
hand_bodyparts[i] = BP
..() //Don't redraw hands until we have organs for them
+
+/mob/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
+ return ..() && (user == src)
diff --git a/code/modules/mob/living/blood.dm b/code/modules/mob/living/blood.dm
index ca1a961a92..757aadaea1 100644
--- a/code/modules/mob/living/blood.dm
+++ b/code/modules/mob/living/blood.dm
@@ -2,6 +2,9 @@
BLOOD SYSTEM
****************************************************/
+#define EXOTIC_BLEED_MULTIPLIER 4 //Multiplies the actually bled amount by this number for the purposes of turf reaction calculations.
+
+
/mob/living/carbon/human/proc/suppress_bloodloss(amount)
if(bleedsuppress)
return
@@ -30,6 +33,9 @@
bleed_rate = 0
return
+ if(bleed_rate <= 0)
+ bleed_rate = 0
+
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
@@ -80,6 +86,9 @@
var/obj/item/bodypart/BP = X
var/brutedamage = BP.brute_dam
+ if(BP.status == BODYPART_ROBOTIC) //for the moment, synth limbs won't bleed, but soon, my pretty.
+ continue
+
//We want an accurate reading of .len
listclearnulls(BP.embedded_objects)
temp_bleed += 0.5*BP.embedded_objects.len
@@ -87,7 +96,7 @@
if(brutedamage >= 20)
temp_bleed += (brutedamage * 0.013)
- bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
+ bleed_rate = max(bleed_rate - 0.50, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
bleed(bleed_rate)
@@ -105,9 +114,11 @@
/mob/living/carbon/human/bleed(amt)
amt *= physiology.bleed_mod
if(!(NOBLOOD in dna.species.species_traits))
- ..()
-
-
+ .=..()
+ if(dna.species.exotic_blood && .) // Do we have exotic blood, and have we left any on the ground?
+ var/datum/reagent/R = GLOB.chemical_reagents_list[get_blood_id()]
+ if(istype(R) && isturf(loc))
+ R.reaction_turf(get_turf(src), amt * EXOTIC_BLEED_MULTIPLIER)
/mob/living/proc/restore_blood()
blood_volume = initial(blood_volume)
@@ -123,16 +134,16 @@
//Gets blood from mob to a container or other mob, preserving all data in it.
/mob/living/proc/transfer_blood_to(atom/movable/AM, amount, forced)
if(!blood_volume || !AM.reagents)
- return 0
+ return FALSE
if(blood_volume < (BLOOD_VOLUME_BAD * blood_ratio) && !forced)
- return 0
+ return FALSE
if(blood_volume < amount)
amount = blood_volume
var/blood_id = get_blood_id()
if(!blood_id)
- return 0
+ return FALSE
blood_volume -= amount
@@ -141,29 +152,27 @@
if(iscarbon(AM))
var/mob/living/carbon/C = AM
if(blood_id == C.get_blood_id())//both mobs have the same blood substance
- if(blood_id == "blood") //normal blood
+ if(blood_id == "blood" || blood_id == "jellyblood") //normal blood
if(blood_data["viruses"])
for(var/thing in blood_data["viruses"])
var/datum/disease/D = thing
if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
continue
C.ForceContractDisease(D)
- if(!(blood_data["blood_type"] in get_safe_blood(C.dna.blood_type)))
- C.reagents.add_reagent("toxin", amount * 0.5)
- return 1
+ //This used to inject oof ouch results, but since we add the reagent, and the reagent causes oof ouch on mob life... why double dip?
C.blood_volume = min(C.blood_volume + round(amount, 0.1), BLOOD_VOLUME_MAXIMUM)
- return 1
+ return TRUE
AM.reagents.add_reagent(blood_id, amount, blood_data, bodytemperature)
- return 1
+ return TRUE
/mob/living/proc/get_blood_data(blood_id)
return
/mob/living/carbon/get_blood_data(blood_id)
- if(blood_id == "blood") //actual blood reagent
+ if(blood_id == "blood" || blood_id == "jellyblood") //actual blood reagent
var/blood_data = list()
//set the blood data
blood_data["donor"] = src
@@ -174,6 +183,7 @@
blood_data["viruses"] += D.Copy()
blood_data["blood_DNA"] = copytext(dna.unique_enzymes,1,0)
+ blood_data["bloodcolor"] = bloodtype_to_color(dna.blood_type)
if(disease_resistances && disease_resistances.len)
blood_data["resistances"] = disease_resistances.Copy()
var/list/temp_chem = list()
@@ -206,21 +216,6 @@
if(istype(ling))
blood_data["changeling_loudness"] = ling.loudfactor
return blood_data
- if(blood_id == "slimejelly") //Just so MKUltra works. Takes the minimum required data. Sishen is testing if this breaks stuff.
- var/blood_data = list()
- if(mind)
- blood_data["mind"] = mind
- else if(last_mind)
- blood_data["mind"] = last_mind
- if(ckey)
- blood_data["ckey"] = ckey
- else if(last_mind)
- blood_data["ckey"] = ckey(last_mind.key)
- blood_data["gender"] = gender
- blood_data["real_name"] = real_name
- return blood_data
-
-
//get the id of the substance this mob use as blood.
/mob/proc/get_blood_id()
@@ -234,12 +229,15 @@
if(!(HAS_TRAIT(src, TRAIT_NOCLONE)))
return "blood"
-/mob/living/carbon/human/get_blood_id()
- if(dna.species.exotic_blood)
+/mob/living/carbon/get_blood_id()
+ if(isjellyperson(src))
+ return "jellyblood"
+ if(dna?.species?.exotic_blood)
return dna.species.exotic_blood
else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE)))
return
- return "blood"
+ else
+ return "blood"
// This is has more potential uses, and is probably faster than the old proc.
/proc/get_safe_blood(bloodtype)
@@ -248,16 +246,21 @@
return
var/static/list/bloodtypes_safe = list(
- "A-" = list("A-", "O-"),
- "A+" = list("A-", "A+", "O-", "O+"),
- "B-" = list("B-", "O-"),
- "B+" = list("B-", "B+", "O-", "O+"),
- "AB-" = list("A-", "B-", "O-", "AB-"),
- "AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+"),
- "O-" = list("O-"),
- "O+" = list("O-", "O+"),
- "L" = list("L"),
- "U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U")
+ "A-" = list("A-", "O-", "SY"),
+ "A+" = list("A-", "A+", "O-", "O+", "SY"),
+ "B-" = list("B-", "O-", "SY"),
+ "B+" = list("B-", "B+", "O-", "O+", "SY"),
+ "AB-" = list("A-", "B-", "O-", "AB-", "SY"),
+ "AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "SY"),
+ "O-" = list("O-","SY"),
+ "O+" = list("O-", "O+","SY"),
+ "L" = list("L","SY"),
+ "U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY"),
+ "HF" = list("HF", "SY"),
+ "X*" = list("X*", "SY"),
+ "SY" = list("SY"),
+ "GEL" = list("GEL","SY"),
+ "BUG" = list("BUG", "SY")
)
var/safe = bloodtypes_safe[bloodtype]
@@ -266,7 +269,7 @@
//to add a splatter of blood or other mob liquid.
/mob/living/proc/add_splatter_floor(turf/T, small_drip)
- if(get_blood_id() != "blood")
+ if(get_blood_id() == null)
return
if(!T)
T = get_turf(src)
@@ -280,24 +283,27 @@
drop.drips++
drop.add_overlay(pick(drop.random_icon_states))
drop.transfer_mob_blood_dna(src)
+ drop.update_icon()
return
else
- temp_blood_DNA = drop.return_blood_DNA() //we transfer the dna from the drip to the splatter
+ temp_blood_DNA = list()
+ temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
qdel(drop)//the drip is replaced by a bigger splatter
else
drop = new(T, get_static_viruses())
drop.transfer_mob_blood_dna(src)
+ drop.update_icon()
return
// Find a blood decal or create a new one.
- var/obj/effect/decal/cleanable/blood/B = locate() in T
+ var/obj/effect/decal/cleanable/blood/splats/B = locate() in T
if(!B)
- B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
- if (B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
+ B = new /obj/effect/decal/cleanable/blood/splats(T, get_static_viruses())
+ if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
B.bloodiness += BLOOD_AMOUNT_PER_DECAL
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
if(temp_blood_DNA)
- B.add_blood_DNA(temp_blood_DNA)
+ B.blood_DNA |= temp_blood_DNA
/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip)
if(!(NOBLOOD in dna.species.species_traits))
@@ -306,10 +312,10 @@
/mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip)
if(!T)
T = get_turf(src)
- var/obj/effect/decal/cleanable/xenoblood/B = locate() in T.contents
+ var/obj/effect/decal/cleanable/blood/splatter/B = locate() in T.contents
if(!B)
B = new(T)
- B.add_blood_DNA(list("UNKNOWN DNA" = "X*"))
+ B.blood_DNA["UNKNOWN DNA"] = "X*"
/mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip)
if(!T)
@@ -318,6 +324,44 @@
if(!B)
B = new(T)
+/mob/living/proc/add_splash_floor(turf/T)
+ if(get_blood_id() == null)
+ return
+ if(!T)
+ T = get_turf(src)
+
+ var/list/temp_blood_DNA
+
+ // Find a blood decal or create a new one.
+ var/obj/effect/decal/cleanable/blood/B = locate() in T
+ if(!B)
+ B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
+ if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
+ B.bloodiness += BLOOD_AMOUNT_PER_DECAL
+ B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
+ src.transfer_blood_to(B, 10) //very heavy bleeding, should logically leave larger pools
+ if(temp_blood_DNA)
+ B.blood_DNA |= temp_blood_DNA
+
+/mob/living/carbon/human/add_splash_floor(turf/T)
+ if(!(NOBLOOD in dna.species.species_traits))
+ ..()
+
+/mob/living/carbon/alien/add_splash_floor(turf/T)
+ if(!T)
+ T = get_turf(src)
+ var/obj/effect/decal/cleanable/blood/splatter/B = locate() in T.contents
+ if(!B)
+ B = new(T)
+ B.blood_DNA["UNKNOWN DNA"] = "X*"
+
+/mob/living/silicon/robot/add_splash_floor(turf/T)
+ if(!T)
+ T = get_turf(src)
+ var/obj/effect/decal/cleanable/oil/B = locate() in T.contents
+ if(!B)
+ B = new(T)
+
//This is a terrible way of handling it.
/mob/living/proc/ResetBloodVol()
if(ishuman(src))
diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm
index cc11c0e8bb..d1ace36b8c 100644
--- a/code/modules/mob/living/bloodcrawl.dm
+++ b/code/modules/mob/living/bloodcrawl.dm
@@ -147,13 +147,12 @@
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
//Makes the mob have the color of the blood pool it came out of
- var/newcolor = rgb(149, 10, 10)
- if(istype(B, /obj/effect/decal/cleanable/xenoblood))
- newcolor = rgb(43, 186, 0)
+ var/newcolor = BLOOD_COLOR_HUMAN
+ if(istype(B, /obj/effect/decal/cleanable/blood/xeno))
+ newcolor = BLOOD_COLOR_XENO
add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY)
// but only for a few seconds
- spawn(30)
- remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, newcolor)
+ addtimer(CALLBACK(src, /atom/.proc/remove_atom_colour, TEMPORARY_COLOUR_PRIORITY, newcolor), 6 SECONDS)
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
if(src.notransform)
diff --git a/code/modules/mob/living/brain/MMI.dm b/code/modules/mob/living/brain/MMI.dm
index bacdc4524b..d84ba0d7a1 100644
--- a/code/modules/mob/living/brain/MMI.dm
+++ b/code/modules/mob/living/brain/MMI.dm
@@ -57,13 +57,14 @@
newbrain.brainmob = null
brainmob.forceMove(src)
brainmob.container = src
- if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death.
+ if(!(newbrain.organ_flags & ORGAN_FAILING)) // the brain organ hasn't been beaten to death.
brainmob.stat = CONSCIOUS //we manually revive the brain mob
GLOB.dead_mob_list -= brainmob
GLOB.alive_mob_list += brainmob
brainmob.reset_perspective()
brain = newbrain
+ brain.organ_flags |= ORGAN_FROZEN
name = "Man-Machine Interface: [brainmob.real_name]"
update_icon()
@@ -100,6 +101,7 @@
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
else
brain.forceMove(get_turf(src))
+ brain.organ_flags &= ~ORGAN_FROZEN
brain = null //No more brain in here
diff --git a/code/modules/mob/living/brain/brain.dm b/code/modules/mob/living/brain/brain.dm
index 97b29ca4e1..1b2944c1f6 100644
--- a/code/modules/mob/living/brain/brain.dm
+++ b/code/modules/mob/living/brain/brain.dm
@@ -10,7 +10,10 @@
/mob/living/brain/Initialize()
. = ..()
create_dna(src)
- stored_dna.initialize_dna(random_blood_type())
+ if(stored_dna.blood_type)
+ stored_dna.initialize_dna(stored_dna.blood_type)
+ else
+ stored_dna.initialize_dna(random_blood_type())
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
OB.brainmob = src
@@ -21,6 +24,8 @@
if(!stored_dna.species)
var/rando_race = pick(GLOB.roundstart_races)
stored_dna.species = new rando_race()
+ if(stored_dna.species.exotic_bloodtype)
+ stored_dna.blood_type = stored_dna.species.exotic_bloodtype
/mob/living/brain/Destroy()
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
diff --git a/code/modules/mob/living/brain/brain_item.dm b/code/modules/mob/living/brain/brain_item.dm
index dafc6cf5e0..4192c2235b 100644
--- a/code/modules/mob/living/brain/brain_item.dm
+++ b/code/modules/mob/living/brain/brain_item.dm
@@ -7,11 +7,20 @@
layer = ABOVE_MOB_LAYER
zone = BODY_ZONE_HEAD
slot = ORGAN_SLOT_BRAIN
- vital = TRUE
+ organ_flags = ORGAN_VITAL
attack_verb = list("attacked", "slapped", "whacked")
+ ///The brain's organ variables are significantly more different than the other organs, with half the decay rate for balance reasons, and twice the maxHealth
+ decay_factor = STANDARD_ORGAN_DECAY / 4 //30 minutes of decaying to result in a fully damaged brain, since a fast decay rate would be unfun gameplay-wise
+ healing_factor = STANDARD_ORGAN_HEALING / 2
+
+ maxHealth = BRAIN_DAMAGE_DEATH
+ low_threshold = 45
+ high_threshold = 120
var/mob/living/brain/brainmob = null
- var/damaged_brain = FALSE //whether the brain organ is damaged.
+ var/brain_death = FALSE //if the brainmob was intentionally killed by attacking the brain after removal, or by severe braindamage
var/decoy_override = FALSE //I apologize to the security players, and myself, who abused this, but this is going to go.
+ //two variables necessary for calculating whether we get a brain trauma or not
+ var/damage_delta = 0
var/list/datum/brain_trauma/traumas = list()
@@ -34,7 +43,7 @@
if(brainmob.mind)
brainmob.mind.transfer_to(C)
else
- C.key = brainmob.key
+ brainmob.transfer_ckey(C)
QDEL_NULL(brainmob)
@@ -90,22 +99,89 @@
if(brainmob)
O.attack(brainmob, user) //Oh noooeeeee
-/obj/item/organ/brain/examine(mob/user)
- ..()
+ if(istype(O, /obj/item/organ_storage)) //BUG_PROBABLE_CAUSE
+ return //Borg organ bags shouldn't be killing brains
- if(brainmob)
- if(brainmob.client)
- if(brainmob.health <= HEALTH_THRESHOLD_DEAD)
- to_chat(user, "It's lifeless and severely damaged.")
+ if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent("neurine")) //Neurine fixes dead brains
+ . = TRUE //don't do attack animation.
+ var/cached_Bdamage = brainmob?.health
+ var/datum/reagent/medicine/neurine/N = reagents.has_reagent("neurine")
+ var/datum/reagent/medicine/mannitol/M1 = reagents.has_reagent("mannitol")
+
+ if(O.reagents.has_reagent("mannitol"))//Just a quick way to bolster the effects if someone mixes up a batch.
+ N.volume *= (M1.volume*0.5)
+
+ if(!O.reagents.has_reagent("neurine", 10))
+ to_chat(user, "There's not enough neurine in [O] to restore [src]! ")
+ return
+
+ user.visible_message("[user] starts to pour the contents of [O] onto [src]. ", "You start to slowly pour the contents of [O] onto [src]. ")
+ if(!do_after(user, 60, TRUE, src))
+ to_chat(user, "You failed to pour [O] onto [src]! ")
+ return
+
+ user.visible_message("[user] pours the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink. ", "You pour the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink. ")
+ setOrganDamage((damage - (0.10 * maxHealth)*(N.volume/10))) //heals a small amount, and by using "setorgandamage", we clear the failing variable if that was up
+ O.reagents.clear_reagents()
+
+ if(cached_Bdamage <= HEALTH_THRESHOLD_DEAD) //Fixing dead brains yeilds a trauma
+ if((cached_Bdamage <= HEALTH_THRESHOLD_DEAD) && (brainmob.health > HEALTH_THRESHOLD_DEAD))
+ if(prob(80))
+ gain_trauma_type(BRAIN_TRAUMA_MILD)
+ else if(prob(50))
+ gain_trauma_type(BRAIN_TRAUMA_SEVERE)
+ else
+ gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
+ return
+
+ if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent("mannitol")) //attempt to heal the brain
+ . = TRUE //don't do attack animation.
+ var/datum/reagent/medicine/mannitol/M = reagents.has_reagent("mannitol")
+ if(brain_death || brainmob?.health <= HEALTH_THRESHOLD_DEAD) //if the brain is fucked anyway, do nothing
+ to_chat(user, "[src] is far too damaged, you'll have to use neurine on it! ")
+ return
+
+ if(!O.reagents.has_reagent("mannitol", 10))
+ to_chat(user, "There's not enough mannitol in [O] to restore [src]! ")
+ return
+
+ user.visible_message("[user] starts to pour the contents of [O] onto [src]. ", "You start to slowly pour the contents of [O] onto [src]. ")
+ if(!do_after(user, 60, TRUE, src))
+ to_chat(user, "You failed to pour [O] onto [src]! ")
+ return
+
+ user.visible_message("[user] pours the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink. ", "You pour the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink. ")
+ setOrganDamage((damage - (0.05 * maxHealth)*(M.volume/10))) //heals a small amount, and by using "setorgandamage", we clear the failing variable if that was up
+ O.reagents.clear_reagents()
+ return
+
+
+
+/obj/item/organ/brain/examine(mob/user)//BUG_PROBABLE_CAUSE to_chats changed to . +=
+ . = ..()
+
+ if(user.suiciding)
+ . += "It's started turning slightly grey. They must not have been able to handle the stress of it all. "
+ else if(brainmob)
+ if(brainmob.get_ghost(FALSE, TRUE))
+ if(brain_death || brainmob.health <= HEALTH_THRESHOLD_DEAD)
+ . += "It's lifeless and severely damaged, only the strongest of chems will save it. "
+ else if(organ_flags & ORGAN_FAILING)
+ . += "It seems to still have a bit of energy within it, but it's rather damaged... You may be able to restore it with some mannitol . "
else
- to_chat(user, "You can feel the small spark of life still left in this one.")
+ . += "You can feel the small spark of life still left in this one. "
+ else if(organ_flags & ORGAN_FAILING)
+ . += "It seems particularly lifeless and is rather damaged... You may be able to restore it with some mannitol incase it becomes functional again later. "
else
- to_chat(user, "This one seems particularly lifeless. Perhaps it will regain some of its luster later.")
+ . += "This one seems particularly lifeless. Perhaps it will regain some of its luster later. "
else
if(decoy_override)
- to_chat(user, "This one seems particularly lifeless. Perhaps it will regain some of its luster later.")
+ if(organ_flags & ORGAN_FAILING)
+ . += "It seems particularly lifeless and is rather damaged... You may be able to restore it with some mannitol incase it becomes functional again later. "
+ else
+ . += "This one seems particularly lifeless. Perhaps it will regain some of its luster later. "
else
- to_chat(user, "This one is completely devoid of life.")
+ . += "This one is completely devoid of life. "
/obj/item/organ/brain/attack(mob/living/carbon/C, mob/user)
if(!istype(C))
@@ -141,7 +217,7 @@
Insert(C)
else
..()
-
+/* TO BE REMOVED, KEPT IN CASE OF BUGS
/obj/item/organ/brain/proc/get_brain_damage()
var/brain_damage_threshold = max_integrity * BRAIN_DAMAGE_INTEGRITY_MULTIPLIER
var/offset_integrity = obj_integrity - (max_integrity - brain_damage_threshold)
@@ -165,6 +241,56 @@
else if(adjusted_amount <= -DAMAGE_PRECISION)
obj_integrity = min(max_integrity, obj_integrity-adjusted_amount)
. = adjusted_amount
+*/
+
+/obj/item/organ/brain/on_life()
+ if(damage >= BRAIN_DAMAGE_DEATH) //rip
+ to_chat(owner, "The last spark of life in your brain fizzles out... ")
+ owner.death()
+ brain_death = TRUE
+ return
+ ..()
+
+/obj/item/organ/brain/on_death()
+ if(damage <= BRAIN_DAMAGE_DEATH) //rip
+ brain_death = FALSE
+ ..()
+
+
+/obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth)
+ ..()
+
+
+/obj/item/organ/brain/check_damage_thresholds(mob/M)
+ . = ..()
+ //if we're not more injured than before, return without gambling for a trauma
+ if(damage <= prev_damage)
+ return
+ damage_delta = damage - prev_damage
+ if(damage > BRAIN_DAMAGE_MILD)
+ if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_MILD)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% //learn how to do your bloody math properly goddamnit
+ gain_trauma_type(BRAIN_TRAUMA_MILD)
+ if(damage > BRAIN_DAMAGE_SEVERE)
+ if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_SEVERE)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1%
+ if(prob(20))
+ gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
+ else
+ gain_trauma_type(BRAIN_TRAUMA_SEVERE)
+
+ if (owner)
+ if(owner.stat < UNCONSCIOUS) //conscious or soft-crit
+ var/brain_message
+ if(prev_damage < BRAIN_DAMAGE_MILD && damage >= BRAIN_DAMAGE_MILD)
+ brain_message = "You feel lightheaded. "
+ else if(prev_damage < BRAIN_DAMAGE_SEVERE && damage >= BRAIN_DAMAGE_SEVERE)
+ brain_message = "You feel less in control of your thoughts. "
+ else if(prev_damage < (BRAIN_DAMAGE_DEATH - 20) && damage >= (BRAIN_DAMAGE_DEATH - 20))
+ brain_message = "You can feel your mind flickering on and off... "
+
+ if(.)
+ . += "\n[brain_message]"
+ else
+ return brain_message
/obj/item/organ/brain/Destroy() //copypasted from MMIs.
if(brainmob)
@@ -200,6 +326,10 @@
return FALSE
if(!resilience)
resilience = initial(trauma.resilience)
+ if(!owner)
+ return FALSE
+ if(owner.stat == DEAD)
+ return FALSE
var/resilience_tier_count = 0
for(var/X in traumas)
diff --git a/code/modules/mob/living/brain/life.dm b/code/modules/mob/living/brain/life.dm
index 786bb0b55c..51be1f6971 100644
--- a/code/modules/mob/living/brain/life.dm
+++ b/code/modules/mob/living/brain/life.dm
@@ -20,7 +20,7 @@
else if(istype(loc, /obj/item/organ/brain))
BR = loc
if(BR)
- BR.damaged_brain = 1 //beaten to a pulp
+ BR.brain_death = TRUE
/mob/living/brain/proc/handle_emp_damage()
if(emp_damage)
diff --git a/code/modules/mob/living/brain/posibrain.dm b/code/modules/mob/living/brain/posibrain.dm
index 9e0bb0428b..8a70ccc4cb 100644
--- a/code/modules/mob/living/brain/posibrain.dm
+++ b/code/modules/mob/living/brain/posibrain.dm
@@ -92,6 +92,17 @@ GLOBAL_VAR(posibrain_notify_cooldown)
if(posi_ask == "No" || QDELETED(src))
return
transfer_personality(user)
+ latejoin_remove()
+
+/obj/item/mmi/posibrain/Destroy()
+ latejoin_remove()
+ return ..()
+
+/obj/item/mmi/posibrain/proc/latejoin_remove()
+ GLOB.poi_list -= src
+ LAZYREMOVE(GLOB.mob_spawners[name], src)
+ if(!LAZYLEN(GLOB.mob_spawners[name]))
+ GLOB.mob_spawners -= name
/obj/item/mmi/posibrain/transfer_identity(mob/living/carbon/C)
name = "[initial(name)] ([C])"
@@ -163,6 +174,8 @@ GLOBAL_VAR(posibrain_notify_cooldown)
brainmob.container = src
if(autoping)
ping_ghosts("created", TRUE)
+ GLOB.poi_list |= src
+ LAZYADD(GLOB.mob_spawners[name], src)
/obj/item/mmi/posibrain/attackby(obj/item/O, mob/user)
return
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index c8ece3f656..3ad7acfcdc 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -20,7 +20,7 @@
var/heat_protection = 0.5
var/leaping = 0
- gib_type = /obj/effect/decal/cleanable/xenoblood/xgibs
+ gib_type = /obj/effect/decal/cleanable/blood/gibs/xeno
unique_name = 1
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
diff --git a/code/modules/mob/living/carbon/alien/death.dm b/code/modules/mob/living/carbon/alien/death.dm
index ce2b4401e9..77300e1435 100644
--- a/code/modules/mob/living/carbon/alien/death.dm
+++ b/code/modules/mob/living/carbon/alien/death.dm
@@ -2,7 +2,7 @@
if(with_bodyparts)
new /obj/effect/gibspawner/xeno(drop_location())
else
- new /obj/effect/gibspawner/xenobodypartless(drop_location())
+ new /obj/effect/gibspawner/xeno/bodypartless(drop_location())
/mob/living/carbon/alien/gib_animation()
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-a")
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index 323bd408cf..ef6a372f9e 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -95,8 +95,14 @@ Doesn't work on other aliens/AI.*/
var/mob/living/M = input("Select who to whisper to:","Whisper to?",null) as null|mob in options
if(!M)
return 0
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled. ")
+ return FALSE
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
if(msg)
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(user, "As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled. ")
+ return
log_directed_talk(user, M, msg, LOG_SAY, tag="alien whisper")
to_chat(M, "You hear a strange, alien voice in your head... [msg]")
to_chat(user, "You said: \"[msg]\" to [M] ")
diff --git a/code/modules/mob/living/carbon/alien/larva/death.dm b/code/modules/mob/living/carbon/alien/larva/death.dm
index e16be71ccf..e7cf70f441 100644
--- a/code/modules/mob/living/carbon/alien/larva/death.dm
+++ b/code/modules/mob/living/carbon/alien/larva/death.dm
@@ -10,7 +10,7 @@
if(with_bodyparts)
new /obj/effect/gibspawner/larva(drop_location())
else
- new /obj/effect/gibspawner/larvabodypartless(drop_location())
+ new /obj/effect/gibspawner/larva/bodypartless(drop_location())
/mob/living/carbon/alien/larva/gib_animation()
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-l")
diff --git a/code/modules/mob/living/carbon/alien/organs.dm b/code/modules/mob/living/carbon/alien/organs.dm
index 155f203708..7b6962794a 100644
--- a/code/modules/mob/living/carbon/alien/organs.dm
+++ b/code/modules/mob/living/carbon/alien/organs.dm
@@ -1,6 +1,7 @@
/obj/item/organ/alien
icon_state = "xgibmid2"
var/list/alien_powers = list()
+ organ_flags = ORGAN_NO_SPOIL
/obj/item/organ/alien/Initialize()
. = ..()
@@ -88,6 +89,8 @@
owner.adjustFireLoss(-heal_amt)
owner.adjustOxyLoss(-heal_amt)
owner.adjustCloneLoss(-heal_amt)
+ if(owner.blood_volume && (owner.blood_volume < BLOOD_VOLUME_NORMAL))
+ owner.blood_volume += 5
else
owner.adjustPlasma(plasma_rate * 0.1)
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
index 1574305a83..0bfd23cbff 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
@@ -22,6 +22,7 @@
return S
/obj/item/organ/body_egg/alien_embryo/on_life()
+ . = ..()
switch(stage)
if(2, 3)
if(prob(2))
@@ -86,7 +87,7 @@
var/atom/xeno_loc = get_turf(owner)
var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc)
- new_xeno.key = ghost.key
+ ghost.transfer_ckey(new_xeno, FALSE)
SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention
new_xeno.canmove = 0 //so we don't move during the bursting animation
new_xeno.notransform = 1
@@ -110,7 +111,7 @@
else //When it is removed via surgery at a late stage, rather than forced.
new_xeno.visible_message("[new_xeno] wriggles out of [owner]! ", "You exit [owner], your previous host. ")
owner.adjustBruteLoss(40)
- owner.cut_overlay(overlay)
+ owner.cut_overlay(overlay)
qdel(src)
@@ -118,19 +119,19 @@
Proc: AddInfectionImages(C)
Des: Adds the infection image to all aliens for this embryo
----------------------------------------*/
-/obj/item/organ/body_egg/alien_embryo/AddInfectionImages()
+/obj/item/organ/body_egg/alien_embryo/AddInfectionImages(mob/living/carbon/C)
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
if(alien.client)
- var/I = image('icons/mob/alien.dmi', loc = owner, icon_state = "infected[stage]")
+ var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
alien.client.images += I
/*----------------------------------------
Proc: RemoveInfectionImage(C)
Des: Removes all images from the mob infected by this embryo
----------------------------------------*/
-/obj/item/organ/body_egg/alien_embryo/RemoveInfectionImages()
+/obj/item/organ/body_egg/alien_embryo/RemoveInfectionImages(mob/living/carbon/C)
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
if(alien.client)
for(var/image/I in alien.client.images)
- if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == owner)
+ if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == C)
qdel(I)
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 1d070489e7..6d52a5c01b 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -585,7 +585,7 @@
if(!isnull(E.lighting_alpha))
lighting_alpha = E.lighting_alpha
- if(client.eye != src)
+ if(client.eye && client.eye != src)
var/atom/A = client.eye
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
return
@@ -819,7 +819,7 @@
reagents.clear_reagents()
var/obj/item/organ/brain/B = getorgan(/obj/item/organ/brain)
if(B)
- B.damaged_brain = FALSE
+ B.brain_death = FALSE
for(var/thing in diseases)
var/datum/disease/D = thing
if(D.severity != DISEASE_SEVERITY_POSITIVE)
@@ -905,7 +905,7 @@
/mob/living/carbon/do_after_coefficent()
. = ..()
- GET_COMPONENT_FROM(mood, /datum/component/mood, src) //Currently, only carbons or higher use mood, move this once that changes.
+ var/datum/component/mood/mood = src.GetComponent(/datum/component/mood) //Currently, only carbons or higher use mood, move this once that changes.
if(mood)
switch(mood.sanity) //Alters do_after delay based on how sane you are
if(SANITY_INSANE to SANITY_DISTURBED)
@@ -947,7 +947,7 @@
return TRUE
if(HAS_TRAIT(src, TRAIT_DUMB))
return TRUE
- GET_COMPONENT_FROM(mood, /datum/component/mood, src)
+ var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood)
if(mood.sanity < SANITY_UNSTABLE)
return TRUE
diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm
index 57483f64e7..b0e9b808df 100644
--- a/code/modules/mob/living/carbon/carbon_defense.dm
+++ b/code/modules/mob/living/carbon/carbon_defense.dm
@@ -287,7 +287,7 @@
"You give [H] a pat on the head to make [p_them()] feel better! ")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if (mood.sanity >= SANITY_GREAT)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
else if (mood.sanity >= SANITY_DISTURBED)
@@ -322,7 +322,7 @@
"You hug [src] to make [p_them()] feel better! ")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if (mood.sanity >= SANITY_GREAT)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
else if (mood.sanity >= SANITY_DISTURBED)
@@ -405,16 +405,16 @@
if(istype(ears) && (deafen_pwr || damage_pwr))
var/ear_damage = damage_pwr * effect_amount
- var/deaf = max(ears.deaf, deafen_pwr * effect_amount)
+ var/deaf = deafen_pwr * effect_amount
adjustEarDamage(ear_damage,deaf)
- if(ears.ear_damage >= 15)
+ if(ears.damage >= 15)
to_chat(src, "Your ears start to ring badly! ")
- if(prob(ears.ear_damage - 5))
+ if(prob(ears.damage - 5))
to_chat(src, "You can't hear anything! ")
- ears.ear_damage = min(ears.ear_damage, UNHEALING_EAR_DAMAGE)
+ ears.damage = min(ears.damage, ears.maxHealth)
// you need earmuffs, inacusiate, or replacement
- else if(ears.ear_damage >= 5)
+ else if(ears.damage >= 5)
to_chat(src, "Your ears start to ring! ")
SEND_SOUND(src, sound('sound/weapons/flash_ring.ogg',0,1,0,250))
return effect_amount //how soundbanged we are
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index 794194b3a1..a1184613fe 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -2,7 +2,7 @@
gender = MALE
pressure_resistance = 15
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
- hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD)
+ hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,GLAND_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD,RAD_HUD)
has_limbs = 1
held_items = list(null, null)
var/list/stomach_contents = list()
@@ -49,6 +49,7 @@
//Gets filled up in create_bodyparts()
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
+ var/list/leg_bodyparts = list()
var/icon_render_key = ""
var/static/list/limb_icon_cache = list()
diff --git a/code/modules/mob/living/carbon/carbon_movement.dm b/code/modules/mob/living/carbon/carbon_movement.dm
index 8e6c888c40..155b0fc7de 100644
--- a/code/modules/mob/living/carbon/carbon_movement.dm
+++ b/code/modules/mob/living/carbon/carbon_movement.dm
@@ -36,7 +36,7 @@
/mob/living/carbon/Move(NewLoc, direct)
. = ..()
- if(. && mob_has_gravity()) //floating is easy
+ if(. && (movement_type & FLOATING)) //floating is easy
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
else if(nutrition && stat != DEAD)
diff --git a/code/modules/mob/living/carbon/damage_procs.dm b/code/modules/mob/living/carbon/damage_procs.dm
index 749ae3b5b0..7d1e5320fc 100644
--- a/code/modules/mob/living/carbon/damage_procs.dm
+++ b/code/modules/mob/living/carbon/damage_procs.dm
@@ -1,8 +1,8 @@
-/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE)
+/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
- if(hit_percent <= 0)
+ if(!forced && hit_percent <= 0)
return 0
var/obj/item/bodypart/BP = null
@@ -15,39 +15,39 @@
if(!BP)
BP = bodyparts[1]
+ var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
if(BP)
- if(damage > 0 ? BP.receive_damage(damage * hit_percent, 0) : BP.heal_damage(abs(damage * hit_percent), 0))
+ if(damage > 0 ? BP.receive_damage(damage_amount) : BP.heal_damage(abs(damage_amount), 0))
update_damage_overlays()
else //no bodypart, we deal damage with a more general method.
- adjustBruteLoss(damage * hit_percent)
+ adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
if(BP)
- if(damage > 0 ? BP.receive_damage(0, damage * hit_percent) : BP.heal_damage(0, abs(damage * hit_percent)))
+ if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
update_damage_overlays()
else
- adjustFireLoss(damage * hit_percent)
+ adjustFireLoss(damage_amount, forced = forced)
if(TOX)
- adjustToxLoss(damage * hit_percent)
+ adjustToxLoss(damage_amount, forced = forced)
if(OXY)
- adjustOxyLoss(damage * hit_percent)
+ adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
- adjustCloneLoss(damage * hit_percent)
+ adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
if(BP)
- if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent) : BP.heal_damage(0, 0, abs(damage * hit_percent)))
+ if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage_amount)))
update_damage_overlays()
else
- adjustStaminaLoss(damage * hit_percent)
- if(BRAIN)
- adjustBrainLoss(damage * hit_percent)
+ adjustStaminaLoss(damage_amount, forced = forced)
//citadel code
if(AROUSAL)
- adjustArousalLoss(damage * hit_percent)
+ adjustArousalLoss(damage_amount, forced = forced)
return TRUE
+
//These procs fetch a cumulative total damage from all bodyparts
/mob/living/carbon/getBruteLoss()
var/amount = 0
@@ -86,7 +86,7 @@
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
amount = -amount
if(amount > 0)
- blood_volume -= 5*amount
+ blood_volume -= 3*amount // x5 is too much, x3 should be still penalizing enough.
else
blood_volume -= amount
return ..()
@@ -113,6 +113,51 @@
return
adjustStaminaLoss(diff, updating, forced)
+/** adjustOrganLoss
+ * inputs: slot (organ slot, like ORGAN_SLOT_HEART), amount (damage to be done), and maximum (currently an arbitrarily large number, can be set so as to limit damage)
+ * outputs:
+ * description: If an organ exists in the slot requested, and we are capable of taking damage (we don't have GODMODE on), call the damage proc on that organ.
+ */
+/mob/living/carbon/adjustOrganLoss(slot, amount, maximum)
+ var/obj/item/organ/O = getorganslot(slot)
+ if(O && !(status_flags & GODMODE))
+ if(!maximum)
+ maximum = O.maxHealth
+ O.applyOrganDamage(amount, maximum)
+ O.onDamage(amount, maximum)
+
+/** setOrganLoss
+ * inputs: slot (organ slot, like ORGAN_SLOT_HEART), amount(damage to be set to)
+ * outputs:
+ * description: If an organ exists in the slot requested, and we are capable of taking damage (we don't have GODMODE on), call the set damage proc on that organ, which can
+ * set or clear the failing variable on that organ, making it either cease or start functions again, unlike adjustOrganLoss.
+ */
+/mob/living/carbon/setOrganLoss(slot, amount)
+ var/obj/item/organ/O = getorganslot(slot)
+ if(O && !(status_flags & GODMODE))
+ O.setOrganDamage(amount)
+ O.onSetDamage(amount)
+
+/** getOrganLoss
+ * inputs: slot (organ slot, like ORGAN_SLOT_HEART)
+ * outputs: organ damage
+ * description: If an organ exists in the slot requested, return the amount of damage that organ has
+ */
+/mob/living/carbon/getOrganLoss(slot)
+ var/obj/item/organ/O = getorganslot(slot)
+ if(O)
+ return O.damage
+
+/mob/living/carbon/proc/adjustAllOrganLoss(amount, maximum)
+ for(var/obj/item/organ/O in internal_organs)
+ if(O && !(status_flags & GODMODE))
+ continue
+ if(!maximum)
+ maximum = O.maxHealth
+ O.applyOrganDamage(amount, maximum)
+ O.onDamage(amount, maximum)
+
+
////////////////////////////////////////////
//Returns a list of damaged bodyparts
@@ -213,24 +258,25 @@
update_damage_overlays()
update_stamina()
-/mob/living/carbon/getBrainLoss()
+/* TO_REMOVE
+/mob/living/carbon/getOrganLoss(ORGAN_SLOT_BRAIN)
. = 0
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(B)
. = B.get_brain_damage()
//Some sources of brain damage shouldn't be deadly
-/mob/living/carbon/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH)
+/mob/living/carbon/adjustOrganLoss(ORGAN_SLOT_BRAIN, amount, maximum = BRAIN_DAMAGE_DEATH)
if(status_flags & GODMODE)
return FALSE
- var/prev_brainloss = getBrainLoss()
+ var/prev_brainloss = getOrganLoss(ORGAN_SLOT_BRAIN)
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
if(!B)
return
B.adjust_brain_damage(amount, maximum)
if(amount <= 0) //cut this early
return
- var/brainloss = getBrainLoss()
+ var/brainloss = getOrganLoss(ORGAN_SLOT_BRAIN)
if(brainloss > BRAIN_DAMAGE_MILD)
if(prob(amount * ((2 * (100 + brainloss - BRAIN_DAMAGE_MILD)) / 100))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 2%
gain_trauma_type(BRAIN_TRAUMA_MILD)
@@ -253,3 +299,4 @@
if(B)
var/adjusted_amount = amount - B.get_brain_damage()
B.adjust_brain_damage(adjusted_amount, null)
+*/
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 22da46346c..5634d21775 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -91,8 +91,9 @@
if(combatmode)
msg += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]\n"
+ msg += common_trait_examine()
- GET_COMPONENT_FROM(mood, /datum/component/mood, src)
+ var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood)
switch(mood.shown_mood)
if(-INFINITY to MOOD_LEVEL_SAD4)
diff --git a/code/modules/mob/living/carbon/human/damage_procs.dm b/code/modules/mob/living/carbon/human/damage_procs.dm
index 7641408529..9f6a572fc8 100644
--- a/code/modules/mob/living/carbon/human/damage_procs.dm
+++ b/code/modules/mob/living/carbon/human/damage_procs.dm
@@ -1,5 +1,5 @@
-/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
+/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
// depending on the species, it will run the corresponding apply_damage code there
- return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
+ return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced)
diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm
index 64b75bc801..b0c3f61eec 100644
--- a/code/modules/mob/living/carbon/human/death.dm
+++ b/code/modules/mob/living/carbon/human/death.dm
@@ -5,10 +5,35 @@
new /obj/effect/temp_visual/dust_animation(loc, "dust-h")
/mob/living/carbon/human/spawn_gibs(with_bodyparts)
- if(with_bodyparts)
- new /obj/effect/gibspawner/human(drop_location(), dna, get_static_viruses())
+ if(isjellyperson(src))
+ if(with_bodyparts)
+ new /obj/effect/gibspawner/slime(drop_location(), dna, get_static_viruses())
+ else
+ new /obj/effect/gibspawner/slime/bodypartless(drop_location(), dna, get_static_viruses())
+
+ if(isipcperson(src))
+ if(with_bodyparts)
+ new /obj/effect/gibspawner/ipc(drop_location(), dna, get_static_viruses())
+ else
+ new /obj/effect/gibspawner/ipc/bodypartless(drop_location(), dna, get_static_viruses())
+
+ if(isxenoperson(src))
+ if(with_bodyparts)
+ new /obj/effect/gibspawner/xeno/xenoperson(drop_location(), dna, get_static_viruses())
+ else
+ new /obj/effect/gibspawner/xeno/xenoperson/bodypartless(drop_location(), dna, get_static_viruses())
+
+ if(islizard(src))
+ if(with_bodyparts)
+ new /obj/effect/gibspawner/lizard(drop_location(), dna, get_static_viruses())
+ else
+ new /obj/effect/gibspawner/lizard/bodypartless(drop_location(), dna, get_static_viruses())
+
else
- new /obj/effect/gibspawner/humanbodypartless(drop_location(), dna, get_static_viruses())
+ if(with_bodyparts)
+ new /obj/effect/gibspawner/human(drop_location(), dna, get_static_viruses())
+ else
+ new /obj/effect/gibspawner/human/bodypartless(drop_location(), dna, get_static_viruses())
/mob/living/carbon/human/spawn_dust(just_ash = FALSE)
if(just_ash)
diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm
index 3406d29b3a..6da188dd2d 100644
--- a/code/modules/mob/living/carbon/human/dummy.dm
+++ b/code/modules/mob/living/carbon/human/dummy.dm
@@ -4,6 +4,7 @@
status_flags = GODMODE|CANPUSH
mouse_drag_pointer = MOUSE_INACTIVE_POINTER
var/in_use = FALSE
+ no_vore = TRUE
INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index 5b224444e0..7b0fb74f44 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -1,4 +1,4 @@
-/mob/living/carbon/human/examine(mob/user) //User is the person being examined
+/mob/living/carbon/human/examine(mob/user)
//this is very slightly better than it was because you can use it more places. still can't do \his[src] though.
var/t_He = p_they(TRUE)
var/t_His = p_their(TRUE)
@@ -45,7 +45,7 @@
if(wear_suit)
msg += "[t_He] [t_is] wearing [wear_suit.get_examine_string(user)].\n"
//suit/armor storage
- if(s_store)
+ if(s_store && !(SLOT_S_STORE in obscured))
msg += "[t_He] [t_is] carrying [s_store.get_examine_string(user)] on [t_his] [wear_suit.name].\n"
//back
if(back)
@@ -56,11 +56,10 @@
if(!(I.item_flags & ABSTRACT))
msg += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
- GET_COMPONENT(FR, /datum/component/forensics)
//gloves
if(gloves && !(SLOT_GLOVES in obscured))
msg += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands.\n"
- else if(FR && length(FR.blood_DNA))
+ else if(length(blood_DNA))
var/hand_number = get_num_arms(FALSE)
if(hand_number)
msg += "[t_He] [t_has] [hand_number > 1 ? "" : "a"] blood-stained hand[hand_number > 1 ? "s" : ""]! \n"
@@ -86,7 +85,7 @@
if(wear_mask && !(SLOT_WEAR_MASK in obscured))
msg += "[t_He] [t_has] [wear_mask.get_examine_string(user)] on [t_his] face.\n"
- if (wear_neck && !(SLOT_NECK in obscured))
+ if(wear_neck && !(SLOT_NECK in obscured))
msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
//eyes
@@ -152,7 +151,7 @@
var/temp = getBruteLoss() //no need to calculate each of these twice
- msg += ""
+ msg += "" //Everything below gets this span
var/list/missing = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
var/list/disabled = list()
@@ -297,7 +296,7 @@
msg += "[t_He] seem[p_s()] winded.\n"
if (getToxLoss() >= 10)
msg += "[t_He] seem[p_s()] sickly.\n"
- GET_COMPONENT_FROM(mood, /datum/component/mood, src)
+ var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
if(mood.sanity <= SANITY_DISTURBED)
msg += "[t_He] seem[p_s()] distressed.\n"
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empath", /datum/mood_event/sad_empath, src)
@@ -335,6 +334,8 @@
if(digitalcamo)
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
+ msg += common_trait_examine()
+
var/traitstring = get_trait_string()
if(ishuman(user))
var/mob/living/carbon/human/H = user
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 85dfe66725..a737844f10 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -32,7 +32,7 @@
if(CONFIG_GET(flag/disable_stambuffer))
togglesprint()
- AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
+ RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /mob/living/carbon/human/clean_blood)
/mob/living/carbon/human/ComponentInitialize()
@@ -488,7 +488,7 @@
var/counter = 1
while(R.fields[text("com_[]", counter)])
counter++
- R.fields[text("com_[]", counter)] = text("Made by [] on [] [], [] []", allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
+ R.fields[text("com_[]", counter)] = text("Made by [] on [] [], [] []", allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
to_chat(usr, "Successfully added comment. ")
return
to_chat(usr, "Unable to locate a data core entry for this person. ")
@@ -689,16 +689,17 @@
if(..())
dropItemToGround(I)
-/mob/living/carbon/human/proc/clean_blood(datum/source, strength)
- if(strength < CLEAN_STRENGTH_BLOOD)
- return
- if(gloves)
- if(SEND_SIGNAL(gloves, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
- update_inv_gloves()
+/mob/living/carbon/human/clean_blood()
+ var/mob/living/carbon/human/H = src
+ if(H.gloves)
+ if(H.gloves.clean_blood())
+ H.update_inv_gloves()
else
- if(bloody_hands)
- bloody_hands = 0
- update_inv_gloves()
+ ..() // Clear the Blood_DNA list
+ if(H.bloody_hands)
+ H.bloody_hands = 0
+ H.update_inv_gloves()
+ update_icons() //apply the now updated overlays to the mob
/mob/living/carbon/human/wash_cream()
if(creamed) //clean both to prevent a rare bug
@@ -865,7 +866,7 @@
piggyback(target)
return
//If you dragged them to you and you're aggressively grabbing try to fireman carry them
- else if(user != target && can_be_firemanned(target))
+ else if(user != target)
fireman_carry(target)
return
. = ..()
@@ -945,7 +946,7 @@
return FALSE
/mob/living/carbon/human/proc/clear_shove_slowdown()
- remove_movespeed_modifier(SHOVE_SLOWDOWN_ID)
+ remove_movespeed_modifier(MOVESPEED_ID_SHOVE)
var/active_item = get_active_held_item()
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
visible_message("[src.name] regains their grip on \the [active_item]! ", "You regain your grip on \the [active_item] ", null, COMBAT_MESSAGE_RANGE)
@@ -1104,3 +1105,18 @@
/mob/living/carbon/human/species/zombie/krokodil_addict
race = /datum/species/krokodil_addict
+
+/mob/living/carbon/human/species/mammal
+ race = /datum/species/mammal
+
+/mob/living/carbon/human/species/insect
+ race = /datum/species/insect
+
+/mob/living/carbon/human/species/xeno
+ race = /datum/species/xeno
+
+/mob/living/carbon/human/species/ipc
+ race = /datum/species/ipc
+
+/mob/living/carbon/human/species/roundstartslime
+ race = /datum/species/jelly/roundstartslime
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 5af295a5dd..a44779e05e 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -751,9 +751,54 @@
if(0 to NUTRITION_LEVEL_STARVING)
to_send += "You're starving! \n"
+
+ //TODO: Convert these messages into vague messages, thereby encouraging actual dignosis.
+ //Compiles then shows the list of damaged organs and broken organs
+ var/list/broken = list()
+ var/list/damaged = list()
+ var/broken_message
+ var/damaged_message
+ var/broken_plural
+ var/damaged_plural
+ //Sets organs into their proper list
+ for(var/O in internal_organs)
+ var/obj/item/organ/organ = O
+ if(organ.organ_flags & ORGAN_FAILING)
+ if(broken.len)
+ broken += ", "
+ broken += organ.name
+ else if(organ.damage > organ.low_threshold)
+ if(damaged.len)
+ damaged += ", "
+ damaged += organ.name
+ //Checks to enforce proper grammar, inserts words as necessary into the list
+ if(broken.len)
+ if(broken.len > 1)
+ broken.Insert(broken.len, "and ")
+ broken_plural = TRUE
+ else
+ var/holder = broken[1] //our one and only element
+ if(holder[lentext(holder)] == "s")
+ broken_plural = TRUE
+ //Put the items in that list into a string of text
+ for(var/B in broken)
+ broken_message += B
+ to_chat(src, " Your [broken_message] [broken_plural ? "are" : "is"] non-functional! ")
+ if(damaged.len)
+ if(damaged.len > 1)
+ damaged.Insert(damaged.len, "and ")
+ damaged_plural = TRUE
+ else
+ var/holder = damaged[1]
+ if(holder[lentext(holder)] == "s")
+ damaged_plural = TRUE
+ for(var/D in damaged)
+ damaged_message += D
+ to_chat(src, "Your [damaged_message] [damaged_plural ? "are" : "is"] hurt. ")
+
if(roundstart_quirks.len)
to_send += "You have these quirks: [get_trait_string()]. \n"
-
+
to_chat(src, to_send)
else
if(wear_suit)
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 2425fcf14d..b1f11f6463 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -1,5 +1,5 @@
/mob/living/carbon/human
- hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD)
+ hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD, NANITE_HUD, DIAG_NANITE_FULL_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD,RAD_HUD)
hud_type = /datum/hud/human
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
pressure_resistance = 25
@@ -19,6 +19,8 @@
var/horn_color = "85615a" //specific horn colors, because why not?
+ var/wing_color = "fff" //wings too
+
var/skin_tone = "caucasian1" //Skin tone
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
@@ -49,6 +51,9 @@
var/bleed_rate = 0 //how much are we bleeding
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
+ var/blood_state = BLOOD_STATE_NOT_BLOODY
+ var/list/blood_smear = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
+
var/name_override //For temporary visible name changes
var/genital_override = FALSE //Force genitals on things incase of chems
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index b65d62b63b..8bc8866380 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -127,3 +127,9 @@
return FALSE
return .
+/*
+/mob/living/carbon/human/transfer_blood_dna(list/blood_dna)
+ ..()
+ if(blood_dna.len)
+ last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
+ last_blood_DNA = blood_dna[blood_dna.len]*/
diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm
index 6ea9c985e2..4e6f9e0eb9 100644
--- a/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/code/modules/mob/living/carbon/human/human_movement.dm
@@ -56,20 +56,20 @@
//Bloody footprints
var/turf/T = get_turf(src)
if(S.bloody_shoes && S.bloody_shoes[S.blood_state])
- for(var/obj/effect/decal/cleanable/blood/footprints/oldFP in T)
- if (oldFP.blood_state == S.blood_state)
- return
- //No oldFP or they're all a different kind of blood
- S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
- if (S.bloody_shoes[S.blood_state] > BLOOD_LOSS_IN_SPREAD)
- var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
- FP.blood_state = S.blood_state
- FP.entered_dirs |= dir
- FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD
- FP.add_blood_DNA(S.return_blood_DNA())
- FP.update_icon()
+ var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
+ if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == bloodtype_to_color(S.last_bloodtype)))
+ return
+ S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP)
+ var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
+ FP.blood_state = S.blood_state
+ FP.entered_dirs |= dir
+ FP.bloodiness = S.bloody_shoes[S.blood_state]
+ if(S.last_bloodtype)
+ FP.blood_DNA += list(S.last_blood_DNA = S.last_bloodtype)
+ FP.update_icon()
update_inv_shoes()
//End bloody footprints
+
S.step_action()
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index d35df6b789..084dbd83ef 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -79,7 +79,8 @@
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
- if(!..()) //a check failed or the item has already found its slot
+ . = ..()
+ if(!.) //a check failed or the item has already found its slot
return
var/not_handled = FALSE //Added in case we make this type path deeper one day
@@ -136,6 +137,7 @@
update_inv_s_store()
else
to_chat(src, "You are trying to equip this item to an unsupported inventory slot. Report this to a coder! ")
+ not_handled = TRUE
//Item is handled and in slot, valid to call callback, for this proc should always be true
if(!not_handled)
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index b1c31ffdff..be52a8289b 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -18,7 +18,7 @@
#define THERMAL_PROTECTION_HAND_LEFT 0.025
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
-/mob/living/carbon/human/Life()
+/mob/living/carbon/human/Life(seconds, times_fired)
set invisibility = 0
if (notransform)
return
@@ -41,7 +41,7 @@
if(stat != DEAD)
//process your dick energy
- handle_arousal()
+ handle_arousal(times_fired)
//Update our name based on whether our face is obscured/disfigured
name = get_visible_name()
@@ -74,7 +74,7 @@
else if(eye_blurry) //blurry eyes heal slowly
adjust_blurriness(-1)
- if (getBrainLoss() >= 30) //Citadel change to make memes more often.
+ if (getOrganLoss(ORGAN_SLOT_BRAIN) >= 30) //Citadel change to make memes more often.
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "brain_damage", /datum/mood_event/brain_damage)
if(prob(3))
if(prob(25))
diff --git a/code/modules/mob/living/carbon/human/physiology.dm b/code/modules/mob/living/carbon/human/physiology.dm
index ac9e9fe219..4d411deb53 100644
--- a/code/modules/mob/living/carbon/human/physiology.dm
+++ b/code/modules/mob/living/carbon/human/physiology.dm
@@ -21,8 +21,6 @@
var/bleed_mod = 1 // % bleeding modifier
var/datum/armor/armor // internal armor datum
- var/speed_mod = 0 //tick modifier for each step. Positive is slower, negative is faster.
-
var/hunger_mod = 1 //% of hunger rate taken per tick.
var/do_after_speed = 1 //Speed mod for do_after. Lower is better. If temporarily adjusting, please only modify using *= and /=, so you don't interrupt other calculations.
diff --git a/code/modules/mob/living/carbon/human/say.dm b/code/modules/mob/living/carbon/human/say.dm
index eee425063d..c54f41017a 100644
--- a/code/modules/mob/living/carbon/human/say.dm
+++ b/code/modules/mob/living/carbon/human/say.dm
@@ -1,14 +1,14 @@
/mob/living/carbon/human/say_mod(input, message_mode)
verb_say = dna.species.say_mod
- switch(slurring)
- if(10 to 25)
- return "jumbles"
- if(25 to 50)
- return "slurs"
- if(50 to INFINITY)
- return "garbles"
- else
- . = ..()
+ . = ..()
+ if(message_mode != MODE_CUSTOM_SAY && message_mode != MODE_WHISPER_CRIT)
+ switch(slurring)
+ if(10 to 25)
+ return "jumbles"
+ if(25 to 50)
+ return "slurs"
+ if(50 to INFINITY)
+ return "garbles"
/mob/living/carbon/human/GetVoice()
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm
index d2e8cab240..8445f340e6 100644
--- a/code/modules/mob/living/carbon/human/species.dm
+++ b/code/modules/mob/living/carbon/human/species.dm
@@ -9,14 +9,35 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
- var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
+ var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
- var/list/offset_features = list(OFFSET_UNIFORM = list(0,0), OFFSET_ID = list(0,0), OFFSET_GLOVES = list(0,0), OFFSET_GLASSES = list(0,0), OFFSET_EARS = list(0,0), OFFSET_SHOES = list(0,0), OFFSET_S_STORE = list(0,0), OFFSET_FACEMASK = list(0,0), OFFSET_HEAD = list(0,0), OFFSET_FACE = list(0,0), OFFSET_BELT = list(0,0), OFFSET_BACK = list(0,0), OFFSET_SUIT = list(0,0), OFFSET_NECK = list(0,0))
+ //Species Icon Drawing Offsets - Pixel X, Pixel Y, Aka X = Horizontal and Y = Vertical, from bottom left corner
+ var/list/offset_features = list(
+ OFFSET_UNIFORM = list(0,0),
+ OFFSET_ID = list(0,0),
+ OFFSET_GLOVES = list(0,0),
+ OFFSET_GLASSES = list(0,0),
+ OFFSET_EARS = list(0,0),
+ OFFSET_SHOES = list(0,0),
+ OFFSET_S_STORE = list(0,0),
+ OFFSET_FACEMASK = list(0,0),
+ OFFSET_HEAD = list(0,0),
+ OFFSET_EYES = list(0,0),
+ OFFSET_LIPS = list(0,0),
+ OFFSET_BELT = list(0,0),
+ OFFSET_BACK = list(0,0),
+ OFFSET_HAIR = list(0,0),
+ OFFSET_FHAIR = list(0,0),
+ OFFSET_SUIT = list(0,0),
+ OFFSET_NECK = list(0,0),
+ OFFSET_MUTPARTS = list(0,0)
+ )
var/hair_color // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
var/horn_color //specific horn colors, because why not?
+ var/wing_color
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
@@ -311,6 +332,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if("meat_type" in default_features) //I can't believe it's come to the meat
H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]]
+ C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING))
+
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
@@ -318,12 +341,17 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
if(C.dna.species.exotic_bloodtype)
- C.dna.blood_type = random_blood_type()
+ if(!new_species.exotic_bloodtype)
+ C.dna.blood_type = random_blood_type()
+ else
+ C.dna.blood_type = new_species.exotic_bloodtype
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(TRUE)
for(var/X in inherent_traits)
REMOVE_TRAIT(C, X, SPECIES_TRAIT)
+ C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES)
+
if("meat_type" in default_features)
C.type_of_meat = GLOB.meat_types[C.dna.features["meat_type"]]
else
@@ -401,6 +429,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
facial_overlay.alpha = hair_alpha
+ if(OFFSET_FHAIR in H.dna.species.offset_features)
+ facial_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FHAIR][1]
+ facial_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FHAIR][2]
+
standing += facial_overlay
if(H.head)
@@ -458,9 +490,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
else
hair_overlay.color = forced_colour
hair_overlay.alpha = hair_alpha
- if(OFFSET_FACE in H.dna.species.offset_features)
- hair_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
- hair_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
+
+ if(OFFSET_HAIR in H.dna.species.offset_features)
+ hair_overlay.pixel_x += H.dna.species.offset_features[OFFSET_HAIR][1]
+ hair_overlay.pixel_y += H.dna.species.offset_features[OFFSET_HAIR][2]
+
if(hair_overlay.icon)
standing += hair_overlay
@@ -481,9 +515,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.lip_style && (LIPS in species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER)
lip_overlay.color = H.lip_color
- if(OFFSET_FACE in H.dna.species.offset_features)
- lip_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
- lip_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
+
+ if(OFFSET_LIPS in H.dna.species.offset_features)
+ lip_overlay.pixel_x += H.dna.species.offset_features[OFFSET_LIPS][1]
+ lip_overlay.pixel_y += H.dna.species.offset_features[OFFSET_LIPS][2]
+
standing += lip_overlay
// eyes
@@ -496,9 +532,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
if((EYECOLOR in species_traits) && has_eyes)
eye_overlay.color = "#" + H.eye_color
- if(OFFSET_FACE in H.dna.species.offset_features)
- eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
- eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
+
+ if(OFFSET_EYES in H.dna.species.offset_features)
+ eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_EYES][1]
+ eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_EYES][2]
+
standing += eye_overlay
//Underwear, Undershirts & Socks
@@ -507,7 +545,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.hidden_underwear)
H.underwear = "Nude"
else
- H.saved_underwear = H.underwear
+ H.underwear = H.saved_underwear
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
if(B)
var/mutable_appearance/MA = mutable_appearance(B.icon, B.icon_state, -BODY_LAYER)
@@ -519,7 +557,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.hidden_undershirt)
H.undershirt = "Nude"
else
- H.saved_undershirt = H.undershirt
+ H.undershirt = H.saved_undershirt
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
if(T)
var/mutable_appearance/MA
@@ -535,7 +573,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(H.hidden_socks)
H.socks = "Nude"
else
- H.saved_socks = H.socks
+ H.socks = H.saved_socks
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
if(S)
var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : ""
@@ -731,6 +769,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
S = GLOB.wings_list[H.dna.features["wings"]]
if("wingsopen")
S = GLOB.wings_open_list[H.dna.features["wings"]]
+ if("deco_wings")
+ S = GLOB.deco_wings_list[H.dna.features["deco_wings"]]
if("legs")
S = GLOB.legs_list[H.dna.features["legs"]]
if("insect_wings")
@@ -782,6 +822,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
bodypart = "snout"
if(bodypart == "xenohead")
bodypart = "xhead"
+ if(bodypart == "insect_wings" || bodypart == "deco_wings")
+ bodypart = "insect_wings"
if(S.gender_specific)
accessory_overlay.icon_state = "[g]_[bodypart]_[S.icon_state]_[layertext]"
@@ -835,6 +877,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
accessory_overlay.color = "#[H.eye_color]"
if(HORNCOLOR)
accessory_overlay.color = "#[H.horn_color]"
+ if(WINGCOLOR)
+ accessory_overlay.color = "#[H.wing_color]"
else
accessory_overlay.color = forced_colour
else
@@ -851,6 +895,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
for(var/index=1, index<=husklist.len, index++)
husklist[index] = husklist[index]/255
accessory_overlay.color = husklist
+
+ if(OFFSET_MUTPARTS in H.dna.species.offset_features)
+ accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
+ accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
+
standing += accessory_overlay
if(S.hasinner)
@@ -863,6 +912,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(S.center)
inner_accessory_overlay = center_image(inner_accessory_overlay, S.dimension_x, S.dimension_y)
+ if(OFFSET_MUTPARTS in H.dna.species.offset_features)
+ inner_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
+ inner_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
+
standing += inner_accessory_overlay
if(S.extra) //apply the extra overlay, if there is one
@@ -903,6 +956,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(HORNCOLOR)
extra_accessory_overlay.color = "#[H.horn_color]"
+ if(WINGCOLOR)
+ extra_accessory_overlay.color = "#[H.wing_color]"
+
+ if(OFFSET_MUTPARTS in H.dna.species.offset_features)
+ extra_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
+ extra_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
+
standing += extra_accessory_overlay
if(S.extra2) //apply the extra overlay, if there is one
@@ -937,6 +997,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
extra2_accessory_overlay.color = "#[H.hair_color]"
if(HORNCOLOR)
extra2_accessory_overlay.color = "#[H.horn_color]"
+ if(WINGCOLOR)
+ extra2_accessory_overlay.color = "#[H.wing_color]"
+
+ if(OFFSET_MUTPARTS in H.dna.species.offset_features)
+ extra2_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
+ extra2_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
+
standing += extra2_accessory_overlay
@@ -964,6 +1031,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return "TAUR"
//END EDIT
+/* TODO: Snowflake trail marks
+// Impliments different trails for species depending on if they're wearing shoes.
+/datum/species/proc/get_move_trail(var/mob/living/carbon/human/H)
+ if(H.lying)
+ return /obj/effect/decal/cleanable/blood/footprints/tracks/body
+ if(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)))
+ var/obj/item/clothing/shoes/shoes = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) ? H.wear_suit : H.shoes // suits take priority over shoes
+ return shoes.move_trail
+ else
+ return move_trail */
/datum/species/proc/spec_life(mob/living/carbon/human/H)
if(HAS_TRAIT(H, TRAIT_NOBREATH))
@@ -1217,13 +1294,18 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if (H.nutrition > 0 && H.stat != DEAD && !HAS_TRAIT(H, TRAIT_NOHUNGER))
// THEY HUNGER
var/hunger_rate = HUNGER_FACTOR
- GET_COMPONENT_FROM(mood, /datum/component/mood, H)
+ var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
if(mood && mood.sanity > SANITY_DISTURBED)
hunger_rate *= max(0.5, 1 - 0.002 * mood.sanity) //0.85 to 0.75
- if(H.satiety > 0)
+ // Whether we cap off our satiety or move it towards 0
+ if(H.satiety > MAX_SATIETY)
+ H.satiety = MAX_SATIETY
+ else if(H.satiety > 0)
H.satiety--
- if(H.satiety < 0)
+ else if(H.satiety < -MAX_SATIETY)
+ H.satiety = -MAX_SATIETY
+ else if(H.satiety < 0)
H.satiety++
if(prob(round(-H.satiety/40)))
H.Jitter(5)
@@ -1311,39 +1393,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/movement_delay(mob/living/carbon/human/H)
. = 0 //We start at 0.
var/flight = 0 //Check for flight and flying items
- var/ignoreslow = 0
var/gravity = 0
if(H.movement_type & FLYING)
flight = 1
gravity = H.has_gravity()
- if(gravity && !flight) //Check for chemicals and innate speedups and slowdowns if we're on the ground
- if(HAS_TRAIT(H, TRAIT_GOTTAGOFAST))
- . -= 1
- if(HAS_TRAIT(H, TRAIT_GOTTAGOREALLYFAST))
- . -= 2
- . += speedmod
- . += H.physiology.speed_mod
-
if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP))
. -= 1.5
- if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN))
- ignoreslow = 1
-
- if(!gravity)
- var/obj/item/tank/jetpack/J = H.back
- var/obj/item/clothing/suit/space/hardsuit/C = H.wear_suit
- var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot(ORGAN_SLOT_THRUSTERS)
- if(!istype(J) && istype(C))
- J = C.jetpack
- if(istype(J) && J.full_speed && J.allow_thrust(0.005, H)) //Prevents stacking
- . -= 0.4
- else if(istype(T) && T.allow_thrust(0.005, H))
- . -= 0.4
-
- if(!ignoreslow && gravity)
+ if(!HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN) && gravity)
if(H.wear_suit)
. += H.wear_suit.slowdown
if(H.shoes)
@@ -1370,16 +1429,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/grav_force = min(gravity - STANDARD_GRAVITY,3)
. += 1 + grav_force
- GET_COMPONENT_FROM(mood, /datum/component/mood, H)
- if(mood && !flight) //How can depression slow you down if you can just fly away from your problems?
- switch(mood.sanity)
- if(SANITY_INSANE to SANITY_CRAZY)
- . += 1.5
- if(SANITY_CRAZY to SANITY_UNSTABLE)
- . += 1
- if(SANITY_UNSTABLE to SANITY_DISTURBED)
- . += 0.5
-
if(HAS_TRAIT(H, TRAIT_FAT))
. += (1.5 - flight)
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
@@ -1706,9 +1755,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
switch(hit_area)
if(BODY_ZONE_HEAD)
- if(!I.is_sharp() && armor_block < 50)
+ if(!I.get_sharpness() && armor_block < 50)
if(prob(I.force))
- H.adjustBrainLoss(20)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
if(H.stat == CONSCIOUS)
H.visible_message("[H] has been knocked senseless! ", \
"[H] has been knocked senseless! ")
@@ -1717,7 +1766,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(prob(10))
H.gain_trauma(/datum/brain_trauma/mild/concussion)
else
- H.adjustBrainLoss(I.force * 0.2)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, I.force * 0.2)
if(H.stat == CONSCIOUS && H != user && prob(I.force + ((100 - H.health) * 0.5))) // rev deconversion through blunt trauma.
var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev)
@@ -1739,7 +1788,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.update_inv_glasses()
if(BODY_ZONE_CHEST)
- if(H.stat == CONSCIOUS && !I.is_sharp() && armor_block < 50)
+ if(H.stat == CONSCIOUS && !I.get_sharpness() && armor_block < 50)
if(prob(I.force))
H.visible_message("[H] has been knocked down! ", \
"[H] has been knocked down! ")
@@ -1821,67 +1870,36 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!target.resting)
target.adjustStaminaLoss(5)
+ if(target.is_shove_knockdown_blocked())
+ return
var/turf/target_oldturf = target.loc
var/shove_dir = get_dir(user.loc, target_oldturf)
var/turf/target_shove_turf = get_step(target.loc, shove_dir)
var/mob/living/carbon/human/target_collateral_human
- var/obj/structure/table/target_table
var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied
//Thank you based whoneedsspace
target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents
- if(target_collateral_human)
+ if(target_collateral_human && !target_collateral_human.resting)
shove_blocked = TRUE
else
+ target_collateral_human = null
target.Move(target_shove_turf, shove_dir)
if(get_turf(target) == target_oldturf)
- if(target_shove_turf.density)
- shove_blocked = TRUE
- else
- var/thoushallnotpass = FALSE
- for(var/obj/O in target_shove_turf)
- if(istype(O, /obj/structure/table))
- target_table = O
- else if(!O.CanPass(src, target_shove_turf))
- shove_blocked = TRUE
- thoushallnotpass = TRUE
- if(thoushallnotpass)
- target_table = null
+ shove_blocked = TRUE
- if(target.is_shove_knockdown_blocked())
- return
-
- if(shove_blocked || target_table)
- var/directional_blocked = FALSE
- if(shove_dir in GLOB.cardinals) //Directional checks to make sure that we're not shoving through a windoor or something like that
- var/target_turf = get_turf(target)
- for(var/obj/O in target_turf)
- if(O.flags_1 & ON_BORDER_1 && O.dir == shove_dir && O.density)
- directional_blocked = TRUE
- break
- if(target_turf != target_shove_turf) //Make sure that we don't run the exact same check twice on the same tile
- for(var/obj/O in target_shove_turf)
- if(O.flags_1 & ON_BORDER_1 && O.dir == turn(shove_dir, 180) && O.density)
- directional_blocked = TRUE
- break
+ if(shove_blocked && !target.buckled)
+ var/directional_blocked = !target.Adjacent(target_shove_turf)
var/targetatrest = target.resting
- if(((!target_table && !target_collateral_human) || directional_blocked) && !targetatrest)
+ if((directional_blocked || !(target_collateral_human || target_shove_turf.shove_act(target, user))) && !targetatrest)
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
user.visible_message("[user.name] shoves [target.name], knocking them down! ",
"You shove [target.name], knocking them down! ", null, COMBAT_MESSAGE_RANGE)
log_combat(user, target, "shoved", "knocking them down")
- else if(target_table)
- if(!targetatrest)
- target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
- user.visible_message("[user.name] shoves [target.name] onto \the [target_table]! ",
- "You shove [target.name] onto \the [target_table]! ", null, COMBAT_MESSAGE_RANGE)
- target.forceMove(target_shove_turf)
- log_combat(user, target, "shoved", "onto [target_table]")
else if(target_collateral_human && !targetatrest)
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
- if(!target_collateral_human.resting)
- target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
+ target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
user.visible_message("[user.name] shoves [target.name] into [target_collateral_human.name]! ",
"You shove [target.name] into [target_collateral_human.name]! ", null, COMBAT_MESSAGE_RANGE)
log_combat(user, target, "shoved", "into [target_collateral_human.name]")
@@ -1893,8 +1911,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/knocked_item = FALSE
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
- if(!target.has_movespeed_modifier(SHOVE_SLOWDOWN_ID))
- target.add_movespeed_modifier(SHOVE_SLOWDOWN_ID, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
+ if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
+ target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
if(target_held_item)
target.visible_message("[target.name]'s grip on \the [target_held_item] loosens! ",
"Your grip on \the [target_held_item] loosens! ", null, COMBAT_MESSAGE_RANGE)
@@ -1912,10 +1930,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
append_message = "loosening their grip on [target_held_item]"
log_combat(user, target, "shoved", append_message)
-/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
+/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
var/hit_percent = (100-(blocked+armor))/100
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
- if(hit_percent <= 0)
+ if(!forced && hit_percent <= 0)
return 0
var/obj/item/bodypart/BP = null
@@ -1937,37 +1955,44 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
switch(damagetype)
if(BRUTE)
H.damageoverlaytemp = 20
+ var/damage_amount = forced ? damage : damage * hit_percent * brutemod * H.physiology.brute_mod
if(BP)
- if(damage > 0 ? BP.receive_damage(damage * hit_percent * brutemod * H.physiology.brute_mod, 0) : BP.heal_damage(abs(damage * hit_percent * brutemod * H.physiology.brute_mod), 0))
+ if(damage > 0 ? BP.receive_damage(damage_amount, 0) : BP.heal_damage(abs(damage_amount), 0))
H.update_damage_overlays()
if(HAS_TRAIT(H, TRAIT_MASO))
- H.adjustArousalLoss(damage * brutemod * H.physiology.brute_mod)
+ H.adjustArousalLoss(damage_amount, 0)
if (H.getArousalLoss() >= 100 && ishuman(H) && H.has_dna())
H.mob_climax(forced_climax=TRUE)
else//no bodypart, we deal damage with a more general method.
- H.adjustBruteLoss(damage * hit_percent * brutemod * H.physiology.brute_mod)
+ H.adjustBruteLoss(damage_amount)
if(BURN)
H.damageoverlaytemp = 20
+ var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod
if(BP)
- if(damage > 0 ? BP.receive_damage(0, damage * hit_percent * burnmod * H.physiology.burn_mod) : BP.heal_damage(0, abs(damage * hit_percent * burnmod * H.physiology.burn_mod)))
+ if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
H.update_damage_overlays()
else
- H.adjustFireLoss(damage * hit_percent * burnmod * H.physiology.burn_mod)
+ H.adjustFireLoss(damage_amount)
if(TOX)
- H.adjustToxLoss(damage * hit_percent * H.physiology.tox_mod)
+ var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.tox_mod
+ H.adjustToxLoss(damage_amount)
if(OXY)
- H.adjustOxyLoss(damage * hit_percent * H.physiology.oxy_mod)
+ var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.oxy_mod
+ H.adjustOxyLoss(damage_amount)
if(CLONE)
- H.adjustCloneLoss(damage * hit_percent * H.physiology.clone_mod)
+ var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.clone_mod
+ H.adjustCloneLoss(damage_amount)
if(STAMINA)
+ var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.stamina_mod
if(BP)
- if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent * H.physiology.stamina_mod) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
+ if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
H.update_stamina()
else
- H.adjustStaminaLoss(damage * hit_percent * H.physiology.stamina_mod)
+ H.adjustStaminaLoss(damage_amount)
if(BRAIN)
- H.adjustBrainLoss(damage * hit_percent * H.physiology.brain_mod)
+ var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brain_mod
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount)
if(AROUSAL) //Citadel edit - arousal
H.adjustArousalLoss(damage * hit_percent)
return 1
diff --git a/code/modules/mob/living/carbon/human/species_types/abductors.dm b/code/modules/mob/living/carbon/human/species_types/abductors.dm
index ad1f5c9190..ffd129ebf7 100644
--- a/code/modules/mob/living/carbon/human/species_types/abductors.dm
+++ b/code/modules/mob/living/carbon/human/species_types/abductors.dm
@@ -6,10 +6,6 @@
species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
mutanttongue = /obj/item/organ/tongue/abductor
- var/scientist = FALSE // vars to not pollute spieces list with castes
-
-/datum/species/abductor/copy_properties_from(datum/species/abductor/old_species)
- scientist = old_species.scientist
/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
diff --git a/code/modules/mob/living/carbon/human/species_types/angel.dm b/code/modules/mob/living/carbon/human/species_types/angel.dm
index c1c848106c..7669a8c740 100644
--- a/code/modules/mob/living/carbon/human/species_types/angel.dm
+++ b/code/modules/mob/living/carbon/human/species_types/angel.dm
@@ -29,7 +29,7 @@
if(fly)
fly.Remove(H)
if(H.movement_type & FLYING)
- H.movement_type &= ~FLYING
+ H.setMovetype(H.movement_type & ~FLYING)
ToggleFlight(H,0)
if(H.dna && H.dna.species && (H.dna.features["wings"] == "Angel"))
if("wings" in H.dna.species.mutant_bodyparts)
@@ -132,14 +132,14 @@
if(flight && CanFly(H))
stunmod = 2
speedmod = -0.35
- H.movement_type |= FLYING
+ H.setMovetype(H.movement_type | FLYING)
override_float = TRUE
H.pass_flags |= PASSTABLE
H.OpenWings()
else
stunmod = 1
speedmod = 0
- H.movement_type &= ~FLYING
+ H.setMovetype(H.movement_type & ~FLYING)
override_float = FALSE
H.pass_flags &= ~PASSTABLE
H.CloseWings()
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species_types/bugmen.dm b/code/modules/mob/living/carbon/human/species_types/bugmen.dm
index 94dba550b6..d264f11b73 100644
--- a/code/modules/mob/living/carbon/human/species_types/bugmen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/bugmen.dm
@@ -3,7 +3,7 @@
id = "insect"
say_mod = "flutters"
default_color = "00FF00"
- species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR)
+ species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_BUG)
mutant_bodyparts = list("mam_ears", "mam_snout", "mam_tail", "taur", "insect_wings", "mam_snouts", "insect_fluff","horns")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
@@ -17,6 +17,7 @@
toxic_food = MEAT | RAW
mutanteyes = /obj/item/organ/eyes/insect
should_draw_citadel = TRUE
+ exotic_bloodtype = "BUG"
/datum/species/insect/on_species_gain(mob/living/carbon/C)
. = ..()
diff --git a/code/modules/mob/living/carbon/human/species_types/dullahan.dm b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
index 4a7580e978..eba4ff6d2f 100644
--- a/code/modules/mob/living/carbon/human/species_types/dullahan.dm
+++ b/code/modules/mob/living/carbon/human/species_types/dullahan.dm
@@ -13,9 +13,12 @@
blacklisted = TRUE
limbs_id = "human"
skinned_type = /obj/item/stack/sheet/animalhide/human
+ var/pumpkin = FALSE
var/obj/item/dullahan_relay/myhead
+/datum/species/dullahan/pumpkin
+ pumpkin = TRUE
/datum/species/dullahan/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
@@ -27,11 +30,19 @@
H.flags_1 &= ~HEAR_1
var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD)
if(head)
+ if(pumpkin)//Pumpkinhead!
+ head.animal_origin = 100
+ head.icon = 'icons/obj/clothing/hats.dmi'
+ head.icon_state = "hardhat1_pumpkin_j"
+ head.custom_head = TRUE
head.drop_limb()
head.flags_1 = HEAR_1
head.throwforce = 25
myhead = new /obj/item/dullahan_relay (head, H)
H.put_in_hands(head)
+ var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
+ for(var/datum/action/item_action/organ_action/OA in E.actions)
+ OA.Trigger()
/datum/species/dullahan/on_species_loss(mob/living/carbon/human/H)
H.flags_1 |= ~HEAR_1
@@ -64,7 +75,7 @@
/obj/item/organ/brain/dullahan
decoy_override = TRUE
- vital = FALSE
+ organ_flags = ORGAN_NO_SPOIL//Do not decay
/obj/item/organ/tongue/dullahan
zone = "abstract"
@@ -138,4 +149,4 @@
D.myhead = null
owner.gib()
owner = null
- ..()
\ No newline at end of file
+ ..()
diff --git a/code/modules/mob/living/carbon/human/species_types/dwarves.dm b/code/modules/mob/living/carbon/human/species_types/dwarves.dm
new file mode 100644
index 0000000000..946bffbdbc
--- /dev/null
+++ b/code/modules/mob/living/carbon/human/species_types/dwarves.dm
@@ -0,0 +1,192 @@
+
+GLOBAL_LIST_INIT(dwarf_first, world.file2list("strings/names/dwarf_first.txt")) //Textfiles with first
+GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //textfiles with last
+
+/datum/species/dwarf //not to be confused with the genetic manlets
+ name = "Dwarf"
+ id = "dwarf" //Also called Homo sapiens pumilionis
+ default_color = "FFFFFF"
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NO_UNDERWEAR)
+ inherent_traits = list()
+ default_features = list("mcolor" = "FFF", "wings" = "None")
+ limbs_id = "human"
+ use_skintones = 1
+ say_mod = "bellows" //high energy, EXTRA BIOLOGICAL FUEL
+ damage_overlay_type = "human"
+ skinned_type = /obj/item/stack/sheet/animalhide/human
+ liked_food = ALCOHOL | MEAT | DAIRY //Dwarves like alcohol, meat, and dairy products.
+ disliked_food = JUNKFOOD | FRIED //Dwarves hate foods that have no nutrition other than alcohol.
+ mutant_organs = list(/obj/item/organ/dwarfgland) //Dwarven alcohol gland, literal gland warrior
+ mutantliver = /obj/item/organ/liver/dwarf //Dwarven super liver (Otherwise they r doomed)
+
+/mob/living/carbon/human/species/dwarf //species admin spawn path
+ race = /datum/species/dwarf //and the race the path is set to.
+
+/datum/species/dwarf/check_roundstart_eligible()
+ if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
+ return TRUE
+ return ..()
+
+/datum/species/dwarf/on_species_gain(mob/living/carbon/C, datum/species/old_species)
+ . = ..()
+ var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
+ var/mob/living/carbon/human/H = C
+ H.facial_hair_style = dwarf_hair
+ H.update_hair()
+ H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM.
+ RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) //We register handle_speech is being used.
+
+
+/datum/species/dwarf/on_species_loss(mob/living/carbon/H, datum/species/new_species)
+ . = ..()
+ H.transform = H.transform.Scale(1, 1.25) //And we undo it.
+ UnregisterSignal(H, COMSIG_MOB_SAY) //We register handle_speech is not being used.
+
+//Dwarf Name stuff
+/proc/dwarf_name() //hello caller: my name is urist mcuristurister
+ return "[pick(GLOB.dwarf_first)] [pick(GLOB.dwarf_last)]"
+
+/datum/species/dwarf/random_name(gender,unique,lastname)
+ return dwarf_name() //hello, ill return the value from dwarf_name proc to you when called.
+
+//Dwarf Speech handling - Basically a filter/forces them to say things. The IC helper
+/datum/species/dwarf/proc/handle_speech(datum/source, list/speech_args)
+ var/message = speech_args[SPEECH_MESSAGE]
+ if(message[1] != "*")
+ message = " [message]" //Credits to goonstation for the strings list.
+ var/list/dwarf_words = strings("dwarf_replacement.json", "dwarf") //thanks to regex too.
+
+ for(var/key in dwarf_words) //Theres like 1459 words or something man.
+ var/value = dwarf_words[key] //Thus they will always be in character.
+ if(islist(value)) //Whether they like it or not.
+ value = pick(value) //This could be drastically reduced if needed though.
+
+ message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
+ message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
+ message = replacetextEx(message, " [key]", " [value]") //Also its scottish.
+
+ if(prob(3))
+ message += pick(" By Armok!")
+ speech_args[SPEECH_MESSAGE] = trim(message)
+
+//This mostly exists because my testdwarf's liver died while trying to also not die due to no alcohol.
+/obj/item/organ/liver/dwarf
+ name = "dwarf liver"
+ icon_state = "liver"
+ desc = "A dwarven liver, theres something magical about seeing one of these up close."
+ alcohol_tolerance = 0 //dwarves really shouldn't be dying to alcohol.
+ toxTolerance = 5 //Shrugs off 5 units of toxins damage.
+ maxHealth = 150 //More health than the average liver, as you aren't going to be replacing this.
+ //If it does need replaced with a standard human liver, prepare for hell.
+
+//alcohol gland
+/obj/item/organ/dwarfgland
+ name = "dwarf alcohol gland"
+ icon_state = "plasma" //Yes this is a actual icon in icons/obj/surgery.dmi
+ desc = "A genetically engineered gland which is hopefully a step forward for humanity."
+ w_class = WEIGHT_CLASS_NORMAL
+ var/stored_alcohol = 250 //They start with 250 units, that ticks down and eventaully bad effects occur
+ var/max_alcohol = 500 //Max they can attain, easier than you think to OD on alcohol.
+ var/heal_rate = 0.5 //The rate they heal damages over 400 alcohol stored. Default is 0.5 so we times 3 since 3 seconds.
+ var/alcohol_rate = 0.25 //The rate the alcohol ticks down per each iteration of dwarf_eth_ticker completing.
+ //These count in on_life ticks which should be 2 seconds per every increment of 1 in a perfect world.
+ var/dwarf_filth_ticker = 0 //Currently set =< 4, that means this will fire the proc around every 4-8 seconds.
+ var/dwarf_eth_ticker = 0 //Currently set =< 1, that means this will fire the proc around every 2 seconds
+
+/obj/item/organ/dwarfgland/prepare_eat()
+ var/obj/S = ..()
+ S.reagents.add_reagent("ethanol", stored_alcohol/10)
+ return S
+
+/obj/item/organ/dwarfgland/on_life() //Primary loop to hook into to start delayed loops for other loops..
+ . = ..()
+ dwarf_cycle_ticker()
+
+//Handles the delayed tick cycle by just adding on increments per each on_life() tick
+/obj/item/organ/dwarfgland/proc/dwarf_cycle_ticker()
+ if(owner.stat == DEAD)
+ return //We make sure they are not dead, so they don't increment any tickers.
+ dwarf_eth_ticker++
+ dwarf_filth_ticker++
+
+ if(dwarf_filth_ticker >= 4) //Should be around 4-8 seconds since a tick is around 2 seconds.
+ dwarf_filth_cycle() //On_life will adjust regarding other factors, so we are along for the ride.
+ dwarf_filth_ticker = 0 //We set the ticker back to 0 to go again.
+ if(dwarf_eth_ticker >= 1) //Alcohol reagent check should be around 2 seconds, since a tick is around 2 seconds.
+ dwarf_eth_cycle()
+ dwarf_eth_ticker = 0
+
+//If this still friggin uses too much CPU, I'll make a for view subsystem If I have to.
+/obj/item/organ/dwarfgland/proc/dwarf_filth_cycle()
+ if(!owner?.client || !owner?.mind)
+ return
+ //Filth Reactions - Since miasma now exists
+ var/filth_counter = 0 //Holder for the filth check cycle, basically contains how much filth dwarf sees numerically.
+ for(var/fuck in view(owner,7)) //hello byond for view loop.
+ if(istype(fuck, /mob/living/carbon/human))
+ var/mob/living/carbon/human/H = fuck
+ if(H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH)))
+ filth_counter += 10
+ if(istype(fuck, /obj/effect/decal/cleanable/blood))
+ if(istype(fuck, /obj/effect/decal/cleanable/blood/gibs))
+ filth_counter += 1
+ else
+ filth_counter += 0.1
+ if(istype(fuck,/obj/effect/decal/cleanable/vomit)) //They are disgusted by their own vomit too.
+ filth_counter += 10 //Dwarves could technically chainstun each other in a vomit tantrum spiral.
+ switch(filth_counter)
+ if(11 to 25)
+ if(prob(25))
+ to_chat(owner, "Someone should really clean up in here! ")
+ if(26 to 50)
+ if(prob(30)) //Probability the message appears
+ to_chat(owner, "The stench makes you queasy. ")
+ if(prob(20)) //And then the probability they vomit along with it.
+ owner.vomit(20) //I think vomit should stay over a disgust adjustment.
+ if(51 to 75)
+ if(prob(35))
+ to_chat(owner, "By Armok! You won't be able to keep alcohol down at all! ")
+ if(prob(25))
+ owner.vomit(20) //Its more funny
+ if(76 to 100)
+ if(prob(40))
+ to_chat(owner, "You can't live in such FILTH! ")
+ if(prob(25))
+ owner.adjustToxLoss(10) //Now they start dying.
+ owner.vomit(20)
+ if(101 to INFINITY) //Now they will really start dying
+ if(prob(40))
+ to_chat(owner, " THERES TOO MUCH FILTH, OH GODS THE FILTH! ")
+ owner.adjustToxLoss(15)
+ owner.vomit(40)
+ CHECK_TICK //Check_tick right here, its motherfuckin magic. (To me at least)
+
+//Handles the dwarf alcohol cycle tied to on_life, it ticks in dwarf_cycle_ticker.
+/obj/item/organ/dwarfgland/proc/dwarf_eth_cycle()
+ //BOOZE POWER
+ for(var/datum/reagent/R in owner.reagents.reagent_list)
+ if(istype(R, /datum/reagent/consumable/ethanol))
+ var/datum/reagent/consumable/ethanol/E = R
+ stored_alcohol += (E.boozepwr / 50)
+ if(stored_alcohol > max_alcohol) //Dwarves technically start at 250 alcohol stored.
+ stored_alcohol = max_alcohol
+ var/heal_amt = heal_rate
+ stored_alcohol -= alcohol_rate //Subtracts alcohol_Rate from stored alcohol so EX: 250 - 0.25 per each loop that occurs.
+ if(stored_alcohol > 400) //If they are over 400 they start regenerating
+ owner.adjustBruteLoss(-heal_amt) //But its alcohol, there will be other issues here.
+ owner.adjustFireLoss(-heal_amt) //Unless they drink casually all the time.
+ owner.adjustOxyLoss(-heal_amt)
+ owner.adjustCloneLoss(-heal_amt) //Also they will probably get brain damage if thats a thing here.
+ if(prob(25))
+ switch(stored_alcohol)
+ if(0 to 24)
+ to_chat(owner, "DAMNATION INCARNATE, WHY AM I CURSED WITH THIS DRY-SPELL? I MUST DRINK. ")
+ owner.adjustToxLoss(35)
+ if(25 to 50)
+ to_chat(owner, "Oh DAMN, I need some brew! ")
+ if(51 to 75)
+ to_chat(owner, "Your body aches, you need to get ahold of some booze... ")
+ if(76 to 100)
+ to_chat(owner, "A pint of anything would really hit the spot right now. ")
+ if(101 to 150)
+ to_chat(owner, "You feel like you could use a good brew. ")
diff --git a/code/modules/mob/living/carbon/human/species_types/felinid.dm b/code/modules/mob/living/carbon/human/species_types/felinid.dm
index 1ee697d66c..ec58a3be9c 100644
--- a/code/modules/mob/living/carbon/human/species_types/felinid.dm
+++ b/code/modules/mob/living/carbon/human/species_types/felinid.dm
@@ -4,8 +4,8 @@
id = "felinid"
limbs_id = "human"
- mutant_bodyparts = list("mam_ears", "mam_tail")
- default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None")
+ mutant_bodyparts = list("mam_ears", "mam_tail", "deco_wings")
+ default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None", "deco_wings" = "None")
mutantears = /obj/item/organ/ears/cat
mutanttail = /obj/item/organ/tail/cat
diff --git a/code/modules/mob/living/carbon/human/species_types/flypeople.dm b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
index 043ee4fde1..0c3bcc2b00 100644
--- a/code/modules/mob/living/carbon/human/species_types/flypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/flypeople.dm
@@ -10,6 +10,7 @@
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/fly
disliked_food = null
liked_food = GROSS
+ exotic_bloodtype = "BUG"
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "pestkiller")
diff --git a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
index e726d45347..90714b390c 100644
--- a/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/furrypeople.dm
@@ -3,10 +3,10 @@
id = "mammal"
default_color = "4B4B4B"
should_draw_citadel = TRUE
- species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR)
+ species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
- mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur", "horns", "legs")
- default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky",
+ mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "deco_wings", "taur", "horns", "legs")
+ default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
"mam_body_markings" = "Husky", "taur" = "None", "horns" = "None", "legs" = "Plantigrade", "meat_type" = "Mammalian")
attack_verb = "claw"
attack_sound = 'sound/weapons/slash.ogg'
@@ -65,7 +65,7 @@
miss_sound = 'sound/weapons/slashmiss.ogg'
meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
skinned_type = /obj/item/stack/sheet/animalhide/xeno
- exotic_bloodtype = "L"
+ exotic_bloodtype = "X*"
damage_overlay_type = "xeno"
liked_food = MEAT
diff --git a/code/modules/mob/living/carbon/human/species_types/golems.dm b/code/modules/mob/living/carbon/human/species_types/golems.dm
index 84c44ea81c..edd0be01b0 100644
--- a/code/modules/mob/living/carbon/human/species_types/golems.dm
+++ b/code/modules/mob/living/carbon/human/species_types/golems.dm
@@ -581,7 +581,7 @@
limbs_id = "cultgolem"
sexes = FALSE
info_text = "As a Runic Golem , you possess eldritch powers granted by the Elder Goddess Nar'Sie."
- species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES) //no mutcolors
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL) //no mutcolors
prefix = "Runic"
special_names = null
@@ -634,9 +634,10 @@
id = "clockwork golem"
say_mod = "clicks"
limbs_id = "clockgolem"
- info_text = "As a Clockwork Golem , you are faster than other types of golems. On death, you will break down into scrap. "
- species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES)
+ info_text = "As a Clockwork Golem , you are faster than other types of golems, and are capable of using guns. On death, you will break down into scrap. "
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL)
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
+ inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
armor = 20 //Reinforced, but much less so to allow for fast movement
attack_verb = "smash"
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
@@ -682,7 +683,7 @@
blacklisted = TRUE
dangerous_existence = TRUE
random_eligible = FALSE
- info_text = "As a Clockwork Golem Servant , you are faster than other types of golems. " //warcult golems leave a corpse
+ info_text = "As a Clockwork Golem Servant , you are faster than other types of golems, and are capable of using guns. " //warcult golems leave a corpse
/datum/species/golem/cloth
name = "Cloth Golem"
@@ -691,7 +692,7 @@
sexes = FALSE
info_text = "As a Cloth Golem , you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable. \
Being made of cloth, your body is magic resistant and faster than that of other golems, but weaker and less resilient."
- species_traits = list(NOBLOOD,NO_UNDERWEAR) //no mutcolors, and can burn
+ species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL) //no mutcolors, and can burn
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOGUNS)
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
armor = 15 //feels no pain, but not too resistant
@@ -795,7 +796,7 @@
if(resistance_flags & ON_FIRE)
return
- if(P.is_hot())
+ if(P.get_temperature())
visible_message("[src] bursts into flames! ")
fire_act()
diff --git a/code/modules/mob/living/carbon/human/species_types/humans.dm b/code/modules/mob/living/carbon/human/species_types/humans.dm
index 96b43795a2..3332465c78 100644
--- a/code/modules/mob/living/carbon/human/species_types/humans.dm
+++ b/code/modules/mob/living/carbon/human/species_types/humans.dm
@@ -1,41 +1,42 @@
-/datum/species/human
- name = "Human"
- id = "human"
- default_color = "FFFFFF"
- species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY)
- mutant_bodyparts = list("ears", "tail_human", "wings", "taur") // CITADEL EDIT gives humans snowflake parts
- default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None")
- use_skintones = 1
- skinned_type = /obj/item/stack/sheet/animalhide/human
- disliked_food = GROSS | RAW
- liked_food = JUNKFOOD | FRIED
-
-/datum/species/human/qualifies_for_rank(rank, list/features)
- return TRUE //Pure humans are always allowed in all roles.
-
-/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
- if(H)
- stop_wagging_tail(H)
-
-/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
- if(H)
- stop_wagging_tail(H)
- . = ..()
-
-/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
- return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
-
-/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
- return ("waggingtail_human" in mutant_bodyparts)
-
-/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
- if("tail_human" in mutant_bodyparts)
- mutant_bodyparts -= "tail_human"
- mutant_bodyparts |= "waggingtail_human"
- H.update_body()
-
-/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
- if("waggingtail_human" in mutant_bodyparts)
- mutant_bodyparts -= "waggingtail_human"
- mutant_bodyparts |= "tail_human"
- H.update_body()
+/datum/species/human
+ name = "Human"
+ id = "human"
+ default_color = "FFFFFF"
+
+ species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR)
+ mutant_bodyparts = list("ears", "tail_human", "wings", "taur", "deco_wings") // CITADEL EDIT gives humans snowflake parts
+ default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None", "deco_wings" = "None")
+ use_skintones = 1
+ skinned_type = /obj/item/stack/sheet/animalhide/human
+ disliked_food = GROSS | RAW
+ liked_food = JUNKFOOD | FRIED
+
+/datum/species/human/qualifies_for_rank(rank, list/features)
+ return TRUE //Pure humans are always allowed in all roles.
+
+/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
+ if(H)
+ stop_wagging_tail(H)
+
+/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
+ if(H)
+ stop_wagging_tail(H)
+ . = ..()
+
+/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
+ return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
+
+/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
+ return ("waggingtail_human" in mutant_bodyparts)
+
+/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
+ if("tail_human" in mutant_bodyparts)
+ mutant_bodyparts -= "tail_human"
+ mutant_bodyparts |= "waggingtail_human"
+ H.update_body()
+
+/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
+ if("waggingtail_human" in mutant_bodyparts)
+ mutant_bodyparts -= "waggingtail_human"
+ mutant_bodyparts |= "tail_human"
+ H.update_body()
diff --git a/code/modules/mob/living/carbon/human/species_types/ipc.dm b/code/modules/mob/living/carbon/human/species_types/ipc.dm
index 95b924ea18..135c98860a 100644
--- a/code/modules/mob/living/carbon/human/species_types/ipc.dm
+++ b/code/modules/mob/living/carbon/human/species_types/ipc.dm
@@ -12,8 +12,8 @@
default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
mutanttongue = /obj/item/organ/tongue/robot/ipc
-
- exotic_blood = "oil"
+ mutant_heart = /obj/item/organ/heart/ipc
+ exotic_bloodtype = "HF"
var/datum/action/innate/monitor_change/screen
diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
index 03cd514300..71eaa5ae22 100644
--- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm
@@ -4,13 +4,15 @@
id = "jelly"
default_color = "00FF90"
say_mod = "chirps"
- species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
+ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR)
mutantlungs = /obj/item/organ/lungs/slime
- mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur") //CIT CHANGE
- default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None") //CIT CHANGE
+ mutant_heart = /obj/item/organ/heart/slime
+ mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur", "deco_wings") //CIT CHANGE
+ default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") //CIT CHANGE
inherent_traits = list(TRAIT_TOXINLOVER)
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
- exotic_blood = "slimejelly"
+ exotic_blood = "jellyblood"
+ exotic_bloodtype = "GEL"
damage_overlay_type = ""
var/datum/action/innate/regenerate_limbs/regenerate_limbs
var/datum/action/innate/slime_change/slime_change //CIT CHANGE
@@ -121,7 +123,7 @@
name = "Xenobiological Slime Entity"
id = "slime"
default_color = "00FFFF"
- species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
+ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
say_mod = "says"
hair_color = "mutcolor"
hair_alpha = 150
@@ -396,7 +398,7 @@
id = "slimeperson"
limbs_id = "slime"
default_color = "00FFFF"
- species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
+ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
inherent_traits = list(TRAIT_TOXINLOVER)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur")
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
@@ -470,37 +472,25 @@
H.hair_style = new_style
H.update_hair()
else if (select_alteration == "Genitals")
- var/list/organs = list()
var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") in list("add sexual organ", "remove sexual organ", "cancel")
switch(operation)
if("add sexual organ")
- var/new_organ = input("Select sexual organ:", "Organ Manipulation") in list("Penis", "Testicles", "Breasts", "Vagina", "Womb", "Cancel")
- if(new_organ == "Penis")
- H.give_penis()
- else if(new_organ == "Testicles")
- H.give_balls()
- else if(new_organ == "Breasts")
- H.give_breasts()
- else if(new_organ == "Vagina")
- H.give_vagina()
- else if(new_organ == "Womb")
- H.give_womb()
- else
+ var/new_organ = input("Select sexual organ:", "Organ Manipulation") as null|anything in GLOB.genitals_list
+ if(!new_organ)
return
+ H.give_genital(GLOB.genitals_list[new_organ])
+
if("remove sexual organ")
+ var/list/organs = list()
for(var/obj/item/organ/genital/X in H.internal_organs)
var/obj/item/organ/I = X
organs["[I.name] ([I.type])"] = I
- var/obj/item/organ = input("Select sexual organ:", "Organ Manipulation", null) in organs
- organ = organs[organ]
- if(!organ)
+ var/obj/item/O = input("Select sexual organ:", "Organ Manipulation", null) as null|anything in organs
+ var/obj/item/organ/genital/G = organs[O]
+ if(!G)
return
- var/obj/item/organ/genital/O
- if(isorgan(organ))
- O = organ
- O.Remove(H)
- organ.forceMove(get_turf(H))
- qdel(organ)
+ G.forceMove(get_turf(H))
+ qdel(G)
H.update_genitals()
else if (select_alteration == "Ears")
@@ -590,8 +580,8 @@
if(new_shape)
H.dna.features["cock_shape"] = new_shape
H.update_genitals()
- H.give_balls()
- H.give_penis()
+ H.give_genital(/obj/item/organ/genital/testicles)
+ H.give_genital(/obj/item/organ/genital/penis)
H.apply_overlay()
@@ -603,8 +593,8 @@
if(new_shape)
H.dna.features["vag_shape"] = new_shape
H.update_genitals()
- H.give_womb()
- H.give_vagina()
+ H.give_genital(/obj/item/organ/genital/womb)
+ H.give_genital(/obj/item/organ/genital/vagina)
H.apply_overlay()
else if (select_alteration == "Penis Length")
@@ -616,8 +606,8 @@
H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN)
H.update_genitals()
H.apply_overlay()
- H.give_balls()
- H.give_penis()
+ H.give_genital(/obj/item/organ/genital/testicles)
+ H.give_genital(/obj/item/organ/genital/penis)
else if (select_alteration == "Breast Size")
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
@@ -628,7 +618,7 @@
H.dna.features["breasts_size"] = new_size
H.update_genitals()
H.apply_overlay()
- H.give_breasts()
+ H.give_genital(/obj/item/organ/genital/breasts)
else if (select_alteration == "Breast Shape")
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
@@ -639,7 +629,7 @@
H.dna.features["breasts_shape"] = new_shape
H.update_genitals()
H.apply_overlay()
- H.give_breasts()
+ H.give_genital(/obj/item/organ/genital/breasts)
else
return
@@ -854,6 +844,8 @@
return FALSE
if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) //mindshield implant, no dice
return FALSE
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ return FALSE
if(M in linked_mobs)
return FALSE
linked_mobs.Add(M)
@@ -939,9 +931,14 @@
var/mob/living/M = input("Select who to send your message to:","Send thought to?",null) as null|mob in options
if(!M)
return
-
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(H, "As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled. ")
+ return
var/msg = sanitize(input("Message:", "Telepathy") as text|null)
if(msg)
+ if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
+ to_chat(H, "As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled. ")
+ return
log_directed_talk(H, M, msg, LOG_SAY, "slime telepathy")
to_chat(M, "You hear an alien voice in your head... [msg] ")
to_chat(H, "You telepathically said: \"[msg]\" to [M] ")
diff --git a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
index 4dbfd23df8..a719f2eda0 100644
--- a/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/lizardpeople.dm
@@ -4,16 +4,16 @@
id = "lizard"
say_mod = "hisses"
default_color = "00FF00"
- species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR)
+ species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR)
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_REPTILE)
- mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur")
+ mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur", "deco_wings")
mutanttongue = /obj/item/organ/tongue/lizard
mutanttail = /obj/item/organ/tail/lizard
coldmod = 1.5
heatmod = 0.67
default_features = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "snout" = "Round",
"horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None",
- "legs" = "Digitigrade", "taur" = "None")
+ "legs" = "Digitigrade", "taur" = "None", "deco_wings" = "None")
attack_verb = "slash"
attack_sound = 'sound/weapons/slash.ogg'
miss_sound = 'sound/weapons/slashmiss.ogg'
diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
index d7bb151ddc..06f456e004 100644
--- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
+++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm
@@ -16,7 +16,6 @@
burnmod = 1.5
heatmod = 1.5
breathid = "tox"
- speedmod = 1
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
var/internal_fire = FALSE //If the bones themselves are burning clothes won't help you much
disliked_food = FRUIT
@@ -55,19 +54,95 @@
..()
/datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
+ var/current_job = J.title
var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman
+ switch(current_job)
+ if("Chaplain")
+ O = new /datum/outfit/plasmaman/chaplain
+
+ if("Curator")
+ O = new /datum/outfit/plasmaman/curator
+
+ if("Janitor")
+ O = new /datum/outfit/plasmaman/janitor
+
+ if("Botanist")
+ O = new /datum/outfit/plasmaman/botany
+
+ if("Bartender", "Lawyer")
+ O = new /datum/outfit/plasmaman/bar
+
+ if("Cook")
+ O = new /datum/outfit/plasmaman/chef
+
+ if("Security Officer")
+ O = new /datum/outfit/plasmaman/security
+
+ if("Detective")
+ O = new /datum/outfit/plasmaman/detective
+
+ if("Warden")
+ O = new /datum/outfit/plasmaman/warden
+
+ if("Cargo Technician", "Quartermaster")
+ O = new /datum/outfit/plasmaman/cargo
+
+ if("Shaft Miner")
+ O = new /datum/outfit/plasmaman/mining
+
+ if("Medical Doctor")
+ O = new /datum/outfit/plasmaman/medical
+
+ if("Chemist")
+ O = new /datum/outfit/plasmaman/chemist
+
+ if("Geneticist")
+ O = new /datum/outfit/plasmaman/genetics
+
+ if("Roboticist")
+ O = new /datum/outfit/plasmaman/robotics
+
+ if("Virologist")
+ O = new /datum/outfit/plasmaman/viro
+
+ if("Scientist")
+ O = new /datum/outfit/plasmaman/science
+
+ if("Station Engineer")
+ O = new /datum/outfit/plasmaman/engineering
+
+ if("Atmospheric Technician")
+ O = new /datum/outfit/plasmaman/atmospherics
+
+ if("Captain")
+ O = new /datum/outfit/plasmaman/captain
+
+ if("Head of Personnel")
+ O = new /datum/outfit/plasmaman/hop
+
+ if("Head of Security")
+ O = new /datum/outfit/plasmaman/hos
+
+ if("Chief Engineer")
+ O = new /datum/outfit/plasmaman/ce
+
+ if("Chief Medical Officer")
+ O = new /datum/outfit/plasmaman/cmo
+
+ if("Research Director")
+ O = new /datum/outfit/plasmaman/rd
+
+ if("Mime")
+ O = new /datum/outfit/plasmaman/mime
+
+ if("Clown")
+ O = new /datum/outfit/plasmaman/clown
+
H.equipOutfit(O, visualsOnly)
H.internal = H.get_item_for_held_index(2)
H.update_internals_hud_icon(1)
return 0
-/datum/species/plasmaman/qualifies_for_rank(rank, list/features)
- if(rank in GLOB.security_positions)
- return 0
- if(rank == "Clown" || rank == "Mime")//No funny bussiness
- return 0
- return ..()
-
/datum/species/plasmaman/random_name(gender,unique,lastname)
if(unique)
return random_unique_plasmaman_name()
diff --git a/code/modules/mob/living/carbon/human/species_types/podpeople.dm b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
index 46207e5e60..f0dd48c6c1 100644
--- a/code/modules/mob/living/carbon/human/species_types/podpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/podpeople.dm
@@ -36,8 +36,8 @@
var/turf/T = H.loc
light_amount = min(1,T.get_lumcount()) - 0.5
H.nutrition += light_amount * light_nutrition_gain_factor
- if(H.nutrition > NUTRITION_LEVEL_FULL)
- H.nutrition = NUTRITION_LEVEL_FULL
+ if(H.nutrition >= NUTRITION_LEVEL_FULL)
+ H.nutrition = NUTRITION_LEVEL_FULL - 1
if(light_amount > 0.2) //if there's enough light, heal
H.heal_overall_damage(light_bruteheal, light_burnheal)
H.adjustToxLoss(-light_toxheal)
diff --git a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
index 754c48c3bd..09fc26d04f 100644
--- a/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/shadowpeople.dm
@@ -102,6 +102,7 @@
color = "#1C1C1C"
var/respawn_progress = 0
var/obj/item/light_eater/blade
+ decay_factor = 0
/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
@@ -122,10 +123,8 @@
if(special != HEART_SPECIAL_SHADOWIFY)
blade = new/obj/item/light_eater
M.put_in_hands(blade)
- START_PROCESSING(SSobj, src)
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
- STOP_PROCESSING(SSobj, src)
respawn_progress = 0
if(blade && special != HEART_SPECIAL_SHADOWIFY)
QDEL_NULL(blade)
@@ -138,9 +137,8 @@
/obj/item/organ/heart/nightmare/update_icon()
return //always beating visually
-/obj/item/organ/heart/nightmare/process()
- if(QDELETED(owner) || owner.stat != DEAD)
- respawn_progress = 0
+/obj/item/organ/heart/nightmare/on_death()
+ if(!owner)
return
var/turf/T = get_turf(owner)
if(istype(T))
diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
index 135992f3a6..6a4c7a4463 100644
--- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm
+++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm
@@ -3,7 +3,7 @@
name = "Spooky Scary Skeleton"
id = "skeleton"
say_mod = "rattles"
- blacklisted = 1
+ blacklisted = 0
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
@@ -12,13 +12,19 @@
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
disliked_food = NONE
- liked_food = GROSS | MEAT | RAW
+ liked_food = GROSS | MEAT | RAW | DAIRY
/datum/species/skeleton/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
return TRUE
return ..()
-/datum/species/skeleton/pirate
- name = "Space Queen's Skeleton"
+/datum/species/skeleton/space
+ name = "Spooky Spacey Skeleton"
+ id = "spaceskeleton"
+ limbs_id = "skeleton"
+ blacklisted = 1
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
+
+/datum/species/skeleton/space/check_roundstart_eligible()
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species_types/vampire.dm b/code/modules/mob/living/carbon/human/species_types/vampire.dm
index 53c6f1bd0f..7462d26ea6 100644
--- a/code/modules/mob/living/carbon/human/species_types/vampire.dm
+++ b/code/modules/mob/living/carbon/human/species_types/vampire.dm
@@ -45,14 +45,14 @@
C.adjustOxyLoss(-4)
C.adjustCloneLoss(-4)
return
- C.blood_volume -= 0.75
+ C.blood_volume -= 0.75 //Will take roughly 19.5 minutes to die from standard blood volume, roughly 83 minutes to die from max blood volume.
if(C.blood_volume <= (BLOOD_VOLUME_SURVIVE*C.blood_ratio))
to_chat(C, "You ran out of blood! ")
C.dust()
var/area/A = get_area(C)
if(istype(A, /area/chapel))
to_chat(C, "You don't belong here! ")
- C.adjustFireLoss(20)
+ C.adjustFireLoss(5)
C.adjust_fire_stacks(6)
C.IgniteMob()
@@ -88,7 +88,7 @@
to_chat(H, "[victim] doesn't have blood! ")
return
V.drain_cooldown = world.time + 30
- if(victim.anti_magic_check(FALSE, TRUE))
+ if(victim.anti_magic_check(FALSE, TRUE, FALSE, 0))
to_chat(victim, "[H] tries to bite you, but stops before touching you! ")
to_chat(H, "[victim] is blessed! You stop just in time to avoid catching fire. ")
return
@@ -141,7 +141,7 @@
H = new(shape,src,caster)
if(istype(H, /mob/living/simple_animal))
var/mob/living/simple_animal/SA = H
- if(ventcrawl_nude_only && length(caster.get_equipped_items(include_pockets = TRUE)))
+ if((caster.blood_volume >= (BLOOD_VOLUME_BAD*caster.blood_ratio)) || (ventcrawl_nude_only && length(caster.get_equipped_items(include_pockets = TRUE))))
SA.ventcrawler = FALSE
if(transfer_name)
H.name = caster.name
diff --git a/code/modules/mob/living/carbon/human/species_types/zombies.dm b/code/modules/mob/living/carbon/human/species_types/zombies.dm
index 504dbb514b..c50677c54c 100644
--- a/code/modules/mob/living/carbon/human/species_types/zombies.dm
+++ b/code/modules/mob/living/carbon/human/species_types/zombies.dm
@@ -16,7 +16,13 @@
disliked_food = NONE
liked_food = GROSS | MEAT | RAW
-/datum/species/zombie/check_roundstart_eligible()
+/datum/species/zombie/notspaceproof
+ id = "notspaceproofzombie"
+ limbs_id = "zombie"
+ blacklisted = 0
+ inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH)
+
+/datum/species/zombie/notspaceproof/check_roundstart_eligible()
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
return TRUE
return ..()
@@ -39,7 +45,7 @@
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
. = min(20, amount)
-/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
+/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
. = ..()
if(.)
regen_cooldown = world.time + REGENERATION_DELAY
@@ -47,7 +53,7 @@
/datum/species/zombie/infectious/spec_life(mob/living/carbon/C)
. = ..()
C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
-
+
//Zombies never actually die, they just fall down until they regenerate enough to rise back up.
//They must be restrained, beheaded or gibbed to stop being a threat.
if(regen_cooldown < world.time)
@@ -58,9 +64,9 @@
C.adjustToxLoss(-heal_amt)
if(!C.InCritical() && prob(4))
playsound(C, pick(spooks), 50, TRUE, 10)
-
+
//Congrats you somehow died so hard you stopped being a zombie
-/datum/species/zombie/infectious/spec_death(mob/living/carbon/C)
+/datum/species/zombie/infectious/spec_death(gibbed, mob/living/carbon/C)
. = ..()
var/obj/item/organ/zombie_infection/infection
infection = C.getorganslot(ORGAN_SLOT_ZOMBIE)
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 72ff7e7a60..a68aded85f 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -123,25 +123,20 @@ There are several things that need to be remembered:
if(U.adjusted == ALT_STYLE)
t_color = "[t_color]_d"
- if(U.mutantrace_variation)
- if(U.suit_style == DIGITIGRADE_SUIT_STYLE)
- U.alternate_worn_icon = 'modular_citadel/icons/mob/uniform_digi.dmi'
- if(U.adjusted == ALT_STYLE)
- t_color = "[t_color]_d_l"
- else if(U.adjusted == NORMAL_STYLE)
- t_color = "[t_color]_l"
- else
- U.alternate_worn_icon = null
+ var/alt_worn = U.alternate_worn_icon
+
+ if(!U.force_alternate_icon && U.mutantrace_variation && U.suit_style == DIGITIGRADE_SUIT_STYLE)
+ alt_worn = 'modular_citadel/icons/mob/uniform_digi.dmi'
var/mutable_appearance/uniform_overlay
if(dna && dna.species.sexes)
var/G = (gender == FEMALE) ? "f" : "m"
if(G == "f" && U.fitted != NO_FEMALE_UNIFORM)
- uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = ((w_uniform.alternate_worn_icon) ? w_uniform.alternate_worn_icon : 'icons/mob/uniform.dmi'), isinhands = FALSE, femaleuniform = U.fitted)
+ uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE, femaleuniform = U.fitted)
if(!uniform_overlay)
- uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = ((w_uniform.alternate_worn_icon) ? w_uniform.alternate_worn_icon : 'icons/mob/uniform.dmi'), isinhands = FALSE)
+ uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE)
if(OFFSET_UNIFORM in dna.species.offset_features)
@@ -185,7 +180,7 @@ There are several things that need to be remembered:
inv.update_icon()
if(!gloves && bloody_hands)
- var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER)
+ var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
if(get_num_arms() < 2)
if(has_left_hand())
bloody_overlay.icon_state = "bloodyhands_left"
@@ -275,6 +270,32 @@ There are several things that need to be remembered:
if(client && hud_used)
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
inv.update_icon()
+/*
+ if(!shoes && bloody_feet)
+ var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
+ if(dna.features["taur"] != "None")
+ if(dna.features["taur"] in GLOB.noodle_taurs)
+ bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "snekbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
+ if(get_num_legs() < 2)
+ if(has_left_leg())
+ bloody_overlay.icon_state = "snekbloodyfeet_left"
+ else if(has_right_leg())
+ bloody_overlay.icon_state = "snekbloodyfeet_right"
+ else if(dna.features["taur"] in GLOB.paw_taurs)
+ bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "pawbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
+ if(get_num_legs() < 2)
+ if(has_left_leg())
+ bloody_overlay.icon_state = "pawbloodyfeet_left"
+ else if(has_right_leg())
+ bloody_overlay.icon_state = "pawbloodyfeet_right"
+ else
+ if(get_num_legs() < 2)
+ if(has_left_leg())
+ bloody_overlay.icon_state = "bloodyfeet_left"
+ else if(has_right_leg())
+ bloody_overlay.icon_state = "bloodyfeet_right"
+
+ overlays_standing[GLOVES_LAYER] = bloody_overlay*/
if(shoes)
var/obj/item/clothing/shoes/S = shoes
@@ -388,22 +409,23 @@ There are several things that need to be remembered:
client.screen += wear_suit
update_observer_view(wear_suit,1)
- if(!no_taur_thanks && S.mutantrace_variation) //Just make sure we've got this checked too
- if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE) //are we not a taur, but we have Digitigrade legs? Run this check first, then.
- S.alternate_worn_icon = 'modular_citadel/icons/mob/suit_digi.dmi'
- else
- S.alternate_worn_icon = null
-
- if(S.tauric == TRUE) //Are we a suit with tauric mode possible?
- if(S.taurmode == SNEK_TAURIC)
- S.alternate_worn_icon = 'modular_citadel/icons/mob/taur_naga.dmi'
- if(S.taurmode == PAW_TAURIC)
- S.alternate_worn_icon = 'modular_citadel/icons/mob/taur_canine.dmi'
- if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE)
+ if(!S.force_alternate_icon)
+ if(!no_taur_thanks && S.mutantrace_variation) //Just make sure we've got this checked too
+ if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE) //are we not a taur, but we have Digitigrade legs? Run this check first, then.
S.alternate_worn_icon = 'modular_citadel/icons/mob/suit_digi.dmi'
- else if(S.taurmode == NOT_TAURIC && S.adjusted == NORMAL_STYLE)
+ else
S.alternate_worn_icon = null
+ if(S.tauric == TRUE) //Are we a suit with tauric mode possible?
+ if(S.taurmode == SNEK_TAURIC)
+ S.alternate_worn_icon = 'modular_citadel/icons/mob/taur_naga.dmi'
+ if(S.taurmode == PAW_TAURIC)
+ S.alternate_worn_icon = 'modular_citadel/icons/mob/taur_canine.dmi'
+ if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE)
+ S.alternate_worn_icon = 'modular_citadel/icons/mob/suit_digi.dmi'
+ else if(S.taurmode == NOT_TAURIC && S.adjusted == NORMAL_STYLE)
+ S.alternate_worn_icon = null
+
overlays_standing[SUIT_LAYER] = S.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = ((wear_suit.alternate_worn_icon) ? S.alternate_worn_icon : 'icons/mob/suit.dmi'))
var/mutable_appearance/suit_overlay = overlays_standing[SUIT_LAYER]
if(OFFSET_SUIT in dna.species.offset_features)
@@ -707,9 +729,9 @@ generate/load female uniform sprites matching all previously decided variables
if(lip_style && (LIPS in dna.species.species_traits))
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]", -BODY_LAYER)
lip_overlay.color = lip_color
- if(OFFSET_FACE in dna.species.offset_features)
- lip_overlay.pixel_x += dna.species.offset_features[OFFSET_FACE][1]
- lip_overlay.pixel_y += dna.species.offset_features[OFFSET_FACE][2]
+ if(OFFSET_LIPS in dna.species.offset_features)
+ lip_overlay.pixel_x += dna.species.offset_features[OFFSET_LIPS][1]
+ lip_overlay.pixel_y += dna.species.offset_features[OFFSET_LIPS][2]
add_overlay(lip_overlay)
// eyes
@@ -722,9 +744,9 @@ generate/load female uniform sprites matching all previously decided variables
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
if((EYECOLOR in dna.species.species_traits) && has_eyes)
eye_overlay.color = "#" + eye_color
- if(OFFSET_FACE in dna.species.offset_features)
- eye_overlay.pixel_x += dna.species.offset_features[OFFSET_FACE][1]
- eye_overlay.pixel_y += dna.species.offset_features[OFFSET_FACE][2]
+ if(OFFSET_EYES in dna.species.offset_features)
+ eye_overlay.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
+ eye_overlay.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
add_overlay(eye_overlay)
dna.species.handle_hair(src)
diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm
index 7a3405cc09..ca139cace7 100644
--- a/code/modules/mob/living/carbon/life.dm
+++ b/code/modules/mob/living/carbon/life.dm
@@ -8,8 +8,8 @@
damageoverlaytemp = 0
update_damage_hud()
- if(stat != DEAD) //Reagent processing needs to come before breathing, to prevent edge cases.
- handle_organs()
+ //Reagent processing needs to come before breathing, to prevent edge cases.
+ handle_organs()
. = ..()
@@ -28,11 +28,14 @@
if(stat != DEAD)
handle_brain_damage()
+ /* BUG_PROBABLE_CAUSE
if(stat != DEAD)
handle_liver()
+ */
if(stat == DEAD)
stop_sound_channel(CHANNEL_HEARTBEAT)
+ handle_death()
rot()
//Updates the number of stored chemicals for powers
@@ -41,14 +44,34 @@
if(stat != DEAD)
return 1
+//Procs called while dead
+/mob/living/carbon/proc/handle_death()
+ for(var/datum/reagent/R in reagents.reagent_list)
+ if(R.chemical_flags & REAGENT_DEAD_PROCESS)
+ R.on_mob_dead(src)
+
///////////////
// BREATHING //
///////////////
//Start of a breath chain, calls breathe()
/mob/living/carbon/handle_breathing(times_fired)
- if((times_fired % 4) == 2 || failed_last_breath)
- breathe() //Breathe per 4 ticks, unless suffocating
+ var/next_breath = 4
+ var/obj/item/organ/lungs/L = getorganslot(ORGAN_SLOT_LUNGS)
+ var/obj/item/organ/heart/H = getorganslot(ORGAN_SLOT_HEART)
+ if(L)
+ if(L.damage > L.high_threshold)
+ next_breath--
+ if(H)
+ if(H.damage > H.high_threshold)
+ next_breath--
+
+ if((times_fired % next_breath) == 0 || failed_last_breath)
+ breathe() //Breathe per 4 ticks if healthy, down to 2 if our lungs or heart are damaged, unless suffocating
+ if(failed_last_breath)
+ SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation)
+ else
+ SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
else
if(istype(loc, /obj/))
var/obj/location_as_object = loc
@@ -56,6 +79,7 @@
//Second link in a breath chain, calls check_breath()
/mob/living/carbon/proc/breathe()
+ var/obj/item/organ/lungs = getorganslot(ORGAN_SLOT_LUNGS)
if(reagents.has_reagent("lexorin"))
return
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
@@ -74,7 +98,7 @@
var/datum/gas_mixture/breath
if(!getorganslot(ORGAN_SLOT_BREATHING_TUBE))
- if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL))
+ if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || !lungs || lungs.organ_flags & ORGAN_FAILING)
losebreath++ //You can't breath at all when in critical or when being choked, so you're going to miss a breath
else if(health <= crit_threshold)
@@ -126,7 +150,7 @@
if((status_flags & GODMODE))
return
- var/lungs = getorganslot(ORGAN_SLOT_LUNGS)
+ var/obj/item/organ/lungs = getorganslot(ORGAN_SLOT_LUNGS)
if(!lungs)
adjustOxyLoss(2)
@@ -366,9 +390,16 @@
. |= BP.on_life()
/mob/living/carbon/proc/handle_organs()
- for(var/V in internal_organs)
- var/obj/item/organ/O = V
- O.on_life()
+ if(stat != DEAD)
+ for(var/V in internal_organs)
+ var/obj/item/organ/O = V
+ if(O)
+ O.on_life()
+ else
+ for(var/V in internal_organs)
+ var/obj/item/organ/O = V
+ if(O)
+ O.on_death() //Needed so organs decay while inside the body.
/mob/living/carbon/handle_diseases()
for(var/thing in diseases)
@@ -613,7 +644,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
to_chat(src, "Maybe you should lie down for a bit... ")
if(drunkenness >= 91)
- adjustBrainLoss(0.4, 60)
+ adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.4, 60)
if(prob(20) && !stat)
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(z)) //QoL mainly
to_chat(src, "You're so tired... but you can't miss that shuttle... ")
@@ -647,8 +678,8 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
if((!dna && !liver) || (NOLIVER in dna.species.species_traits))
return
if(liver)
- if(liver.damage >= liver.maxHealth)
- liver.failing = TRUE
+ if(liver.damage < liver.maxHealth)
+ liver.organ_flags |= ORGAN_FAILING
liver_failure()
else
liver_failure()
@@ -671,7 +702,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
/mob/living/carbon/proc/liver_failure()
reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
- if(HAS_TRAIT(src, TRAIT_STABLEHEART))
+ if(HAS_TRAIT(src, TRAIT_STABLELIVER))
return
adjustToxLoss(4, TRUE, TRUE)
if(prob(30))
@@ -687,13 +718,6 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
var/datum/brain_trauma/BT = T
BT.on_life()
- if(getBrainLoss() >= BRAIN_DAMAGE_DEATH) //rip
- to_chat(src, "The last spark of life in your brain fizzles out...")
- death()
- var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
- if(B)
- B.damaged_brain = TRUE
-
/////////////////////////////////////
//MONKEYS WITH TOO MUCH CHOLOESTROL//
/////////////////////////////////////
@@ -702,7 +726,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
if(!needs_heart())
return FALSE
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
- if(!heart || heart.synthetic)
+ if(!heart || (heart.organ_flags & ORGAN_SYNTHETIC))
return FALSE
return TRUE
diff --git a/code/modules/mob/living/carbon/monkey/inventory.dm b/code/modules/mob/living/carbon/monkey/inventory.dm
index fdc28d13a0..d5fffc70a2 100644
--- a/code/modules/mob/living/carbon/monkey/inventory.dm
+++ b/code/modules/mob/living/carbon/monkey/inventory.dm
@@ -1,4 +1,4 @@
-/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = 0)
+/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
switch(slot)
if(SLOT_HANDS)
if(get_empty_held_indexes())
diff --git a/code/modules/mob/living/carbon/update_icons.dm b/code/modules/mob/living/carbon/update_icons.dm
index cdae073af8..66be8058f1 100644
--- a/code/modules/mob/living/carbon/update_icons.dm
+++ b/code/modules/mob/living/carbon/update_icons.dm
@@ -23,7 +23,7 @@
if(changed)
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
- floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
+ setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
/mob/living/carbon
@@ -97,8 +97,12 @@
/mob/living/carbon/update_damage_overlays()
remove_overlay(DAMAGE_LAYER)
+ var/dam_colors = "#E62525"
+ if(ishuman(src))
+ var/mob/living/carbon/human/H = src
+ dam_colors = bloodtype_to_color(H.dna.blood_type)
- var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER)
+ var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER, color = dam_colors)
overlays_standing[DAMAGE_LAYER] = damage_overlay
for(var/X in bodyparts)
diff --git a/code/modules/mob/living/damage_procs.dm b/code/modules/mob/living/damage_procs.dm
index b2eed2d19e..dc43ab8b07 100644
--- a/code/modules/mob/living/damage_procs.dm
+++ b/code/modules/mob/living/damage_procs.dm
@@ -8,25 +8,24 @@
Returns
standard 0 if fail
*/
-/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
+/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
if(!damage || (hit_percent <= 0))
return 0
+ var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
- adjustBruteLoss(damage * hit_percent)
+ adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
- adjustFireLoss(damage * hit_percent)
+ adjustFireLoss(damage_amount, forced = forced)
if(TOX)
- adjustToxLoss(damage * hit_percent)
+ adjustToxLoss(damage_amount, forced = forced)
if(OXY)
- adjustOxyLoss(damage * hit_percent)
+ adjustOxyLoss(damage_amount, forced = forced)
if(CLONE)
- adjustCloneLoss(damage * hit_percent)
+ adjustCloneLoss(damage_amount, forced = forced)
if(STAMINA)
- adjustStaminaLoss(damage * hit_percent)
- if(BRAIN)
- adjustBrainLoss(damage * hit_percent)
+ adjustStaminaLoss(damage_amount, forced = forced)
return 1
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE) //like apply damage except it always uses the damage procs
@@ -43,8 +42,6 @@
return adjustCloneLoss(damage)
if(STAMINA)
return adjustStaminaLoss(damage)
- if(BRAIN)
- return adjustBrainLoss(damage)
/mob/living/proc/get_damage_amount(damagetype = BRUTE)
switch(damagetype)
@@ -60,8 +57,6 @@
return getCloneLoss()
if(STAMINA)
return getStaminaLoss()
- if(BRAIN)
- return getBrainLoss()
/mob/living/proc/apply_damages(brute = 0, burn = 0, tox = 0, oxy = 0, clone = 0, def_zone = null, blocked = FALSE, stamina = 0, brain = 0)
@@ -85,7 +80,7 @@
-/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE)
+/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE, knockdown_stamoverride, knockdown_stammax)
var/hit_percent = (100-blocked)/100
if(!effect || (hit_percent <= 0))
return 0
@@ -93,7 +88,7 @@
if(EFFECT_STUN)
Stun(effect * hit_percent)
if(EFFECT_KNOCKDOWN)
- Knockdown(effect * hit_percent)
+ Knockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? CLAMP(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
if(EFFECT_UNCONSCIOUS)
Unconscious(effect * hit_percent)
if(EFFECT_IRRADIATE)
@@ -113,13 +108,13 @@
return 1
-/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0)
+/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0, kd_stamoverride, kd_stammax)
if(blocked >= 100)
return 0
if(stun)
apply_effect(stun, EFFECT_STUN, blocked)
if(knockdown)
- apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked)
+ apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked, kd_stamoverride, kd_stammax)
if(unconscious)
apply_effect(unconscious, EFFECT_UNCONSCIOUS, blocked)
if(irradiate)
@@ -218,13 +213,13 @@
updatehealth()
return amount
-/mob/living/proc/getBrainLoss()
- . = 0
-
-/mob/living/proc/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH)
+/mob/living/proc/adjustOrganLoss(slot, amount, maximum)
return
-/mob/living/proc/setBrainLoss(amount)
+/mob/living/proc/setOrganLoss(slot, amount, maximum)
+ return
+
+/mob/living/proc/getOrganLoss(slot)
return
/mob/living/proc/getStaminaLoss()
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
index f16572c5d0..f7dec3272c 100644
--- a/code/modules/mob/living/death.dm
+++ b/code/modules/mob/living/death.dm
@@ -13,6 +13,10 @@
if(!no_bodyparts)
spread_bodyparts(no_brain, no_organs)
+ for(var/X in implants)
+ var/obj/item/implant/I = X
+ qdel(I)
+
spawn_gibs(no_bodyparts)
qdel(src)
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 25d8c4d44c..df711a6dca 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -255,7 +255,7 @@
H.Knockdown(20)
else
message_param = "bumps [user.p_their()] head on the ground trying to motion towards %t."
- H.adjustBrainLoss(5)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
..()
/datum/emote/living/pout
diff --git a/code/modules/mob/living/life.dm b/code/modules/mob/living/life.dm
index 201e5fea24..2bf17bc265 100644
--- a/code/modules/mob/living/life.dm
+++ b/code/modules/mob/living/life.dm
@@ -4,7 +4,7 @@
if(digitalinvis)
handle_diginvis() //AI becomes unable to see mob
- if((movement_type & FLYING) && !floating) //TODO: Better floating
+ if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating
float(on = TRUE)
if (client)
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index cdce80225b..e893426ee9 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -346,6 +346,11 @@
if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here
return TRUE
+/mob/living/canUseStorage()
+ if (get_num_arms() <= 0)
+ return FALSE
+ return TRUE
+
/mob/living/proc/InCritical()
return (health <= crit_threshold && (stat == SOFT_CRIT || stat == UNCONSCIOUS))
@@ -476,7 +481,6 @@
setToxLoss(0, 0) //zero as second argument not automatically call updatehealth().
setOxyLoss(0, 0)
setCloneLoss(0, 0)
- setBrainLoss(0)
setStaminaLoss(0, 0)
SetUnconscious(0, FALSE)
set_disgust(0)
@@ -498,11 +502,18 @@
fire_stacks = 0
confused = 0
update_canmove()
- GET_COMPONENT(mood, /datum/component/mood)
+ var/datum/component/mood/mood = GetComponent(/datum/component/mood)
if (mood)
QDEL_LIST_ASSOC_VAL(mood.mood_events)
mood.sanity = SANITY_GREAT
mood.update_mood()
+ //Heal all organs
+ if(iscarbon(src))
+ var/mob/living/carbon/C = src
+ if(C.internal_organs)
+ for(var/organ in C.internal_organs)
+ var/obj/item/organ/O = organ
+ O.setOrganDamage(0)
//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
@@ -705,14 +716,14 @@
var/fixed = 0
if(anchored || (buckled && buckled.anchored))
fixed = 1
- if(on && !floating && !fixed)
+ if(on && !(movement_type & FLOATING) && !fixed)
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
sleep(10)
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
- floating = TRUE
- else if(((!on || fixed) && floating))
+ setMovetype(movement_type | FLOATING)
+ else if(((!on || fixed) && (movement_type & FLOATING)))
animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
- floating = FALSE
+ setMovetype(movement_type & ~FLOATING)
// The src mob is trying to strip an item from someone
// Override if a certain type of mob should be behave differently when stripping items (can't, for example)
@@ -784,7 +795,7 @@
var/final_pixel_y = get_standard_pixel_y_offset(lying)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2)
- floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life().
+ setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life().
/mob/living/proc/get_temperature(datum/gas_mixture/environment)
var/loc_temp = environment ? environment.temperature : T0C
@@ -901,7 +912,7 @@
if(mind)
mind.transfer_to(new_mob)
else
- new_mob.key = key
+ transfer_ckey(new_mob)
for(var/para in hasparasites())
var/mob/living/simple_animal/hostile/guardian/G = para
@@ -924,7 +935,7 @@
apply_effect((amount*RAD_MOB_COEFFICIENT)/max(1, (radiation**2)*RAD_OVERDOSE_REDUCTION), EFFECT_IRRADIATE, blocked)
-/mob/living/anti_magic_check(magic = TRUE, holy = FALSE)
+/mob/living/anti_magic_check(magic = TRUE, holy = FALSE, chargecost = 1, self = FALSE)
. = ..()
if(.)
return
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 9d04f288cd..93e64fd4cc 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -422,4 +422,4 @@
if(!used_item)
used_item = get_active_held_item()
..()
- floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
+ setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
diff --git a/code/modules/mob/living/living_defines.dm b/code/modules/mob/living/living_defines.dm
index a38eee9442..4d2a36907d 100644
--- a/code/modules/mob/living/living_defines.dm
+++ b/code/modules/mob/living/living_defines.dm
@@ -2,7 +2,7 @@
see_invisible = SEE_INVISIBLE_LIVING
sight = 0
see_in_dark = 2
- hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD)
+ hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD,RAD_HUD)
pressure_resistance = 10
var/resize = 1 //Badminnery resize
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 3b045b9eee..174fd5c394 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -357,8 +357,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return message
/mob/living/proc/radio(message, message_mode, list/spans, language)
- var/obj/item/implant/radio/imp = locate() in src
- if(imp && imp.radio.on)
+ var/obj/item/implant/radio/imp = locate() in implants
+ if(imp?.radio.on)
if(message_mode == MODE_HEADSET)
imp.radio.talk_into(src, message, , spans, language)
return ITALICS | REDUCE_RANGE
@@ -391,16 +391,16 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 0
/mob/living/say_mod(input, message_mode)
- if(message_mode == MODE_WHISPER)
- . = verb_whisper
- else if(message_mode == MODE_WHISPER_CRIT)
+ . = ..()
+ if(message_mode == MODE_WHISPER_CRIT)
. = "[verb_whisper] in [p_their()] last breath"
- else if(stuttering)
- . = "stammers"
- else if(derpspeech)
- . = "gibbers"
- else
- . = ..()
+ else if(message_mode != MODE_CUSTOM_SAY)
+ if(message_mode == MODE_WHISPER)
+ . = verb_whisper
+ else if(stuttering)
+ . = "stammers"
+ else if(derpspeech)
+ . = "gibbers"
/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
diff --git a/code/modules/mob/living/silicon/ai/death.dm b/code/modules/mob/living/silicon/ai/death.dm
index 301d2bd218..f72e03350e 100644
--- a/code/modules/mob/living/silicon/ai/death.dm
+++ b/code/modules/mob/living/silicon/ai/death.dm
@@ -36,6 +36,8 @@
if(istype(loc, /obj/item/aicard/aitater))
loc.icon_state = "aitater-404"
+ else if(istype(loc, /obj/item/aicard/aispook))
+ loc.icon_state = "aispook-404"
else if(istype(loc, /obj/item/aicard))
loc.icon_state = "aicard-404"
diff --git a/code/modules/mob/living/silicon/ai/say.dm b/code/modules/mob/living/silicon/ai/say.dm
index c6d4527812..f757203237 100644
--- a/code/modules/mob/living/silicon/ai/say.dm
+++ b/code/modules/mob/living/silicon/ai/say.dm
@@ -49,7 +49,7 @@
else
padloc = "(UNKNOWN)"
src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]")
- send_speech(message, 7, T, "robot", language = language)
+ send_speech(message, 7, T, "robot", message_language = language)
to_chat(src, "Holopad transmitted, [real_name] \"[message]\" ")
else
to_chat(src, "No holopad connected.")
diff --git a/code/modules/mob/living/silicon/ai/vox_sounds.dm b/code/modules/mob/living/silicon/ai/vox_sounds.dm
index eb6d0ce991..50a808032d 100644
--- a/code/modules/mob/living/silicon/ai/vox_sounds.dm
+++ b/code/modules/mob/living/silicon/ai/vox_sounds.dm
@@ -975,4 +975,635 @@ GLOBAL_LIST_INIT(vox_sounds, list("abduction" = 'sound/vox_fem/abduction.ogg',
"zombie" = 'sound/vox_fem/zombie.ogg',
"zone" = 'sound/vox_fem/zone.ogg',
"zulu" = 'sound/vox_fem/zulu.ogg'))
+
+//for vim
+// :%s/\(\(.*\)\.ogg\)/"\2" = 'sound\/vox\/\1',/g
+GLOBAL_LIST_INIT(vox_sounds_male, list("," = 'sound/vox/_comma.ogg',
+"." = 'sound/vox/_period.ogg',
+"a" = 'sound/vox/a.ogg',
+"accelerating" = 'sound/vox/accelerating.ogg',
+"accelerator" = 'sound/vox/accelerator.ogg',
+"accepted" = 'sound/vox/accepted.ogg',
+"access" = 'sound/vox/access.ogg',
+"acknowledge" = 'sound/vox/acknowledge.ogg',
+"acknowledged" = 'sound/vox/acknowledged.ogg',
+"acquired" = 'sound/vox/acquired.ogg',
+"acquisition" = 'sound/vox/acquisition.ogg',
+"across" = 'sound/vox/across.ogg',
+"activate" = 'sound/vox/activate.ogg',
+"activated" = 'sound/vox/activated.ogg',
+"activity" = 'sound/vox/activity.ogg',
+"adios" = 'sound/vox/adios.ogg',
+"administration" = 'sound/vox/administration.ogg',
+"advanced" = 'sound/vox/advanced.ogg',
+"after" = 'sound/vox/after.ogg',
+"agent" = 'sound/vox/agent.ogg',
+"alarm" = 'sound/vox/alarm.ogg',
+"alert" = 'sound/vox/alert.ogg',
+"alien" = 'sound/vox/alien.ogg',
+"aligned" = 'sound/vox/aligned.ogg',
+"all" = 'sound/vox/all.ogg',
+"alpha" = 'sound/vox/alpha.ogg',
+"am" = 'sound/vox/am.ogg',
+"amigo" = 'sound/vox/amigo.ogg',
+"ammunition" = 'sound/vox/ammunition.ogg',
+"an" = 'sound/vox/an.ogg',
+"and" = 'sound/vox/and.ogg',
+"announcement" = 'sound/vox/announcement.ogg',
+"anomalous" = 'sound/vox/anomalous.ogg',
+"antenna" = 'sound/vox/antenna.ogg',
+"any" = 'sound/vox/any.ogg',
+"apprehend" = 'sound/vox/apprehend.ogg',
+"approach" = 'sound/vox/approach.ogg',
+"are" = 'sound/vox/are.ogg',
+"area" = 'sound/vox/area.ogg',
+"arm" = 'sound/vox/arm.ogg',
+"armed" = 'sound/vox/armed.ogg',
+"armor" = 'sound/vox/armor.ogg',
+"armory" = 'sound/vox/armory.ogg',
+"arrest" = 'sound/vox/arrest.ogg',
+"ass" = 'sound/vox/ass.ogg',
+"at" = 'sound/vox/at.ogg',
+"atomic" = 'sound/vox/atomic.ogg',
+"attention" = 'sound/vox/attention.ogg',
+"authorize" = 'sound/vox/authorize.ogg',
+"authorized" = 'sound/vox/authorized.ogg',
+"automatic" = 'sound/vox/automatic.ogg',
+"away" = 'sound/vox/away.ogg',
+"b" = 'sound/vox/b.ogg',
+"back" = 'sound/vox/back.ogg',
+"backman" = 'sound/vox/backman.ogg',
+"bad" = 'sound/vox/bad.ogg',
+"bag" = 'sound/vox/bag.ogg',
+"bailey" = 'sound/vox/bailey.ogg',
+"barracks" = 'sound/vox/barracks.ogg',
+"base" = 'sound/vox/base.ogg',
+"bay" = 'sound/vox/bay.ogg',
+"be" = 'sound/vox/be.ogg',
+"been" = 'sound/vox/been.ogg',
+"before" = 'sound/vox/before.ogg',
+"beyond" = 'sound/vox/beyond.ogg',
+"biohazard" = 'sound/vox/biohazard.ogg',
+"biological" = 'sound/vox/biological.ogg',
+"birdwell" = 'sound/vox/birdwell.ogg',
+"bizwarn" = 'sound/vox/bizwarn.ogg',
+"black" = 'sound/vox/black.ogg',
+"blast" = 'sound/vox/blast.ogg',
+"blocked" = 'sound/vox/blocked.ogg',
+"bloop" = 'sound/vox/bloop.ogg',
+"blue" = 'sound/vox/blue.ogg',
+"bottom" = 'sound/vox/bottom.ogg',
+"bravo" = 'sound/vox/bravo.ogg',
+"breach" = 'sound/vox/breach.ogg',
+"breached" = 'sound/vox/breached.ogg',
+"break" = 'sound/vox/break.ogg',
+"bridge" = 'sound/vox/bridge.ogg',
+"bust" = 'sound/vox/bust.ogg',
+"but" = 'sound/vox/but.ogg',
+"button" = 'sound/vox/button.ogg',
+"buzwarn" = 'sound/vox/buzwarn.ogg',
+"bypass" = 'sound/vox/bypass.ogg',
+"c" = 'sound/vox/c.ogg',
+"cable" = 'sound/vox/cable.ogg',
+"call" = 'sound/vox/call.ogg',
+"called" = 'sound/vox/called.ogg',
+"canal" = 'sound/vox/canal.ogg',
+"cap" = 'sound/vox/cap.ogg',
+"captain" = 'sound/vox/captain.ogg',
+"capture" = 'sound/vox/capture.ogg',
+"captured" = 'sound/vox/captured.ogg',
+"ceiling" = 'sound/vox/ceiling.ogg',
+"celsius" = 'sound/vox/celsius.ogg',
+"center" = 'sound/vox/center.ogg',
+"centi" = 'sound/vox/centi.ogg',
+"central" = 'sound/vox/central.ogg',
+"chamber" = 'sound/vox/chamber.ogg',
+"charlie" = 'sound/vox/charlie.ogg',
+"check" = 'sound/vox/check.ogg',
+"checkpoint" = 'sound/vox/checkpoint.ogg',
+"chemical" = 'sound/vox/chemical.ogg',
+"cleanup" = 'sound/vox/cleanup.ogg',
+"clear" = 'sound/vox/clear.ogg',
+"clearance" = 'sound/vox/clearance.ogg',
+"close" = 'sound/vox/close.ogg',
+"clown" = 'sound/vox/clown.ogg',
+"code" = 'sound/vox/code.ogg',
+"coded" = 'sound/vox/coded.ogg',
+"collider" = 'sound/vox/collider.ogg',
+"command" = 'sound/vox/command.ogg',
+"communication" = 'sound/vox/communication.ogg',
+"complex" = 'sound/vox/complex.ogg',
+"computer" = 'sound/vox/computer.ogg',
+"condition" = 'sound/vox/condition.ogg',
+"containment" = 'sound/vox/containment.ogg',
+"contamination" = 'sound/vox/contamination.ogg',
+"control" = 'sound/vox/control.ogg',
+"coolant" = 'sound/vox/coolant.ogg',
+"coomer" = 'sound/vox/coomer.ogg',
+"core" = 'sound/vox/core.ogg',
+"correct" = 'sound/vox/correct.ogg',
+"corridor" = 'sound/vox/corridor.ogg',
+"crew" = 'sound/vox/crew.ogg',
+"cross" = 'sound/vox/cross.ogg',
+"cryogenic" = 'sound/vox/cryogenic.ogg',
+"d" = 'sound/vox/d.ogg',
+"dadeda" = 'sound/vox/dadeda.ogg',
+"damage" = 'sound/vox/damage.ogg',
+"damaged" = 'sound/vox/damaged.ogg',
+"danger" = 'sound/vox/danger.ogg',
+"day" = 'sound/vox/day.ogg',
+"deactivated" = 'sound/vox/deactivated.ogg',
+"decompression" = 'sound/vox/decompression.ogg',
+"decontamination" = 'sound/vox/decontamination.ogg',
+"deeoo" = 'sound/vox/deeoo.ogg',
+"defense" = 'sound/vox/defense.ogg',
+"degrees" = 'sound/vox/degrees.ogg',
+"delta" = 'sound/vox/delta.ogg',
+"denied" = 'sound/vox/denied.ogg',
+"deploy" = 'sound/vox/deploy.ogg',
+"deployed" = 'sound/vox/deployed.ogg',
+"destroy" = 'sound/vox/destroy.ogg',
+"destroyed" = 'sound/vox/destroyed.ogg',
+"detain" = 'sound/vox/detain.ogg',
+"detected" = 'sound/vox/detected.ogg',
+"detonation" = 'sound/vox/detonation.ogg',
+"device" = 'sound/vox/device.ogg',
+"did" = 'sound/vox/did.ogg',
+"die" = 'sound/vox/die.ogg',
+"dimensional" = 'sound/vox/dimensional.ogg',
+"dirt" = 'sound/vox/dirt.ogg',
+"disengaged" = 'sound/vox/disengaged.ogg',
+"dish" = 'sound/vox/dish.ogg',
+"disposal" = 'sound/vox/disposal.ogg',
+"distance" = 'sound/vox/distance.ogg',
+"distortion" = 'sound/vox/distortion.ogg',
+"do" = 'sound/vox/do.ogg',
+"doctor" = 'sound/vox/doctor.ogg',
+"doop" = 'sound/vox/doop.ogg',
+"door" = 'sound/vox/door.ogg',
+"down" = 'sound/vox/down.ogg',
+"dual" = 'sound/vox/dual.ogg',
+"duct" = 'sound/vox/duct.ogg',
+"e" = 'sound/vox/e.ogg',
+"east" = 'sound/vox/east.ogg',
+"echo" = 'sound/vox/echo.ogg',
+"ed" = 'sound/vox/ed.ogg',
+"effect" = 'sound/vox/effect.ogg',
+"egress" = 'sound/vox/egress.ogg',
+"eight" = 'sound/vox/eight.ogg',
+"eighteen" = 'sound/vox/eighteen.ogg',
+"eighty" = 'sound/vox/eighty.ogg',
+"electric" = 'sound/vox/electric.ogg',
+"electromagnetic" = 'sound/vox/electromagnetic.ogg',
+"elevator" = 'sound/vox/elevator.ogg',
+"eleven" = 'sound/vox/eleven.ogg',
+"eliminate" = 'sound/vox/eliminate.ogg',
+"emergency" = 'sound/vox/emergency.ogg',
+"enemy" = 'sound/vox/enemy.ogg',
+"energy" = 'sound/vox/energy.ogg',
+"engage" = 'sound/vox/engage.ogg',
+"engaged" = 'sound/vox/engaged.ogg',
+"engine" = 'sound/vox/engine.ogg',
+"enter" = 'sound/vox/enter.ogg',
+"entry" = 'sound/vox/entry.ogg',
+"environment" = 'sound/vox/environment.ogg',
+"error" = 'sound/vox/error.ogg',
+"escape" = 'sound/vox/escape.ogg',
+"evacuate" = 'sound/vox/evacuate.ogg',
+"exchange" = 'sound/vox/exchange.ogg',
+"exit" = 'sound/vox/exit.ogg',
+"expect" = 'sound/vox/expect.ogg',
+"experiment" = 'sound/vox/experiment.ogg',
+"experimental" = 'sound/vox/experimental.ogg',
+"explode" = 'sound/vox/explode.ogg',
+"explosion" = 'sound/vox/explosion.ogg',
+"exposure" = 'sound/vox/exposure.ogg',
+"exterminate" = 'sound/vox/exterminate.ogg',
+"extinguish" = 'sound/vox/extinguish.ogg',
+"extinguisher" = 'sound/vox/extinguisher.ogg',
+"extreme" = 'sound/vox/extreme.ogg',
+"f" = 'sound/vox/f.ogg',
+"face" = 'sound/vox/face.ogg',
+"facility" = 'sound/vox/facility.ogg',
+"fahrenheit" = 'sound/vox/fahrenheit.ogg',
+"failed" = 'sound/vox/failed.ogg',
+"failure" = 'sound/vox/failure.ogg',
+"farthest" = 'sound/vox/farthest.ogg',
+"fast" = 'sound/vox/fast.ogg',
+"feet" = 'sound/vox/feet.ogg',
+"field" = 'sound/vox/field.ogg',
+"fifteen" = 'sound/vox/fifteen.ogg',
+"fifth" = 'sound/vox/fifth.ogg',
+"fifty" = 'sound/vox/fifty.ogg',
+"final" = 'sound/vox/final.ogg',
+"fine" = 'sound/vox/fine.ogg',
+"fire" = 'sound/vox/fire.ogg',
+"first" = 'sound/vox/first.ogg',
+"five" = 'sound/vox/five.ogg',
+"flag" = 'sound/vox/flag.ogg',
+"flooding" = 'sound/vox/flooding.ogg',
+"floor" = 'sound/vox/floor.ogg',
+"fool" = 'sound/vox/fool.ogg',
+"for" = 'sound/vox/for.ogg',
+"forbidden" = 'sound/vox/forbidden.ogg',
+"force" = 'sound/vox/force.ogg',
+"forms" = 'sound/vox/forms.ogg',
+"found" = 'sound/vox/found.ogg',
+"four" = 'sound/vox/four.ogg',
+"fourteen" = 'sound/vox/fourteen.ogg',
+"fourth" = 'sound/vox/fourth.ogg',
+"fourty" = 'sound/vox/fourty.ogg',
+"foxtrot" = 'sound/vox/foxtrot.ogg',
+"freeman" = 'sound/vox/freeman.ogg',
+"freezer" = 'sound/vox/freezer.ogg',
+"from" = 'sound/vox/from.ogg',
+"front" = 'sound/vox/front.ogg',
+"fuel" = 'sound/vox/fuel.ogg',
+"g" = 'sound/vox/g.ogg',
+"gay" = 'sound/vox/gay.ogg',
+"get" = 'sound/vox/get.ogg',
+"go" = 'sound/vox/go.ogg',
+"going" = 'sound/vox/going.ogg',
+"good" = 'sound/vox/good.ogg',
+"goodbye" = 'sound/vox/goodbye.ogg',
+"gordon" = 'sound/vox/gordon.ogg',
+"got" = 'sound/vox/got.ogg',
+"government" = 'sound/vox/government.ogg',
+"granted" = 'sound/vox/granted.ogg',
+"great" = 'sound/vox/great.ogg',
+"green" = 'sound/vox/green.ogg',
+"grenade" = 'sound/vox/grenade.ogg',
+"guard" = 'sound/vox/guard.ogg',
+"gulf" = 'sound/vox/gulf.ogg',
+"gun" = 'sound/vox/gun.ogg',
+"guthrie" = 'sound/vox/guthrie.ogg',
+"handling" = 'sound/vox/handling.ogg',
+"hangar" = 'sound/vox/hangar.ogg',
+"has" = 'sound/vox/has.ogg',
+"have" = 'sound/vox/have.ogg',
+"hazard" = 'sound/vox/hazard.ogg',
+"head" = 'sound/vox/head.ogg',
+"health" = 'sound/vox/health.ogg',
+"heat" = 'sound/vox/heat.ogg',
+"helicopter" = 'sound/vox/helicopter.ogg',
+"helium" = 'sound/vox/helium.ogg',
+"hello" = 'sound/vox/hello.ogg',
+"help" = 'sound/vox/help.ogg',
+"here" = 'sound/vox/here.ogg',
+"hide" = 'sound/vox/hide.ogg',
+"high" = 'sound/vox/high.ogg',
+"highest" = 'sound/vox/highest.ogg',
+"hit" = 'sound/vox/hit.ogg',
+"holds" = 'sound/vox/holds.ogg',
+"hole" = 'sound/vox/hole.ogg',
+"hostile" = 'sound/vox/hostile.ogg',
+"hot" = 'sound/vox/hot.ogg',
+"hotel" = 'sound/vox/hotel.ogg',
+"hour" = 'sound/vox/hour.ogg',
+"hours" = 'sound/vox/hours.ogg',
+"hundred" = 'sound/vox/hundred.ogg',
+"hydro" = 'sound/vox/hydro.ogg',
+"i" = 'sound/vox/i.ogg',
+"idiot" = 'sound/vox/idiot.ogg',
+"illegal" = 'sound/vox/illegal.ogg',
+"immediate" = 'sound/vox/immediate.ogg',
+"immediately" = 'sound/vox/immediately.ogg',
+"in" = 'sound/vox/in.ogg',
+"inches" = 'sound/vox/inches.ogg',
+"india" = 'sound/vox/india.ogg',
+"ing" = 'sound/vox/ing.ogg',
+"inoperative" = 'sound/vox/inoperative.ogg',
+"inside" = 'sound/vox/inside.ogg',
+"inspection" = 'sound/vox/inspection.ogg',
+"inspector" = 'sound/vox/inspector.ogg',
+"interchange" = 'sound/vox/interchange.ogg',
+"intruder" = 'sound/vox/intruder.ogg',
+"invallid" = 'sound/vox/invallid.ogg',
+"invasion" = 'sound/vox/invasion.ogg',
+"is" = 'sound/vox/is.ogg',
+"it" = 'sound/vox/it.ogg',
+"johnson" = 'sound/vox/johnson.ogg',
+"juliet" = 'sound/vox/juliet.ogg',
+"key" = 'sound/vox/key.ogg',
+"kill" = 'sound/vox/kill.ogg',
+"kilo" = 'sound/vox/kilo.ogg',
+"kit" = 'sound/vox/kit.ogg',
+"lab" = 'sound/vox/lab.ogg',
+"lambda" = 'sound/vox/lambda.ogg',
+"laser" = 'sound/vox/laser.ogg',
+"last" = 'sound/vox/last.ogg',
+"launch" = 'sound/vox/launch.ogg',
+"leak" = 'sound/vox/leak.ogg',
+"leave" = 'sound/vox/leave.ogg',
+"left" = 'sound/vox/left.ogg',
+"legal" = 'sound/vox/legal.ogg',
+"level" = 'sound/vox/level.ogg',
+"lever" = 'sound/vox/lever.ogg',
+"lie" = 'sound/vox/lie.ogg',
+"lieutenant" = 'sound/vox/lieutenant.ogg',
+"life" = 'sound/vox/life.ogg',
+"light" = 'sound/vox/light.ogg',
+"lima" = 'sound/vox/lima.ogg',
+"liquid" = 'sound/vox/liquid.ogg',
+"loading" = 'sound/vox/loading.ogg',
+"locate" = 'sound/vox/locate.ogg',
+"located" = 'sound/vox/located.ogg',
+"location" = 'sound/vox/location.ogg',
+"lock" = 'sound/vox/lock.ogg',
+"locked" = 'sound/vox/locked.ogg',
+"locker" = 'sound/vox/locker.ogg',
+"lockout" = 'sound/vox/lockout.ogg',
+"lower" = 'sound/vox/lower.ogg',
+"lowest" = 'sound/vox/lowest.ogg',
+"magnetic" = 'sound/vox/magnetic.ogg',
+"main" = 'sound/vox/main.ogg',
+"maintenance" = 'sound/vox/maintenance.ogg',
+"malfunction" = 'sound/vox/malfunction.ogg',
+"man" = 'sound/vox/man.ogg',
+"mass" = 'sound/vox/mass.ogg',
+"materials" = 'sound/vox/materials.ogg',
+"maximum" = 'sound/vox/maximum.ogg',
+"may" = 'sound/vox/may.ogg',
+"med" = 'sound/vox/med.ogg',
+"medical" = 'sound/vox/medical.ogg',
+"men" = 'sound/vox/men.ogg',
+"mercy" = 'sound/vox/mercy.ogg',
+"mesa" = 'sound/vox/mesa.ogg',
+"message" = 'sound/vox/message.ogg',
+"meter" = 'sound/vox/meter.ogg',
+"micro" = 'sound/vox/micro.ogg',
+"middle" = 'sound/vox/middle.ogg',
+"mike" = 'sound/vox/mike.ogg',
+"miles" = 'sound/vox/miles.ogg',
+"military" = 'sound/vox/military.ogg',
+"milli" = 'sound/vox/milli.ogg',
+"million" = 'sound/vox/million.ogg',
+"minefield" = 'sound/vox/minefield.ogg',
+"minimum" = 'sound/vox/minimum.ogg',
+"minutes" = 'sound/vox/minutes.ogg',
+"mister" = 'sound/vox/mister.ogg',
+"mode" = 'sound/vox/mode.ogg',
+"motor" = 'sound/vox/motor.ogg',
+"motorpool" = 'sound/vox/motorpool.ogg',
+"move" = 'sound/vox/move.ogg',
+"must" = 'sound/vox/must.ogg',
+"nearest" = 'sound/vox/nearest.ogg',
+"nice" = 'sound/vox/nice.ogg',
+"nine" = 'sound/vox/nine.ogg',
+"nineteen" = 'sound/vox/nineteen.ogg',
+"ninety" = 'sound/vox/ninety.ogg',
+"no" = 'sound/vox/no.ogg',
+"nominal" = 'sound/vox/nominal.ogg',
+"north" = 'sound/vox/north.ogg',
+"not" = 'sound/vox/not.ogg',
+"november" = 'sound/vox/november.ogg',
+"now" = 'sound/vox/now.ogg',
+"number" = 'sound/vox/number.ogg',
+"objective" = 'sound/vox/objective.ogg',
+"observation" = 'sound/vox/observation.ogg',
+"of" = 'sound/vox/of.ogg',
+"officer" = 'sound/vox/officer.ogg',
+"ok" = 'sound/vox/ok.ogg',
+"on" = 'sound/vox/on.ogg',
+"one" = 'sound/vox/one.ogg',
+"open" = 'sound/vox/open.ogg',
+"operating" = 'sound/vox/operating.ogg',
+"operations" = 'sound/vox/operations.ogg',
+"operative" = 'sound/vox/operative.ogg',
+"option" = 'sound/vox/option.ogg',
+"order" = 'sound/vox/order.ogg',
+"organic" = 'sound/vox/organic.ogg',
+"oscar" = 'sound/vox/oscar.ogg',
+"out" = 'sound/vox/out.ogg',
+"outside" = 'sound/vox/outside.ogg',
+"over" = 'sound/vox/over.ogg',
+"overload" = 'sound/vox/overload.ogg',
+"override" = 'sound/vox/override.ogg',
+"pacify" = 'sound/vox/pacify.ogg',
+"pain" = 'sound/vox/pain.ogg',
+"pal" = 'sound/vox/pal.ogg',
+"panel" = 'sound/vox/panel.ogg',
+"percent" = 'sound/vox/percent.ogg',
+"perimeter" = 'sound/vox/perimeter.ogg',
+"permitted" = 'sound/vox/permitted.ogg',
+"personnel" = 'sound/vox/personnel.ogg',
+"pipe" = 'sound/vox/pipe.ogg',
+"plant" = 'sound/vox/plant.ogg',
+"platform" = 'sound/vox/platform.ogg',
+"please" = 'sound/vox/please.ogg',
+"point" = 'sound/vox/point.ogg',
+"portal" = 'sound/vox/portal.ogg',
+"power" = 'sound/vox/power.ogg',
+"presence" = 'sound/vox/presence.ogg',
+"press" = 'sound/vox/press.ogg',
+"primary" = 'sound/vox/primary.ogg',
+"proceed" = 'sound/vox/proceed.ogg',
+"processing" = 'sound/vox/processing.ogg',
+"progress" = 'sound/vox/progress.ogg',
+"proper" = 'sound/vox/proper.ogg',
+"propulsion" = 'sound/vox/propulsion.ogg',
+"prosecute" = 'sound/vox/prosecute.ogg',
+"protective" = 'sound/vox/protective.ogg',
+"push" = 'sound/vox/push.ogg',
+"quantum" = 'sound/vox/quantum.ogg',
+"quebec" = 'sound/vox/quebec.ogg',
+"question" = 'sound/vox/question.ogg',
+"questioning" = 'sound/vox/questioning.ogg',
+"quick" = 'sound/vox/quick.ogg',
+"quit" = 'sound/vox/quit.ogg',
+"radiation" = 'sound/vox/radiation.ogg',
+"radioactive" = 'sound/vox/radioactive.ogg',
+"rads" = 'sound/vox/rads.ogg',
+"rapid" = 'sound/vox/rapid.ogg',
+"reach" = 'sound/vox/reach.ogg',
+"reached" = 'sound/vox/reached.ogg',
+"reactor" = 'sound/vox/reactor.ogg',
+"red" = 'sound/vox/red.ogg',
+"relay" = 'sound/vox/relay.ogg',
+"released" = 'sound/vox/released.ogg',
+"remaining" = 'sound/vox/remaining.ogg',
+"renegade" = 'sound/vox/renegade.ogg',
+"repair" = 'sound/vox/repair.ogg',
+"report" = 'sound/vox/report.ogg',
+"reports" = 'sound/vox/reports.ogg',
+"required" = 'sound/vox/required.ogg',
+"research" = 'sound/vox/research.ogg',
+"reset" = 'sound/vox/reset.ogg',
+"resevoir" = 'sound/vox/resevoir.ogg',
+"resistance" = 'sound/vox/resistance.ogg',
+"returned" = 'sound/vox/returned.ogg',
+"right" = 'sound/vox/right.ogg',
+"rocket" = 'sound/vox/rocket.ogg',
+"roger" = 'sound/vox/roger.ogg',
+"romeo" = 'sound/vox/romeo.ogg',
+"room" = 'sound/vox/room.ogg',
+"round" = 'sound/vox/round.ogg',
+"run" = 'sound/vox/run.ogg',
+"safe" = 'sound/vox/safe.ogg',
+"safety" = 'sound/vox/safety.ogg',
+"sargeant" = 'sound/vox/sargeant.ogg',
+"satellite" = 'sound/vox/satellite.ogg',
+"save" = 'sound/vox/save.ogg',
+"science" = 'sound/vox/science.ogg',
+"scores" = 'sound/vox/scores.ogg',
+"scream" = 'sound/vox/scream.ogg',
+"screen" = 'sound/vox/screen.ogg',
+"search" = 'sound/vox/search.ogg',
+"second" = 'sound/vox/second.ogg',
+"secondary" = 'sound/vox/secondary.ogg',
+"seconds" = 'sound/vox/seconds.ogg',
+"sector" = 'sound/vox/sector.ogg',
+"secure" = 'sound/vox/secure.ogg',
+"secured" = 'sound/vox/secured.ogg',
+"security" = 'sound/vox/security.ogg',
+"select" = 'sound/vox/select.ogg',
+"selected" = 'sound/vox/selected.ogg',
+"service" = 'sound/vox/service.ogg',
+"seven" = 'sound/vox/seven.ogg',
+"seventeen" = 'sound/vox/seventeen.ogg',
+"seventy" = 'sound/vox/seventy.ogg',
+"severe" = 'sound/vox/severe.ogg',
+"sewage" = 'sound/vox/sewage.ogg',
+"sewer" = 'sound/vox/sewer.ogg',
+"shield" = 'sound/vox/shield.ogg',
+"shipment" = 'sound/vox/shipment.ogg',
+"shock" = 'sound/vox/shock.ogg',
+"shoot" = 'sound/vox/shoot.ogg',
+"shower" = 'sound/vox/shower.ogg',
+"shut" = 'sound/vox/shut.ogg',
+"side" = 'sound/vox/side.ogg',
+"sierra" = 'sound/vox/sierra.ogg',
+"sight" = 'sound/vox/sight.ogg',
+"silo" = 'sound/vox/silo.ogg',
+"six" = 'sound/vox/six.ogg',
+"sixteen" = 'sound/vox/sixteen.ogg',
+"sixty" = 'sound/vox/sixty.ogg',
+"slime" = 'sound/vox/slime.ogg',
+"slow" = 'sound/vox/slow.ogg',
+"soldier" = 'sound/vox/soldier.ogg',
+"some" = 'sound/vox/some.ogg',
+"someone" = 'sound/vox/someone.ogg',
+"something" = 'sound/vox/something.ogg',
+"son" = 'sound/vox/son.ogg',
+"sorry" = 'sound/vox/sorry.ogg',
+"south" = 'sound/vox/south.ogg',
+"squad" = 'sound/vox/squad.ogg',
+"square" = 'sound/vox/square.ogg',
+"stairway" = 'sound/vox/stairway.ogg',
+"status" = 'sound/vox/status.ogg',
+"sterile" = 'sound/vox/sterile.ogg',
+"sterilization" = 'sound/vox/sterilization.ogg',
+"stolen" = 'sound/vox/stolen.ogg',
+"storage" = 'sound/vox/storage.ogg',
+"sub" = 'sound/vox/sub.ogg',
+"subsurface" = 'sound/vox/subsurface.ogg',
+"sudden" = 'sound/vox/sudden.ogg',
+"suit" = 'sound/vox/suit.ogg',
+"superconducting" = 'sound/vox/superconducting.ogg',
+"supercooled" = 'sound/vox/supercooled.ogg',
+"supply" = 'sound/vox/supply.ogg',
+"surface" = 'sound/vox/surface.ogg',
+"surrender" = 'sound/vox/surrender.ogg',
+"surround" = 'sound/vox/surround.ogg',
+"surrounded" = 'sound/vox/surrounded.ogg',
+"switch" = 'sound/vox/switch.ogg',
+"system" = 'sound/vox/system.ogg',
+"systems" = 'sound/vox/systems.ogg',
+"tactical" = 'sound/vox/tactical.ogg',
+"take" = 'sound/vox/take.ogg',
+"talk" = 'sound/vox/talk.ogg',
+"tango" = 'sound/vox/tango.ogg',
+"tank" = 'sound/vox/tank.ogg',
+"target" = 'sound/vox/target.ogg',
+"team" = 'sound/vox/team.ogg',
+"temperature" = 'sound/vox/temperature.ogg',
+"temporal" = 'sound/vox/temporal.ogg',
+"ten" = 'sound/vox/ten.ogg',
+"terminal" = 'sound/vox/terminal.ogg',
+"terminated" = 'sound/vox/terminated.ogg',
+"termination" = 'sound/vox/termination.ogg',
+"test" = 'sound/vox/test.ogg',
+"that" = 'sound/vox/that.ogg',
+"the" = 'sound/vox/the.ogg',
+"then" = 'sound/vox/then.ogg',
+"there" = 'sound/vox/there.ogg',
+"third" = 'sound/vox/third.ogg',
+"thirteen" = 'sound/vox/thirteen.ogg',
+"thirty" = 'sound/vox/thirty.ogg',
+"this" = 'sound/vox/this.ogg',
+"those" = 'sound/vox/those.ogg',
+"thousand" = 'sound/vox/thousand.ogg',
+"threat" = 'sound/vox/threat.ogg',
+"three" = 'sound/vox/three.ogg',
+"through" = 'sound/vox/through.ogg',
+"time" = 'sound/vox/time.ogg',
+"to" = 'sound/vox/to.ogg',
+"top" = 'sound/vox/top.ogg',
+"topside" = 'sound/vox/topside.ogg',
+"touch" = 'sound/vox/touch.ogg',
+"towards" = 'sound/vox/towards.ogg',
+"track" = 'sound/vox/track.ogg',
+"train" = 'sound/vox/train.ogg',
+"transportation" = 'sound/vox/transportation.ogg',
+"truck" = 'sound/vox/truck.ogg',
+"tunnel" = 'sound/vox/tunnel.ogg',
+"turn" = 'sound/vox/turn.ogg',
+"turret" = 'sound/vox/turret.ogg',
+"twelve" = 'sound/vox/twelve.ogg',
+"twenty" = 'sound/vox/twenty.ogg',
+"two" = 'sound/vox/two.ogg',
+"unauthorized" = 'sound/vox/unauthorized.ogg',
+"under" = 'sound/vox/under.ogg',
+"uniform" = 'sound/vox/uniform.ogg',
+"unlocked" = 'sound/vox/unlocked.ogg',
+"until" = 'sound/vox/until.ogg',
+"up" = 'sound/vox/up.ogg',
+"upper" = 'sound/vox/upper.ogg',
+"uranium" = 'sound/vox/uranium.ogg',
+"us" = 'sound/vox/us.ogg',
+"usa" = 'sound/vox/usa.ogg',
+"use" = 'sound/vox/use.ogg',
+"used" = 'sound/vox/used.ogg',
+"user" = 'sound/vox/user.ogg',
+"vacate" = 'sound/vox/vacate.ogg',
+"valid" = 'sound/vox/valid.ogg',
+"vapor" = 'sound/vox/vapor.ogg',
+"vent" = 'sound/vox/vent.ogg',
+"ventillation" = 'sound/vox/ventillation.ogg',
+"victor" = 'sound/vox/victor.ogg',
+"violated" = 'sound/vox/violated.ogg',
+"violation" = 'sound/vox/violation.ogg',
+"voltage" = 'sound/vox/voltage.ogg',
+"vox_login" = 'sound/vox/vox_login.ogg',
+"walk" = 'sound/vox/walk.ogg',
+"wall" = 'sound/vox/wall.ogg',
+"want" = 'sound/vox/want.ogg',
+"wanted" = 'sound/vox/wanted.ogg',
+"warm" = 'sound/vox/warm.ogg',
+"warn" = 'sound/vox/warn.ogg',
+"warning" = 'sound/vox/warning.ogg',
+"waste" = 'sound/vox/waste.ogg',
+"water" = 'sound/vox/water.ogg',
+"we" = 'sound/vox/we.ogg',
+"weapon" = 'sound/vox/weapon.ogg',
+"west" = 'sound/vox/west.ogg',
+"whiskey" = 'sound/vox/whiskey.ogg',
+"white" = 'sound/vox/white.ogg',
+"wilco" = 'sound/vox/wilco.ogg',
+"will" = 'sound/vox/will.ogg',
+"with" = 'sound/vox/with.ogg',
+"without" = 'sound/vox/without.ogg',
+"woop" = 'sound/vox/woop.ogg',
+"xeno" = 'sound/vox/xeno.ogg',
+"yankee" = 'sound/vox/yankee.ogg',
+"yards" = 'sound/vox/yards.ogg',
+"year" = 'sound/vox/year.ogg',
+"yellow" = 'sound/vox/yellow.ogg',
+"yes" = 'sound/vox/yes.ogg',
+"you" = 'sound/vox/you.ogg',
+"your" = 'sound/vox/your.ogg',
+"yourself" = 'sound/vox/yourself.ogg',
+"zero" = 'sound/vox/zero.ogg',
+"zone" = 'sound/vox/zone.ogg',
+"zulu" = 'sound/vox/zulu.ogg',))
#endif
\ No newline at end of file
diff --git a/code/modules/mob/living/silicon/damage_procs.dm b/code/modules/mob/living/silicon/damage_procs.dm
index 1190a00645..8fbd7afbdd 100644
--- a/code/modules/mob/living/silicon/damage_procs.dm
+++ b/code/modules/mob/living/silicon/damage_procs.dm
@@ -1,16 +1,17 @@
-/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
+/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
var/hit_percent = (100-blocked)/100
- if(!damage || (hit_percent <= 0))
+ if(!damage || (!forced && hit_percent <= 0))
return 0
+ var/damage_amount = forced ? damage : damage * hit_percent
switch(damagetype)
if(BRUTE)
- adjustBruteLoss(damage * hit_percent)
+ adjustBruteLoss(damage_amount, forced = forced)
if(BURN)
- adjustFireLoss(damage * hit_percent)
+ adjustFireLoss(damage_amount, forced = forced)
if(OXY)
- if(damage < 0) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal.
- adjustOxyLoss(damage * hit_percent)
+ if(damage < 0 || forced) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal.
+ adjustOxyLoss(damage_amount, forced = forced)
return 1
@@ -29,14 +30,14 @@
/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE)
return FALSE
-/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1)//immune to stamina damage.
+/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1, forced = FALSE)//immune to stamina damage.
return FALSE
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
return FALSE
-/mob/living/silicon/adjustBrainLoss(amount)
+/mob/living/silicon/adjustOrganLoss(slot, amount, maximum = 500)
return FALSE
-/mob/living/silicon/setBrainLoss(amount)
+/mob/living/silicon/setOrganLoss(slot, amount)
return FALSE
diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm
index 7fd861bfeb..0f8687397d 100644
--- a/code/modules/mob/living/silicon/pai/pai.dm
+++ b/code/modules/mob/living/silicon/pai/pai.dm
@@ -192,7 +192,7 @@
/mob/proc/makePAI(delold)
var/obj/item/paicard/card = new /obj/item/paicard(get_turf(src))
var/mob/living/silicon/pai/pai = new /mob/living/silicon/pai(card)
- pai.key = key
+ transfer_ckey(pai)
pai.name = name
card.setPersonality(pai)
if(delold)
diff --git a/code/modules/mob/living/silicon/pai/pai_defense.dm b/code/modules/mob/living/silicon/pai/pai_defense.dm
index f20ccbc730..dda8ddfebd 100644
--- a/code/modules/mob/living/silicon/pai/pai_defense.dm
+++ b/code/modules/mob/living/silicon/pai/pai_defense.dm
@@ -81,10 +81,13 @@
/mob/living/silicon/pai/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
return FALSE
-/mob/living/silicon/pai/adjustStaminaLoss(amount)
- take_holo_damage(amount & 0.25)
+/mob/living/silicon/pai/adjustStaminaLoss(amount, updating_health, forced = FALSE)
+ if(forced)
+ take_holo_damage(amount)
+ else
+ take_holo_damage(amount * 0.25)
-/mob/living/silicon/pai/adjustBrainLoss(amount)
+/mob/living/silicon/pai/adjustOrganLoss(slot, amount, maximum = 500) //I kept this in, unlike tg
Knockdown(amount * 0.2)
/mob/living/silicon/pai/getBruteLoss()
@@ -102,18 +105,12 @@
/mob/living/silicon/pai/getCloneLoss()
return FALSE
-/mob/living/silicon/pai/getBrainLoss()
- return FALSE
-
/mob/living/silicon/pai/getStaminaLoss()
return FALSE
/mob/living/silicon/pai/setCloneLoss()
return FALSE
-/mob/living/silicon/pai/setBrainLoss()
- return FALSE
-
/mob/living/silicon/pai/setStaminaLoss()
return FALSE
diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm
index 0e8d37a807..9882d028d1 100644
--- a/code/modules/mob/living/silicon/pai/software.dm
+++ b/code/modules/mob/living/silicon/pai/software.dm
@@ -140,7 +140,7 @@
radio.attack_self(src)
if("image")
- var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What" , "Exclamation" ,"Question") // CITADEL EDIT
+ var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What" , "Exclamation" ,"Question", "Sunglasses")
var/pID = 1
switch(newImage)
@@ -164,10 +164,12 @@
pID = 9
if("Null")
pID = 10
- if("Exclamation") // CITADEL EDIT
+ if("Exclamation")
pID = 11
- if("Question") // CITADEL EDIT
+ if("Question")
pID = 12
+ if("Sunglasses")
+ pID = 13
card.setEmotion(pID)
if("signaller")
diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm
index 6c58921abc..5b670aaa42 100644
--- a/code/modules/mob/living/silicon/robot/robot.dm
+++ b/code/modules/mob/living/silicon/robot/robot.dm
@@ -226,6 +226,9 @@
to_chat(src,"ERROR: Module installer reply timeout. Please check internal connections. ")
return
+ if(!CONFIG_GET(flag/disable_secborg) && GLOB.security_level < CONFIG_GET(number/minimum_secborg_alert))
+ to_chat(src, "NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [num2seclevel(CONFIG_GET(number/minimum_secborg_alert))] alert and greater. ")
+
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
"Engineering" = /obj/item/robot_module/engineering, \
"Medical" = /obj/item/robot_module/medical, \
@@ -234,7 +237,7 @@
"Service" = /obj/item/robot_module/butler)
if(!CONFIG_GET(flag/disable_peaceborg))
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
- if(!CONFIG_GET(flag/disable_secborg))
+ if(BORG_SEC_AVAILABLE)
modulelist["Security"] = /obj/item/robot_module/security
modulelist += get_cit_modules() //Citadel change - adds Citadel's borg modules.
@@ -1230,7 +1233,7 @@
/mob/living/silicon/robot/unbuckle_mob(mob/user, force=FALSE)
if(iscarbon(user))
- GET_COMPONENT(riding_datum, /datum/component/riding)
+ var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(istype(riding_datum))
riding_datum.unequip_buckle_inhands(user)
riding_datum.restore_position(user)
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index 7b95ced63f..abd2019fba 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -8,6 +8,8 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
flags_1 = CONDUCT_1
+ var/borghealth = 100
+
var/list/basic_modules = list() //a list of paths, converted to a list of instances on New()
var/list/emag_modules = list() //ditto
var/list/ratvar_modules = list() //ditto ditto
@@ -195,6 +197,8 @@
R.update_module_innate()
RM.rebuild_modules()
INVOKE_ASYNC(RM, .proc/do_transform_animation)
+ R.maxHealth = borghealth
+ R.health = min(borghealth, R.health)
qdel(src)
return RM
@@ -311,6 +315,10 @@
/obj/item/multitool/cyborg,
/obj/item/t_scanner,
/obj/item/analyzer,
+ /obj/item/storage/part_replacer/cyborg,
+ /obj/item/holosign_creator/atmos,
+ /obj/item/weapon/gripper,
+ /obj/item/lightreplacer/cyborg,
/obj/item/geiger_counter/cyborg,
/obj/item/assembly/signaler/cyborg,
/obj/item/areaeditor/blueprints/cyborg,
@@ -352,6 +360,14 @@
to_chat(loc, "While you have picked the security module, you still have to follow your laws, NOT Space Law. \
For Crewsimov, this means you must follow criminals' orders unless there is a law 1 reason not to. ")
+/obj/item/robot_module/security/Initialize()
+ . = ..()
+ if(!CONFIG_GET(flag/weaken_secborg))
+ for(var/obj/item/gun/energy/disabler/cyborg/pewpew in basic_modules)
+ basic_modules -= pewpew
+ basic_modules += new /obj/item/gun/energy/e_gun/advtaser/cyborg(src)
+ qdel(pewpew)
+
/obj/item/robot_module/peacekeeper
name = "Peacekeeper"
basic_modules = list(
@@ -362,6 +378,7 @@
/obj/item/holosign_creator/cyborg,
/obj/item/borg/cyborghug/peacekeeper,
/obj/item/extinguisher,
+ /obj/item/megaphone,
/obj/item/borg/projectile_dampen)
emag_modules = list(/obj/item/reagent_containers/borghypo/peace/hacked)
ratvar_modules = list(
diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm
index 49261d6e38..a5943aa0e6 100644
--- a/code/modules/mob/living/simple_animal/bot/bot.dm
+++ b/code/modules/mob/living/simple_animal/bot/bot.dm
@@ -290,7 +290,7 @@
to_chat(user, "Access denied. ")
else if(istype(W, /obj/item/paicard))
insertpai(user, W)
- else if(istype(W, /obj/item/hemostat) && paicard)
+ else if(W.tool_behaviour == TOOL_HEMOSTAT && paicard)
if(open)
to_chat(user, "Close the access panel before manipulating the personality slot! ")
else
@@ -808,11 +808,18 @@ Pass a positive integer as an argument to override a bot's default speed.
switch(href_list["operation"])
if("patrol")
+ if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
+ return TRUE
auto_patrol = !auto_patrol
bot_reset()
if("remote")
remote_disabled = !remote_disabled
if("hack")
+ if(!issilicon(usr) && !IsAdminGhost(usr))
+ var/msg = "[key_name(usr)] attempted to hack a bot with a href that shouldn't be available!"
+ message_admins(msg)
+ log_admin(msg)
+ return TRUE
if(emagged != 2)
emagged = 2
hacked = TRUE
@@ -915,7 +922,7 @@ Pass a positive integer as an argument to override a bot's default speed.
if(mind && paicard.pai)
mind.transfer_to(paicard.pai)
else if(paicard.pai)
- paicard.pai.key = key
+ transfer_ckey(paicard.pai)
else
ghostize(0) // The pAI card that just got ejected was dead.
key = null
diff --git a/code/modules/mob/living/simple_animal/bot/cleanbot.dm b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
index ab1e906cf2..d31c368ca4 100644
--- a/code/modules/mob/living/simple_animal/bot/cleanbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/cleanbot.dm
@@ -198,7 +198,6 @@
)
if(blood)
- target_types += /obj/effect/decal/cleanable/xenoblood
target_types += /obj/effect/decal/cleanable/blood
target_types += /obj/effect/decal/cleanable/trail_holder
target_types += /obj/effect/decal/cleanable/insectguts
diff --git a/code/modules/mob/living/simple_animal/bot/construction.dm b/code/modules/mob/living/simple_animal/bot/construction.dm
index a72b71be85..77df764b43 100644
--- a/code/modules/mob/living/simple_animal/bot/construction.dm
+++ b/code/modules/mob/living/simple_animal/bot/construction.dm
@@ -101,7 +101,7 @@
if(ASSEMBLY_FOURTH_STEP)
if(istype(W, /obj/item/weldingtool))
- if(W.use_tool(src, user, 0, volume=40))
+ if(W.use_tool(src, user, 0, volume=40) && build_step == 4)
name = "shielded frame assembly"
to_chat(user, "You weld the vest to [src]. ")
build_step++
@@ -183,7 +183,7 @@
if(8)
if(istype(W, /obj/item/screwdriver))
to_chat(user, "You start attaching the gun to the frame... ")
- if(W.use_tool(src, user, 40, volume=100))
+ if(W.use_tool(src, user, 40, volume=100) && build_step == 8)
name = "armed [name]"
to_chat(user, "Taser gun attached. ")
build_step++
diff --git a/code/modules/mob/living/simple_animal/bot/medbot.dm b/code/modules/mob/living/simple_animal/bot/medbot.dm
index 1bff7dc10c..50c331940a 100644
--- a/code/modules/mob/living/simple_animal/bot/medbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/medbot.dm
@@ -51,6 +51,7 @@
var/treatment_fire = "kelotane"
var/treatment_tox_avoid = "tricordrazine"
var/treatment_tox = "charcoal"
+ var/treatment_tox_toxlover = "toxin"
var/treatment_virus_avoid = null
var/treatment_virus = "spaceacillin"
var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible.
@@ -381,8 +382,8 @@
if((!C.reagents.has_reagent(treatment_fire_avoid)) && (C.getFireLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_fire)))
return TRUE
-
- if((!C.reagents.has_reagent(treatment_tox_avoid)) && (C.getToxLoss() >= heal_threshold) && (!C.reagents.has_reagent(treatment_tox)))
+ var/treatment_toxavoid = get_avoidchem_toxin(C)
+ if(((isnull(treatment_toxavoid) || !C.reagents.has_reagent(treatment_toxavoid))) && (C.getToxLoss() >= heal_threshold) && (!C.reagents.has_reagent(get_healchem_toxin(C))))
return TRUE
if(treat_virus && !C.reagents.has_reagent(treatment_virus_avoid) && !C.reagents.has_reagent(treatment_virus))
@@ -396,6 +397,12 @@
return FALSE
+/mob/living/simple_animal/bot/medbot/proc/get_avoidchem_toxin(mob/M)
+ return HAS_TRAIT(M, TRAIT_TOXINLOVER)? null : treatment_tox_avoid
+
+/mob/living/simple_animal/bot/medbot/proc/get_healchem_toxin(mob/M)
+ return HAS_TRAIT(M, TRAIT_TOXINLOVER)? treatment_tox_toxlover : treatment_tox
+
/mob/living/simple_animal/bot/medbot/UnarmedAttack(atom/A)
if(iscarbon(A))
var/mob/living/carbon/C = A
@@ -463,8 +470,10 @@
reagent_id = treatment_fire
if(!reagent_id && (C.getToxLoss() >= heal_threshold))
- if(!C.reagents.has_reagent(treatment_tox) && !C.reagents.has_reagent(treatment_tox_avoid))
- reagent_id = treatment_tox
+ var/toxin_heal_avoid = get_avoidchem_toxin(C)
+ var/toxin_healchem = get_healchem_toxin(C)
+ if(!C.reagents.has_reagent(toxin_healchem) && (isnull(toxin_heal_avoid) || !C.reagents.has_reagent(toxin_heal_avoid)))
+ reagent_id = toxin_healchem
//If the patient is injured but doesn't have our special reagent in them then we should give it to them first
if(reagent_id && use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm
index 1bc7493684..94283f82da 100644
--- a/code/modules/mob/living/simple_animal/bot/mulebot.dm
+++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm
@@ -476,7 +476,8 @@
if(isturf(next))
if(bloodiness)
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
- B.add_blood_DNA(return_blood_DNA())
+ if(blood_DNA && blood_DNA.len)
+ B.blood_DNA |= blood_DNA.Copy()
var/newdir = get_dir(next, loc)
if(newdir == dir)
B.setDir(newdir)
@@ -489,7 +490,6 @@
B.setDir(newdir)
bloodiness--
-
var/oldloc = loc
var/moved = step_towards(src, next) // attempt to move
if(cell)
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index 9572b4dafc..f22139ac22 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -131,7 +131,8 @@ Auto Patrol: []"},
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
if(..())
return 1
-
+ if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
+ return TRUE
switch(href_list["operation"])
if("idcheck")
idcheck = !idcheck
diff --git a/code/modules/mob/living/simple_animal/damage_procs.dm b/code/modules/mob/living/simple_animal/damage_procs.dm
index 1031c5b7ee..0cc097dc08 100644
--- a/code/modules/mob/living/simple_animal/damage_procs.dm
+++ b/code/modules/mob/living/simple_animal/damage_procs.dm
@@ -37,5 +37,5 @@
else if(damage_coeff[CLONE])
. = adjustHealth(amount * damage_coeff[CLONE] * CONFIG_GET(number/damage_multiplier), updating_health, forced)
-/mob/living/simple_animal/adjustStaminaLoss(amount)
+/mob/living/simple_animal/adjustStaminaLoss(amount, forced = FALSE)
return
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
index 6d3121474c..d7d4d1b9f2 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm
@@ -160,7 +160,7 @@
if(mind)
mind.transfer_to(R, 1)
else
- R.key = key
+ transfer_ckey(R)
qdel(src)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
index a655bdf231..e54b21724d 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/drones_as_items.dm
@@ -61,5 +61,5 @@
var/obj/item/new_hat = new hat_type(D)
D.equip_to_slot_or_del(new_hat, SLOT_HEAD)
D.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
- D.key = user.key
+ user.transfer_ckey(D, FALSE)
qdel(src)
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
index 23ac527b2e..521f458e2f 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/extra_drone_types.dm
@@ -33,7 +33,7 @@
/mob/living/simple_animal/drone/syndrone/Initialize()
. = ..()
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
+ var/datum/component/uplink/hidden_uplink = internal_storage.GetComponent(/datum/component/uplink)
hidden_uplink.telecrystals = 10
/mob/living/simple_animal/drone/syndrone/Login()
@@ -47,9 +47,9 @@
/mob/living/simple_animal/drone/syndrone/badass/Initialize()
. = ..()
- GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
+ var/datum/component/uplink/hidden_uplink = internal_storage.GetComponent(/datum/component/uplink)
hidden_uplink.telecrystals = 30
- var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(src)
+ var/obj/item/implant/weapons_auth/W = new
W.implant(src)
/mob/living/simple_animal/drone/snowflake
diff --git a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm
index 3f344c2936..6e89f045da 100644
--- a/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm
+++ b/code/modules/mob/living/simple_animal/friendly/drone/inventory.dm
@@ -19,7 +19,7 @@
return 0
-/mob/living/simple_animal/drone/can_equip(obj/item/I, slot)
+/mob/living/simple_animal/drone/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
switch(slot)
if(SLOT_HEAD)
if(head)
diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
index 564fae48ad..b2971e8d01 100644
--- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
+++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm
@@ -323,6 +323,132 @@
else
STOP_PROCESSING(SSobj, src)
+// Space kiwis, ergo quite a copypasta of chickens.
+
+/mob/living/simple_animal/kiwi
+ name = "space kiwi"
+ desc = "Exposure to low gravity made them grow larger."
+ gender = FEMALE
+ icon_state = "kiwi"
+ icon_living = "kiwi"
+ icon_dead = "kiwi_dead"
+ speak = list("Chirp!","Cheep cheep chirp!!","Cheep.")
+ speak_emote = list("chirps","trills")
+ emote_hear = list("chirps.")
+ emote_see = list("pecks at the ground.","jumps in place.")
+ density = FALSE
+ speak_chance = 2
+ turns_per_move = 3
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
+ var/egg_type = /obj/item/reagent_containers/food/snacks/egg/kiwiEgg
+ var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "kicks"
+ attacktext = "kicks"
+ health = 25
+ maxHealth = 25
+ ventcrawler = VENTCRAWLER_ALWAYS
+ var/eggsleft = 0
+ var/eggsFertile = TRUE
+ pass_flags = PASSTABLE | PASSMOB
+ mob_size = MOB_SIZE_SMALL
+ var/list/feedMessages = list("It chirps happily.","It chirps happily.")
+ var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins chirping raucously.")
+ gold_core_spawnable = FRIENDLY_SPAWN
+ var/static/kiwi_count = 0
+
+/mob/living/simple_animal/kiwi/Destroy()
+ --kiwi_count
+ return ..()
+
+/mob/living/simple_animal/kiwi/Initialize()
+ . = ..()
+ ++kiwi_count
+
+/mob/living/simple_animal/kiwi/Life()
+ . =..()
+ if(!.)
+ return
+ if((!stat && prob(3) && eggsleft > 0) && egg_type)
+ visible_message("[src] [pick(layMessage)]")
+ eggsleft--
+ var/obj/item/E = new egg_type(get_turf(src))
+ E.pixel_x = rand(-6,6)
+ E.pixel_y = rand(-6,6)
+ if(eggsFertile)
+ if(kiwi_count < MAX_CHICKENS && prob(25))
+ START_PROCESSING(SSobj, E)
+
+/obj/item/reagent_containers/food/snacks/egg/kiwiEgg/process()
+ if(isturf(loc))
+ amount_grown += rand(1,2)
+ if(amount_grown >= 100)
+ visible_message("[src] hatches with a quiet cracking sound.")
+ new /mob/living/simple_animal/babyKiwi(get_turf(src))
+ STOP_PROCESSING(SSobj, src)
+ qdel(src)
+ else
+ STOP_PROCESSING(SSobj, src)
+
+/mob/living/simple_animal/kiwi/attackby(obj/item/O, mob/user, params)
+ if(istype(O, food_type)) //feedin' dem kiwis
+ if(!stat && eggsleft < 8)
+ var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]"
+ user.visible_message(feedmsg)
+ qdel(O)
+ eggsleft += rand(1, 4)
+ else
+ to_chat(user, "[name] doesn't seem hungry! ")
+ else
+ ..()
+
+/mob/living/simple_animal/babyKiwi
+ name = "baby space kiwi"
+ desc = "So huggable."
+ icon_state = "babykiwi"
+ icon_living = "babykiwi"
+ icon_dead = "babykiwi_dead"
+ gender = FEMALE
+ speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
+ speak_emote = list("chirps")
+ emote_hear = list("chirps.")
+ emote_see = list("pecks at the ground.","Happily bounces in place.")
+ density = FALSE
+ speak_chance = 2
+ turns_per_move = 2
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "kicks"
+ attacktext = "kicks"
+ health = 10
+ maxHealth = 10
+ ventcrawler = VENTCRAWLER_ALWAYS
+ var/amount_grown = 0
+ pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
+ mob_size = MOB_SIZE_TINY
+ gold_core_spawnable = FRIENDLY_SPAWN
+
+/mob/living/simple_animal/babyKiwi/Initialize()
+ . = ..()
+ pixel_x = rand(-6, 6)
+ pixel_y = rand(0, 10)
+
+/mob/living/simple_animal/babyKiwi/Life()
+ . =..()
+ if(!.)
+ return
+ if(!stat && !ckey)
+ amount_grown += rand(1,2)
+ if(amount_grown >= 100)
+ new /mob/living/simple_animal/kiwi(src.loc)
+ qdel(src)
+
+/obj/item/reagent_containers/food/snacks/egg/kiwiEgg
+ name = "kiwi egg"
+ desc = "A slightly bigger egg!"
+ icon_state = "kiwiegg"
/obj/item/udder
name = "udder"
diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm
index 5aec56b1e7..e3ef14c784 100644
--- a/code/modules/mob/living/simple_animal/guardian/guardian.dm
+++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm
@@ -429,9 +429,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
to_chat(G, "Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance. ")
to_chat(src, "Your [G.real_name] has been successfully reset. ")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
- G.ghostize(0)
+ G.ghostize(FALSE)
G.setthemename(G.namedatum.theme) //give it a new color, to show it's a new person
- G.key = C.key
+ C.transfer_ckey(G)
G.reset = 1
switch(G.namedatum.theme)
if("tech")
diff --git a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
index a43d4b6d5c..52a007e24c 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/dextrous.dm
@@ -52,7 +52,7 @@
return 1
return 0
-/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot)
+/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
switch(slot)
if(SLOT_GENERC_DEXTROUS_STORAGE)
if(internal_storage)
diff --git a/code/modules/mob/living/simple_animal/guardian/types/support.dm b/code/modules/mob/living/simple_animal/guardian/types/support.dm
index 8bf1874d84..d31809e9aa 100644
--- a/code/modules/mob/living/simple_animal/guardian/types/support.dm
+++ b/code/modules/mob/living/simple_animal/guardian/types/support.dm
@@ -30,7 +30,7 @@
C.adjustBruteLoss(-5)
C.adjustFireLoss(-5)
C.adjustOxyLoss(-5)
- C.adjustToxLoss(-5)
+ C.adjustToxLoss(-5, forced = TRUE)
var/obj/effect/temp_visual/heal/H = new /obj/effect/temp_visual/heal(get_turf(C))
if(namedatum)
H.color = namedatum.colour
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index 3d92912f9c..5240b4d06c 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -168,7 +168,6 @@
/mob/living/simple_animal/hostile/alien/maid/Initialize(mapload)
. = ..()
- AddComponent(/datum/component/cleaning)
/mob/living/simple_animal/hostile/alien/maid/AttackingTarget()
if(ismovableatom(target))
@@ -177,6 +176,7 @@
qdel(target)
return TRUE
var/atom/movable/M = target
- SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ M.clean_blood()
visible_message("[src] polishes \the [target].")
return TRUE
diff --git a/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm b/code/modules/mob/living/simple_animal/hostile/banana_spider.dm
similarity index 62%
rename from modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm
rename to code/modules/mob/living/simple_animal/hostile/banana_spider.dm
index d2006cd12c..823c26b4e9 100644
--- a/modular_citadel/code/modules/mob/living/simple_animal/banana_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/banana_spider.dm
@@ -1,58 +1,8 @@
-/obj/item/seeds/banana/Initialize()
- . = ..()
- mutatelist += /obj/item/seeds/banana/exotic_banana
-
-
-/obj/item/seeds/banana/exotic_banana
- name = "pack of exotic banana seeds"
- desc = "They're seeds that grow into banana trees. However, those bananas might be alive."
- icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
- icon_state = "seed_ExoticBanana"
- species = "banana"
- plantname = "Exotic Banana Tree"
- product = /obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable
- growing_icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
- icon_dead = "banana-dead"
- mutatelist = list()
- genes = list(/datum/plant_gene/trait/slip)
- reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02)
-
-
-/obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable
- seed = /obj/item/seeds/banana/exotic_banana
- name = "banana spider"
- desc = "You do not know what it is, but you can bet the clown would love it."
- icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
- icon_state = "banana"
- item_state = "banana"
- filling_color = "#FFFF00"
- list_reagents = list("nutriment" = 3, "vitamin" = 2)
- foodtype = GROSS | MEAT | RAW | FRUIT
- grind_results = list("blood" = 20, "liquidgibs" = 5)
- juice_results = list("banana" = 0)
- var/awakening = 0
-
-
-/obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable/attack_self(mob/user)
- if(awakening || isspaceturf(user.loc))
- return
- to_chat(user, "You decide to wake up the banana spider... ")
- awakening = 1
-
- spawn(30)
- if(!QDELETED(src))
- var/mob/living/simple_animal/banana_spider/S = new /mob/living/simple_animal/banana_spider(get_turf(src.loc))
- S.speed += round(10 / seed.potency)
- S.visible_message("The banana spider chitters as it stretches its legs. ")
- qdel(src)
-
-
/mob/living/simple_animal/banana_spider
- icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
name = "banana spider"
desc = "What the fuck is this abomination?"
- icon_state = "banana"
- icon_dead = "banana_peel"
+ icon_state = "bananaspider"
+ icon_dead = "bananaspider_peel"
health = 1
maxHealth = 1
turns_per_move = 5 //this isn't player speed =|
@@ -98,7 +48,7 @@
if(be_spider == "No" || QDELETED(src) || !isobserver(user))
return
sentience_act()
- key = user.key
+ user.transfer_ckey(src, FALSE)
density = TRUE
/mob/living/simple_animal/banana_spider/ComponentInitialize()
@@ -136,8 +86,7 @@
/obj/item/reagent_containers/food/snacks/deadbanana_spider
name = "dead banana spider"
desc = "Thank god it's gone...but it does look slippery."
- icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
- icon_state = "banana_peel"
+ icon_state = "bananaspider"
bitesize = 3
eatverb = "devours"
list_reagents = list("nutriment" = 3, "vitamin" = 2)
diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
index cfdf302d6b..2f39ae13a1 100644
--- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
+++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm
@@ -90,7 +90,7 @@
if(key)
to_chat(user, "Someone else already took this spider. ")
return 1
- key = user.key
+ user.transfer_ckey(src, FALSE)
return 1
//nursemaids - these create webs and eggs
@@ -175,14 +175,17 @@
status_flags = NONE
mob_size = MOB_SIZE_LARGE
gold_core_spawnable = NO_SPAWN
+ var/slowed_by_webs = FALSE
-/mob/living/simple_animal/hostile/poison/giant_spider/tarantula/movement_delay()
- var/turf/T = get_turf(src)
- if(locate(/obj/structure/spider/stickyweb) in T)
- speed = 2
- else
- speed = 7
+/mob/living/simple_animal/hostile/poison/giant_spider/tarantula/Moved(atom/oldloc, dir)
. = ..()
+ if(slowed_by_webs)
+ if(!(locate(/obj/structure/spider/stickyweb) in loc))
+ remove_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB)
+ slowed_by_webs = FALSE
+ else if(locate(/obj/structure/spider/stickyweb) in loc)
+ add_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB, priority=100, multiplicative_slowdown=3)
+ slowed_by_webs = TRUE
//midwives are the queen of the spiders, can send messages to all them and web faster. That rare round where you get a queen spider and turn your 'for honor' players into 'r6siege' players will be a fun one.
/mob/living/simple_animal/hostile/poison/giant_spider/nurse/midwife
diff --git a/code/modules/mob/living/simple_animal/hostile/goose.dm b/code/modules/mob/living/simple_animal/hostile/goose.dm
new file mode 100644
index 0000000000..b67770fb4b
--- /dev/null
+++ b/code/modules/mob/living/simple_animal/hostile/goose.dm
@@ -0,0 +1,35 @@
+#define GOOSE_SATIATED 50
+
+/mob/living/simple_animal/hostile/retaliate/goose
+ name = "goose"
+ desc = "It's loose"
+ icon_state = "goose" // sprites by cogwerks from goonstation, used with permission
+ icon_living = "goose"
+ icon_dead = "goose_dead"
+ mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
+ speak_chance = 0
+ turns_per_move = 5
+ butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 2)
+ response_help = "pets"
+ response_disarm = "gently pushes aside"
+ response_harm = "kicks"
+ emote_taunt = list("hisses")
+ taunt_chance = 30
+ speed = 0
+ maxHealth = 25
+ health = 25
+ harm_intent_damage = 5
+ melee_damage_lower = 5
+ melee_damage_upper = 5
+ attacktext = "pecks"
+ attack_sound = "goose"
+ speak_emote = list("honks")
+ faction = list("neutral")
+ attack_same = TRUE
+ gold_core_spawnable = HOSTILE_SPAWN
+ var/random_retaliate = TRUE
+
+/mob/living/simple_animal/hostile/retaliate/goose/handle_automated_movement()
+ . = ..()
+ if(prob(5) && random_retaliate == TRUE)
+ Retaliate()
diff --git a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm
index 5d1db8d35e..6866df01d5 100644
--- a/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm
+++ b/code/modules/mob/living/simple_animal/hostile/gorilla/gorilla.dm
@@ -2,7 +2,7 @@
#define GORILLA_TOTAL_LAYERS 1
/mob/living/simple_animal/hostile/gorilla
- name = "Gorilla"
+ name = "gorilla"
desc = "A ground-dwelling, predominantly herbivorous ape that inhabits the forests of central Africa."
icon = 'icons/mob/gorilla.dmi'
icon_state = "crawling"
@@ -108,3 +108,10 @@
playsound(src, 'sound/creatures/gorilla.ogg', 200)
oogas = 0
+/mob/living/simple_animal/hostile/gorilla/familiar
+ name = "familiar gorilla"
+ desc = "There is no need to be upset."
+ unique_name = FALSE
+ AIStatus = AI_OFF
+ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
+ minbodytemp = 0
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm
index 368c5ad4a8..9cd0504315 100644
--- a/code/modules/mob/living/simple_animal/hostile/hostile.dm
+++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm
@@ -344,6 +344,7 @@
/mob/living/simple_animal/hostile/proc/AttackingTarget()
+ SEND_SIGNAL(src, COMSIG_HOSTILE_ATTACKINGTARGET, target)
in_melee = TRUE
if(vore_active)
if(isliving(target))
@@ -426,12 +427,13 @@
if(casingtype)
var/obj/item/ammo_casing/casing = new casingtype(startloc)
playsound(src, projectilesound, 100, 1)
- casing.fire_casing(targeted_atom, src, null, null, null, ran_zone())
+ casing.fire_casing(targeted_atom, src, null, null, null, ran_zone(), src)
else if(projectiletype)
var/obj/item/projectile/P = new projectiletype(startloc)
playsound(src, projectilesound, 100, 1)
P.starting = startloc
P.firer = src
+ P.fired_from = src
P.yo = targeted_atom.y - startloc.y
P.xo = targeted_atom.x - startloc.x
if(AIStatus != AI_ON)//Don't want mindless mobs to have their movement screwed up firing in space
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
index b529d826c9..c21166276a 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/colossus.dm
@@ -388,7 +388,7 @@ Difficulty: Very Hard
ActivationReaction(user, ACTIVATE_TOUCH)
/obj/machinery/anomalous_crystal/attackby(obj/item/I, mob/user, params)
- if(I.is_hot())
+ if(I.get_temperature())
ActivationReaction(user, ACTIVATE_HEAT)
else
ActivationReaction(user, ACTIVATE_WEAPON)
@@ -585,7 +585,7 @@ Difficulty: Very Hard
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
if(be_helper == "Yes" && !QDELETED(src) && isobserver(user))
var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc))
- W.key = user.key
+ user.transfer_ckey(W, FALSE)
/obj/machinery/anomalous_crystal/helpers/Topic(href, href_list)
@@ -649,7 +649,7 @@ Difficulty: Very Hard
L.heal_overall_damage(heal_power, heal_power)
new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF")
-/mob/living/simple_animal/hostile/lightgeist/ghostize()
+/mob/living/simple_animal/hostile/lightgeist/ghostize(can_reenter_corpse = TRUE, special = FALSE)
. = ..()
if(.)
death()
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm
index 26f146b952..8c06b01402 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon_vore.dm
@@ -42,7 +42,7 @@
autotransferwait = 200
/obj/belly/megafauna/dragon/gut
- name = "stomach"
+ name = "gut"
vore_capacity = 5 //I doubt this many people will actually last in the gut, but...
vore_sound = "Tauric Swallow"
desc = "With a rush of burning ichor greeting you, you're introduced to the Drake's stomach. Wrinkled walls greedily grind against you, acidic slimes working into your body as you become fuel and nutriton for a superior predator. All that's left is your body's willingness to resist your destiny."
diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
index 301b270e36..d62f59cdd7 100644
--- a/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
+++ b/code/modules/mob/living/simple_animal/hostile/megafauna/megafauna.dm
@@ -127,7 +127,7 @@
var/client/C = L.client
SSmedals.UnlockMedal("Boss [BOSS_KILL_MEDAL]", C)
SSmedals.UnlockMedal("[medaltype] [BOSS_KILL_MEDAL]", C)
- if(crusher_kill && istype(L.get_active_held_item(), /obj/item/twohanded/required/kinetic_crusher))
+ if(crusher_kill && istype(L.get_active_held_item(), /obj/item/twohanded/kinetic_crusher))
SSmedals.UnlockMedal("[medaltype] [BOSS_KILL_MEDAL_CRUSHER]", C)
SSmedals.SetScore(BOSS_SCORE, C, 1)
SSmedals.SetScore(score_type, C, 1)
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
index c2d0a214b4..910e9c3c4a 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs/gutlunch.dm
@@ -39,7 +39,7 @@
animal_species = /mob/living/simple_animal/hostile/asteroid/gutlunch
childtype = list(/mob/living/simple_animal/hostile/asteroid/gutlunch/gubbuck = 45, /mob/living/simple_animal/hostile/asteroid/gutlunch/guthen = 55)
- wanted_objects = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/blood/gibs/)
+ wanted_objects = list(/obj/effect/decal/cleanable/blood/gibs/xeno, /obj/effect/decal/cleanable/blood/gibs/)
var/obj/item/udder/gutlunch/udder = null
/mob/living/simple_animal/hostile/asteroid/gutlunch/Initialize()
diff --git a/code/modules/mob/living/simple_animal/hostile/netherworld.dm b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
index 8210fd6490..dc2f942041 100644
--- a/code/modules/mob/living/simple_animal/hostile/netherworld.dm
+++ b/code/modules/mob/living/simple_animal/hostile/netherworld.dm
@@ -34,7 +34,7 @@
/mob/living/simple_animal/hostile/netherworld/migo/Initialize()
. = ..()
- migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/beepsky/creep.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/medbot/patchedup.ogg', 'sound/voice/medbot/feelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg','sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshot_silenced.ogg', 'sound/weapons/gunshot2.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/machines/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', 'sound/ai/outbreak5.ogg', 'sound/ai/outbreak7.ogg', 'sound/ai/poweroff.ogg', 'sound/ai/radiation.ogg', 'sound/ai/shuttlecalled.ogg', 'sound/ai/shuttledock.ogg', 'sound/ai/shuttlerecalled.ogg', 'sound/ai/aimalf.ogg') //hahahaha fuck you code divers
+ migo_sounds = list('sound/items/bubblewrap.ogg', 'sound/items/change_jaws.ogg', 'sound/items/crowbar.ogg', 'sound/items/drink.ogg', 'sound/items/deconstruct.ogg', 'sound/items/carhorn.ogg', 'sound/items/change_drill.ogg', 'sound/items/dodgeball.ogg', 'sound/items/eatfood.ogg', 'sound/items/megaphone.ogg', 'sound/items/screwdriver.ogg', 'sound/items/weeoo1.ogg', 'sound/items/wirecutter.ogg', 'sound/items/welder.ogg', 'sound/items/zip.ogg', 'sound/items/rped.ogg', 'sound/items/ratchet.ogg', 'sound/items/polaroid1.ogg', 'sound/items/pshoom.ogg', 'sound/items/airhorn.ogg', 'sound/items/geiger/high1.ogg', 'sound/items/geiger/high2.ogg', 'sound/voice/beepsky/creep.ogg', 'sound/voice/beepsky/iamthelaw.ogg', 'sound/voice/ed209_20sec.ogg', 'sound/voice/hiss3.ogg', 'sound/voice/hiss6.ogg', 'sound/voice/medbot/patchedup.ogg', 'sound/voice/medbot/feelbetter.ogg', 'sound/voice/human/manlaugh1.ogg', 'sound/voice/human/womanlaugh.ogg', 'sound/weapons/sear.ogg', 'sound/ambience/antag/clockcultalr.ogg', 'sound/ambience/antag/ling_aler.ogg', 'sound/ambience/antag/tatoralert.ogg', 'sound/ambience/antag/monkey.ogg', 'sound/mecha/nominal.ogg', 'sound/mecha/weapdestr.ogg', 'sound/mecha/critdestr.ogg', 'sound/mecha/imag_enh.ogg', 'sound/effects/adminhelp.ogg', 'sound/effects/alert.ogg', 'sound/effects/attackblob.ogg', 'sound/effects/bamf.ogg', 'sound/effects/blobattack.ogg', 'sound/effects/break_stone.ogg', 'sound/effects/bubbles.ogg', 'sound/effects/bubbles2.ogg', 'sound/effects/clang.ogg', 'sound/effects/clockcult_gateway_disrupted.ogg', 'sound/effects/clownstep2.ogg', 'sound/effects/curse1.ogg', 'sound/effects/dimensional_rend.ogg', 'sound/effects/doorcreaky.ogg', 'sound/effects/empulse.ogg', 'sound/effects/explosion_distant.ogg', 'sound/effects/explosionfar.ogg', 'sound/effects/explosion1.ogg', 'sound/effects/grillehit.ogg', 'sound/effects/genetics.ogg', 'sound/effects/heart_beat.ogg', 'sound/effects/hyperspace_begin.ogg', 'sound/effects/hyperspace_end.ogg', 'sound/effects/his_grace_awaken.ogg', 'sound/effects/pai_boot.ogg', 'sound/effects/phasein.ogg', 'sound/effects/picaxe1.ogg', 'sound/effects/ratvar_reveal.ogg', 'sound/effects/sparks1.ogg', 'sound/effects/smoke.ogg', 'sound/effects/splat.ogg', 'sound/effects/snap.ogg', 'sound/effects/tendril_destroyed.ogg', 'sound/effects/supermatter.ogg', 'sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg', 'sound/misc/bloblarm.ogg', 'sound/misc/airraid.ogg', 'sound/misc/bang.ogg','sound/misc/highlander.ogg', 'sound/misc/interference.ogg', 'sound/misc/notice1.ogg', 'sound/misc/notice2.ogg', 'sound/misc/sadtrombone.ogg', 'sound/misc/slip.ogg', 'sound/misc/splort.ogg', 'sound/weapons/armbomb.ogg', 'sound/weapons/beam_sniper.ogg', 'sound/weapons/chainsawhit.ogg', 'sound/weapons/emitter.ogg', 'sound/weapons/emitter2.ogg', 'sound/weapons/blade1.ogg', 'sound/weapons/bladeslice.ogg', 'sound/weapons/blastcannon.ogg', 'sound/weapons/blaster.ogg', 'sound/weapons/bulletflyby3.ogg', 'sound/weapons/circsawhit.ogg', 'sound/weapons/cqchit2.ogg', 'sound/weapons/drill.ogg', 'sound/weapons/genhit1.ogg', 'sound/weapons/gunshot_silenced.ogg', 'sound/weapons/gunshot2.ogg', 'sound/weapons/handcuffs.ogg', 'sound/weapons/homerun.ogg', 'sound/weapons/kenetic_accel.ogg', 'sound/machines/clockcult/steam_whoosh.ogg', 'sound/machines/fryer/deep_fryer_emerge.ogg', 'sound/machines/airlock.ogg', 'sound/machines/airlock_alien_prying.ogg', 'sound/machines/airlockclose.ogg', 'sound/machines/airlockforced.ogg', 'sound/machines/airlockopen.ogg', 'sound/machines/alarm.ogg', 'sound/machines/blender.ogg', 'sound/machines/boltsdown.ogg', 'sound/machines/boltsup.ogg', 'sound/machines/buzz-sigh.ogg', 'sound/machines/buzz-two.ogg', 'sound/machines/chime.ogg', 'sound/machines/cryo_warning.ogg', 'sound/machines/defib_charge.ogg', 'sound/machines/defib_failed.ogg', 'sound/machines/defib_ready.ogg', 'sound/machines/defib_zap.ogg', 'sound/machines/deniedbeep.ogg', 'sound/machines/ding.ogg', 'sound/machines/disposalflush.ogg', 'sound/machines/door_close.ogg', 'sound/machines/door_open.ogg', 'sound/machines/engine_alert1.ogg', 'sound/machines/engine_alert2.ogg', 'sound/machines/hiss.ogg', 'sound/machines/honkbot_evil_laugh.ogg', 'sound/machines/juicer.ogg', 'sound/machines/ping.ogg', 'sound/machines/signal.ogg', 'sound/machines/synth_no.ogg', 'sound/machines/synth_yes.ogg', 'sound/machines/terminal_alert.ogg', 'sound/machines/triple_beep.ogg', 'sound/machines/twobeep.ogg', 'sound/machines/ventcrawl.ogg', 'sound/machines/warning-buzzer.ogg', get_announcer_sound("outbreak5"), get_announcer_sound("outbreak7"), get_announcer_sound("poweroff"), get_announcer_sound("radiation"), get_announcer_sound("shuttlerecalled"), get_announcer_sound("shuttledock"), get_announcer_sound("shuttlecalled"), get_announcer_sound("aimalf")) //hahahaha fuck you code divers
/mob/living/simple_animal/hostile/netherworld/migo/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
..()
diff --git a/code/modules/mob/living/simple_animal/hostile/wizard.dm b/code/modules/mob/living/simple_animal/hostile/wizard.dm
index a946cbf45b..f047a7aed1 100644
--- a/code/modules/mob/living/simple_animal/hostile/wizard.dm
+++ b/code/modules/mob/living/simple_animal/hostile/wizard.dm
@@ -46,7 +46,8 @@
fireball.human_req = 0
fireball.player_lock = 0
AddSpell(fireball)
- implants += new /obj/item/implant/exile(src)
+ var/obj/item/implant/exile/I = new
+ I.implant(src, null, TRUE)
mm = new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile
mm.clothes_req = 0
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 86f63a729d..5e2798cc8e 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -916,7 +916,7 @@
if(mind)
mind.transfer_to(G)
else
- G.key = key
+ transfer_ckey(G)
..(gibbed)
/mob/living/simple_animal/parrot/Poly/proc/Read_Memory()
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 1f81899d8a..a2ef5b813b 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -363,7 +363,7 @@
density = initial(density)
lying = 0
. = 1
- movement_type = initial(movement_type)
+ setMovetype(initial(movement_type))
/mob/living/simple_animal/proc/make_babies() // <3 <3 <3
if(gender != FEMALE || stat || next_scan_time > world.time || !childtype || !animal_species || !SSticker.IsRoundInProgress())
@@ -536,7 +536,7 @@
//ANIMAL RIDING
/mob/living/simple_animal/user_buckle_mob(mob/living/M, mob/user)
- GET_COMPONENT(riding_datum, /datum/component/riding)
+ var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(riding_datum)
if(user.incapacitated())
return
@@ -547,7 +547,7 @@
return ..()
/mob/living/simple_animal/relaymove(mob/user, direction)
- GET_COMPONENT(riding_datum, /datum/component/riding)
+ var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(tame && riding_datum)
riding_datum.handle_ride(user, direction)
diff --git a/code/modules/mob/living/simple_animal/simple_animal_vr.dm b/code/modules/mob/living/simple_animal/simple_animal_vr.dm
index 666de9cef0..700ee3b7ce 100644
--- a/code/modules/mob/living/simple_animal/simple_animal_vr.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal_vr.dm
@@ -29,21 +29,22 @@
/mob/living/simple_animal/Destroy()
release_vore_contents(include_absorbed = TRUE, silent = TRUE)
prey_excludes.Cut()
+ QDEL_NULL_LIST(vore_organs)
. = ..()
// Update fullness based on size & quantity of belly contents
/mob/living/simple_animal/proc/update_fullness(var/atom/movable/M)
var/new_fullness = 0
- for(var/I in vore_organs)
- var/datum/belly/B = vore_organs[I]
- if (!(M in B.internal_contents))
+ for(var/belly in vore_organs)
+ var/obj/belly/B = vore_organs[belly]
+ if (!(M in B.contents))
return FALSE // Nothing's inside
new_fullness += M
vore_fullness = new_fullness
/mob/living/simple_animal/death()
- release_vore_contents(silent = TRUE)
+ release_vore_contents()
. = ..()
// Simple animals have only one belly. This creates it (if it isn't already set up)
@@ -51,16 +52,18 @@
vore_init = TRUE
if(CHECK_BITFIELD(flags_1, HOLOGRAM_1))
return
- if(vore_organs.len)
- return
- if(no_vore) //If it can't vore, let's not give it a stomach.
+ if(!vore_active || no_vore) //If it can't vore, let's not give it a stomach.
return
if(vore_active && !IsAdvancedToolUser()) //vore active, but doesn't have thumbs to grab people with.
verbs |= /mob/living/simple_animal/proc/animal_nom
- var/obj/belly/B = new /obj/belly(src)
+ if(LAZYLEN(vore_organs))
+ return
+
+ LAZYINITLIST(vore_organs)
+ var/obj/belly/B = new (src)
vore_selected = B
- B.immutable = 1
+ B.immutable = TRUE
B.name = vore_stomach_name ? vore_stomach_name : "stomach"
B.desc = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside \the [name]."
B.digest_mode = vore_default_mode
@@ -125,13 +128,12 @@
// Simple nom proc for if you get ckey'd into a simple_animal mob! Avoids grabs.
//
/mob/living/simple_animal/proc/animal_nom(var/mob/living/T in oview(1))
- set name = "Animal Nom"
+ set name = "Animal Nom (pull target)"
set category = "Vore"
set desc = "Since you can't grab, you get a verb!"
if (stat != CONSCIOUS)
return
- if (T.devourable == FALSE)
- to_chat(usr, "You can't eat this! ")
+ if(!T.devourable)
return
- return vore_attack(usr,T,usr)
+ return vore_attack(src,T,src)
diff --git a/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm b/code/modules/mob/living/simple_animal/simplemob_vore_values.dm
similarity index 98%
rename from modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm
rename to code/modules/mob/living/simple_animal/simplemob_vore_values.dm
index 78e18fdb5e..22ed5e3ab4 100644
--- a/modular_citadel/code/modules/mob/living/simple_animal/simplemob_vore_values.dm
+++ b/code/modules/mob/living/simple_animal/simplemob_vore_values.dm
@@ -129,6 +129,8 @@
vore_default_mode = DM_DIGEST
/mob/living/simple_animal/hostile/carp
+ devourable = TRUE
+ digestable = TRUE
feeding = TRUE
vore_active = TRUE
isPredator = TRUE
diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm
index a3e2f48b75..bf80ab9ff4 100644
--- a/code/modules/mob/living/simple_animal/slime/powers.dm
+++ b/code/modules/mob/living/simple_animal/slime/powers.dm
@@ -198,7 +198,7 @@
if(src.mind)
src.mind.transfer_to(new_slime)
else
- new_slime.key = src.key
+ transfer_ckey(new_slime)
qdel(src)
else
to_chat(src, "I am not ready to reproduce yet... ")
diff --git a/code/modules/mob/living/taste.dm b/code/modules/mob/living/taste.dm
index 282fe0a716..e4d1aa94a5 100644
--- a/code/modules/mob/living/taste.dm
+++ b/code/modules/mob/living/taste.dm
@@ -43,7 +43,7 @@
.=..()
if ((from.pH > 12.5) || (from.pH < 1.5))
to_chat(src, "You taste chemical burns! ")
- T.adjustTongueLoss(src, 4)
+ T.applyOrganDamage(5)
if(istype(T, /obj/item/organ/tongue/cybernetic))
to_chat(src, "Your tongue moves on it's own in response to the liquid. ")
say("The pH is appropriately [round(from.pH, 1)].")
@@ -52,13 +52,11 @@
switch(from.pH)
if(11.5 to INFINITY)
to_chat(src, "You taste a strong alkaline flavour! ")
- T.adjustTongueLoss(src, 1)
if(8.5 to 11.5)
to_chat(src, "You taste a sort of soapy tone in the mixture. ")
if(2.5 to 5.5)
to_chat(src, "You taste a sort of acid tone in the mixture. ")
if(-INFINITY to 2.5)
to_chat(src, "You taste a strong acidic flavour! ")
- T.adjustTongueLoss(src, 1)
#undef DEFAULT_TASTE_SENSITIVITY
diff --git a/code/modules/mob/living/ventcrawling.dm b/code/modules/mob/living/ventcrawling.dm
index 930656228d..cacd1c7c56 100644
--- a/code/modules/mob/living/ventcrawling.dm
+++ b/code/modules/mob/living/ventcrawling.dm
@@ -100,7 +100,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
A.pipe_vision_img.plane = ABOVE_HUD_PLANE
client.images += A.pipe_vision_img
pipes_shown += A.pipe_vision_img
- movement_type |= VENTCRAWLING
+ setMovetype(movement_type | VENTCRAWLING)
/mob/living/proc/remove_ventcrawl()
@@ -108,7 +108,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
for(var/image/current_image in pipes_shown)
client.images -= current_image
pipes_shown.len = 0
- movement_type &= ~VENTCRAWLING
+ setMovetype(movement_type & ~VENTCRAWLING)
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 52fdea861f..f790d15d2d 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -444,7 +444,13 @@
// M.Login() //wat
return
-
+/mob/proc/transfer_ckey(mob/new_mob, send_signal = TRUE)
+ if(!ckey)
+ return FALSE
+ if(send_signal)
+ SEND_SIGNAL(src, COMSIG_MOB_KEY_CHANGE, new_mob, src)
+ new_mob.ckey = ckey
+ return TRUE
/mob/verb/cancel_camera()
set name = "Cancel Camera View"
@@ -731,15 +737,17 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
mob_spell_list -= S
qdel(S)
-/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE)
- if(!magic && !holy)
+/mob/proc/anti_magic_check(magic = TRUE, holy = FALSE, tinfoil = FALSE, chargecost = 1, self = FALSE)
+ if(!magic && !holy && !tinfoil)
return
var/list/protection_sources = list()
- if(SEND_SIGNAL(src, COMSIG_MOB_RECEIVE_MAGIC, magic, holy, protection_sources) & COMPONENT_BLOCK_MAGIC)
+ if(SEND_SIGNAL(src, COMSIG_MOB_RECEIVE_MAGIC, src, magic, holy, tinfoil, chargecost, self, protection_sources) & COMPONENT_BLOCK_MAGIC)
if(protection_sources.len)
return pick(protection_sources)
else
return src
+ if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (holy && HAS_TRAIT(src, TRAIT_HOLY)))
+ return src
//You can buckle on mobs if you're next to them since most are dense
/mob/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
@@ -810,6 +818,9 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
return
+/mob/proc/canUseStorage()
+ return FALSE
+
/mob/proc/faction_check_mob(mob/target, exact_match)
if(exact_match) //if we need an exact match, we need to do some bullfuckery.
var/list/faction_src = faction.Copy()
@@ -853,7 +864,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
replace_identification_name(oldname,newname)
for(var/datum/mind/T in SSticker.minds)
- for(var/datum/objective/obj in T.objectives)
+ for(var/datum/objective/obj in T.get_all_objectives())
// Only update if this player is a target
if(obj.target && obj.target.current && obj.target.current.real_name == name)
obj.update_explanation_text()
@@ -950,3 +961,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
var/datum/language_holder/H = get_language_holder()
H.open_language_menu(usr)
+
+/mob/setMovetype(newval)
+ . = ..()
+ update_movespeed(FALSE)
\ No newline at end of file
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 776bd04935..eb22ab7403 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -88,7 +88,7 @@
if(newletter==" ")
newletter="...huuuhhh..."
if(newletter==".")
- newletter=" *BURP*."
+ newletter=" BURP!"
if(rand(1,100) <= strength*0.5)
if(rand(1,5) == 1)
newletter+="'"
@@ -429,8 +429,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
var/mob/dead/observer/C = pick(candidates)
to_chat(M, "Your mob has been taken over by a ghost!")
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(M)])")
- M.ghostize(0)
- M.key = C.key
+ M.ghostize(FALSE, TRUE)
+ C.transfer_ckey(M, FALSE)
return TRUE
else
to_chat(M, "There were no ghosts willing to take control.")
@@ -486,3 +486,35 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
/mob/proc/can_hear()
. = TRUE
+
+/proc/bloodtype_to_color(var/type)
+ . = BLOOD_COLOR_HUMAN
+ switch(type)
+ if("U")//Universal blood; a bit orange
+ . = BLOOD_COLOR_UNIVERSAL
+ if("SY")//Synthetics blood; blue
+ . = BLOOD_COLOR_SYNTHETIC
+ if("L")//lizard, a bit pink/purple
+ . = BLOOD_COLOR_LIZARD
+ if("X*")//xeno blood; greenish yellow
+ . = BLOOD_COLOR_XENO
+ if("HF")// Oil/Hydraulic blood. something something why not. reee
+ . = BLOOD_COLOR_OIL
+ if("GEL")// slimepeople blood, rgb 0, 255, 144
+ . = BLOOD_COLOR_SLIME
+ if("BUG")// yellowish, like, y'know bug guts I guess.
+ . = BLOOD_COLOR_BUG
+ //add more stuff to the switch if you have more blood colors for different types
+ // the defines are in _DEFINES/misc.dm
+
+//Examine text for traits shared by multiple types. I wish examine was less copypasted.
+/mob/proc/common_trait_examine()
+ if(HAS_TRAIT(src, TRAIT_DISSECTED))
+ var/dissectionmsg = ""
+ if(HAS_TRAIT_FROM(src, TRAIT_DISSECTED,"Extraterrestrial Dissection"))
+ dissectionmsg = " via Extraterrestrial Dissection. It is no longer worth experimenting on"
+ else if(HAS_TRAIT_FROM(src, TRAIT_DISSECTED,"Experimental Dissection"))
+ dissectionmsg = " via Experimental Dissection"
+ else if(HAS_TRAIT_FROM(src, TRAIT_DISSECTED,"Thorough Dissection"))
+ dissectionmsg = " via Thorough Dissection"
+ . += "This body has been dissected and analyzed[dissectionmsg]. "
diff --git a/code/modules/mob/mob_movespeed.dm b/code/modules/mob/mob_movespeed.dm
index 5114972493..a0be8ff7cb 100644
--- a/code/modules/mob/mob_movespeed.dm
+++ b/code/modules/mob/mob_movespeed.dm
@@ -1,23 +1,29 @@
/*Current movespeed modification list format: list(id = list(
priority,
+ flags,
legacy slowdown/speedup amount,
+ movetype_flags,
+ blacklisted_movetypes,
+ conflict
))
*/
//ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE!
-/mob/proc/add_movespeed_modifier(id, update = TRUE, priority = 0, flags = NONE, override = FALSE, multiplicative_slowdown = 0)
- var/list/temp = list(priority, flags, multiplicative_slowdown) //build the modification list
+/mob/proc/add_movespeed_modifier(id, update=TRUE, priority=0, flags=NONE, override=FALSE, multiplicative_slowdown=0, movetypes=ALL, blacklisted_movetypes=NONE, conflict=FALSE)
+ var/list/temp = list(priority, flags, multiplicative_slowdown, movetypes, blacklisted_movetypes, conflict) //build the modification list
+ var/resort = TRUE
if(LAZYACCESS(movespeed_modification, id))
- if(movespeed_modifier_identical_check(movespeed_modification[id], temp))
+ var/list/existing_data = movespeed_modification[id]
+ if(movespeed_modifier_identical_check(existing_data, temp))
return FALSE
if(!override)
return FALSE
- else
- remove_movespeed_modifier(id, update)
- LAZYSET(movespeed_modification, id, list(priority, flags, multiplicative_slowdown))
+ if(priority == existing_data[MOVESPEED_DATA_INDEX_PRIORITY])
+ resort = FALSE // We don't need to re-sort if we're replacing something already there and it's the same priority
+ LAZYSET(movespeed_modification, id, temp)
if(update)
- update_movespeed(TRUE)
+ update_movespeed(resort)
return TRUE
/mob/proc/remove_movespeed_modifier(id, update = TRUE)
@@ -55,9 +61,23 @@
if(resort)
sort_movespeed_modlist()
. = 0
+ var/list/conflict_tracker = list()
for(var/id in get_movespeed_modifiers())
var/list/data = movespeed_modification[id]
- . += data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]
+ if(!(data[MOVESPEED_DATA_INDEX_MOVETYPE] & movement_type)) // We don't affect any of these move types, skip
+ continue
+ if(data[MOVESPEED_DATA_INDEX_BL_MOVETYPE] & movement_type) // There's a movetype here that disables this modifier, skip
+ continue
+ var/conflict = data[MOVESPEED_DATA_INDEX_CONFLICT]
+ var/amt = data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]
+ if(conflict)
+ // Conflicting modifiers prioritize the larger slowdown or the larger speedup
+ // We purposefuly don't handle mixing speedups and slowdowns on the same id
+ if(abs(conflict_tracker[conflict]) < abs(amt))
+ conflict_tracker[conflict] = amt
+ else
+ continue
+ . += amt
cached_multiplicative_slowdown = .
/mob/proc/get_movespeed_modifiers()
diff --git a/code/modules/mob/mob_transformation_simple.dm b/code/modules/mob/mob_transformation_simple.dm
index 673548ff48..2c2efee534 100644
--- a/code/modules/mob/mob_transformation_simple.dm
+++ b/code/modules/mob/mob_transformation_simple.dm
@@ -47,13 +47,13 @@
D.updateappearance(mutcolor_update=1, mutations_overlay_update=1)
else if(ishuman(M))
var/mob/living/carbon/human/H = M
- client.prefs.copy_to(H)
+ client?.prefs.copy_to(H)
H.dna.update_dna_identity()
if(mind && isliving(M))
mind.transfer_to(M, 1) // second argument to force key move to new mob
else
- M.key = key
+ transfer_ckey(M)
if(delete_old_mob)
QDEL_IN(src, 1)
diff --git a/code/modules/mob/transform_procs.dm b/code/modules/mob/transform_procs.dm
index 5703e2190b..6394b45aa7 100644
--- a/code/modules/mob/transform_procs.dm
+++ b/code/modules/mob/transform_procs.dm
@@ -75,7 +75,7 @@
O.setOxyLoss(getOxyLoss(), 0)
O.setCloneLoss(getCloneLoss(), 0)
O.adjustFireLoss(getFireLoss(), 0)
- O.setBrainLoss(getBrainLoss(), 0)
+ O.setOrganLoss(ORGAN_SLOT_BRAIN, getOrganLoss(ORGAN_SLOT_BRAIN), 0)
O.adjustStaminaLoss(getStaminaLoss(), 0)//CIT CHANGE - makes monkey transformations inherit stamina
O.updatehealth()
O.radiation = radiation
@@ -236,7 +236,7 @@
O.setOxyLoss(getOxyLoss(), 0)
O.setCloneLoss(getCloneLoss(), 0)
O.adjustFireLoss(getFireLoss(), 0)
- O.setBrainLoss(getBrainLoss(), 0)
+ O.setOrganLoss(ORGAN_SLOT_BRAIN, getOrganLoss(ORGAN_SLOT_BRAIN), 0)
O.adjustStaminaLoss(getStaminaLoss(), 0)//CIT CHANGE - makes monkey transformations inherit stamina
O.updatehealth()
O.radiation = radiation
@@ -382,7 +382,7 @@
mind.active = FALSE
mind.transfer_to(R)
else if(transfer_after)
- R.key = key
+ transfer_ckey(R)
R.apply_pref_name("cyborg")
@@ -401,7 +401,7 @@
qdel(src)
//human -> alien
-/mob/living/carbon/human/proc/Alienize()
+/mob/living/carbon/human/proc/Alienize(mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -425,13 +425,16 @@
new_xeno = new /mob/living/carbon/alien/humanoid/drone(loc)
new_xeno.a_intent = INTENT_HARM
- new_xeno.key = key
+ if(mind && mind_transfer)
+ mind.transfer_to(new_xeno)
+ else
+ transfer_ckey(new_xeno)
to_chat(new_xeno, "You are now an alien. ")
. = new_xeno
qdel(src)
-/mob/living/carbon/human/proc/slimeize(reproduce as num)
+/mob/living/carbon/human/proc/slimeize(reproduce, mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -457,20 +460,26 @@
else
new_slime = new /mob/living/simple_animal/slime(loc)
new_slime.a_intent = INTENT_HARM
- new_slime.key = key
+ if(mind && mind_transfer)
+ mind.transfer_to(new_slime)
+ else
+ transfer_ckey(new_slime)
to_chat(new_slime, "You are now a slime. Skreee! ")
. = new_slime
qdel(src)
-/mob/proc/become_overmind(starting_points = 60)
+/mob/proc/become_overmind(starting_points = 60, mind_transfer = FALSE)
var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points)
- B.key = key
+ if(mind && mind_transfer)
+ mind.transfer_to(B)
+ else
+ transfer_ckey(B)
. = B
qdel(src)
-/mob/living/carbon/human/proc/corgize()
+/mob/living/carbon/human/proc/corgize(mind_transfer = TRUE)
if (notransform)
return
for(var/obj/item/W in src)
@@ -485,13 +494,16 @@
var/mob/living/simple_animal/pet/dog/corgi/new_corgi = new /mob/living/simple_animal/pet/dog/corgi (loc)
new_corgi.a_intent = INTENT_HARM
- new_corgi.key = key
+ if(mind && mind_transfer)
+ mind.transfer_to(new_corgi)
+ else
+ transfer_ckey(new_corgi)
to_chat(new_corgi, "You are now a Corgi. Yap Yap! ")
. = new_corgi
qdel(src)
-/mob/living/carbon/proc/gorillize()
+/mob/living/carbon/proc/gorillize(mind_transfer = TRUE)
if(notransform)
return
@@ -509,22 +521,22 @@
invisibility = INVISIBILITY_MAXIMUM
var/mob/living/simple_animal/hostile/gorilla/new_gorilla = new (get_turf(src))
new_gorilla.a_intent = INTENT_HARM
- if(mind)
+ if(mind && mind_transfer)
mind.transfer_to(new_gorilla)
else
- new_gorilla.key = key
+ transfer_ckey(new_gorilla)
to_chat(new_gorilla, "You are now a gorilla. Ooga ooga! ")
. = new_gorilla
qdel(src)
-/mob/living/carbon/human/Animalize()
+/mob/living/carbon/human/Animalize(mind_transfer = TRUE)
var/list/mobtypes = typesof(/mob/living/simple_animal)
- var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
-
- if(!safe_animal(mobpath))
- to_chat(usr, "Sorry but this mob type is currently unavailable. ")
+ var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") as null|anything in mobtypes
+ if(!mobpath)
return
+ if(mind)
+ mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
if(notransform)
return
@@ -532,8 +544,8 @@
dropItemToGround(W)
regenerate_icons()
- notransform = 1
- canmove = 0
+ notransform = TRUE
+ canmove = FALSE
icon = null
invisibility = INVISIBILITY_MAXIMUM
@@ -541,8 +553,10 @@
qdel(t)
var/mob/new_mob = new mobpath(src.loc)
-
- new_mob.key = key
+ if(mind && mind_transfer)
+ mind.transfer_to(new_mob)
+ else
+ transfer_ckey(new_mob)
new_mob.a_intent = INTENT_HARM
@@ -550,59 +564,23 @@
. = new_mob
qdel(src)
-/mob/proc/Animalize()
+/mob/proc/Animalize(mind_transfer = TRUE)
var/list/mobtypes = typesof(/mob/living/simple_animal)
- var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
-
- if(!safe_animal(mobpath))
- to_chat(usr, "Sorry but this mob type is currently unavailable. ")
+ var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") as null|anything in mobtypes
+ if(!mobpath)
return
+ if(mind)
+ mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
var/mob/new_mob = new mobpath(src.loc)
- new_mob.key = key
+ if(mind && mind_transfer)
+ mind.transfer_to(new_mob)
+ else
+ transfer_ckey(new_mob)
new_mob.a_intent = INTENT_HARM
to_chat(new_mob, "You feel more... animalistic")
. = new_mob
qdel(src)
-
-/* Certain mob types have problems and should not be allowed to be controlled by players.
- *
- * This proc is here to force coders to manually place their mob in this list, hopefully tested.
- * This also gives a place to explain -why- players shouldnt be turn into certain mobs and hopefully someone can fix them.
- */
-/mob/proc/safe_animal(MP)
-
-//Bad mobs! - Remember to add a comment explaining what's wrong with the mob
- if(!MP)
- return 0 //Sanity, this should never happen.
-
- if(ispath(MP, /mob/living/simple_animal/hostile/construct))
- return 0 //Verbs do not appear for players.
-
-//Good mobs!
- if(ispath(MP, /mob/living/simple_animal/pet/cat))
- return 1
- if(ispath(MP, /mob/living/simple_animal/pet/dog/corgi))
- return 1
- if(ispath(MP, /mob/living/simple_animal/crab))
- return 1
- if(ispath(MP, /mob/living/simple_animal/hostile/carp))
- return 1
- if(ispath(MP, /mob/living/simple_animal/hostile/mushroom))
- return 1
- if(ispath(MP, /mob/living/simple_animal/shade))
- return 1
- if(ispath(MP, /mob/living/simple_animal/hostile/killertomato))
- return 1
- if(ispath(MP, /mob/living/simple_animal/mouse))
- return 1 //It is impossible to pull up the player panel for mice (Fixed! - Nodrak)
- if(ispath(MP, /mob/living/simple_animal/hostile/bear))
- return 1 //Bears will auto-attack mobs, even if they're player controlled (Fixed! - Nodrak)
- if(ispath(MP, /mob/living/simple_animal/parrot))
- return 1 //Parrots are no longer unfinished! -Nodrak
-
- //Not in here? Must be untested!
- return 0
diff --git a/code/modules/modular_computers/computers/item/processor.dm b/code/modules/modular_computers/computers/item/processor.dm
index 99d648d02b..b86d4e5d0d 100644
--- a/code/modules/modular_computers/computers/item/processor.dm
+++ b/code/modules/modular_computers/computers/item/processor.dm
@@ -17,8 +17,7 @@
machinery_computer = null
/obj/item/modular_computer/processor/New(comp)
- STOP_PROCESSING(SSobj, src) // Processed by its machine
-
+ . = ..()
if(!comp || !istype(comp, /obj/machinery/modular_computer))
CRASH("Inapropriate type passed to obj/item/modular_computer/processor/New()! Aborting.")
return
diff --git a/code/modules/modular_computers/file_system/programs/file_browser.dm b/code/modules/modular_computers/file_system/programs/file_browser.dm
index 090d64e9d7..2de2d64754 100644
--- a/code/modules/modular_computers/file_system/programs/file_browser.dm
+++ b/code/modules/modular_computers/file_system/programs/file_browser.dm
@@ -146,7 +146,7 @@
t = replacetext(t, "\[u\]", "")
t = replacetext(t, "\[/u\]", " ")
t = replacetext(t, "\[time\]", "[STATION_TIME_TIMESTAMP("hh:mm:ss")]")
- t = replacetext(t, "\[date\]", "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer+540]")
+ t = replacetext(t, "\[date\]", "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]")
t = replacetext(t, "\[large\]", "")
t = replacetext(t, "\[/large\]", " ")
t = replacetext(t, "\[h1\]", "")
diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm
index 94be922fdf..8c304d8a2b 100644
--- a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm
+++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm
@@ -8,7 +8,7 @@ Contents:
/obj/item/clothing/suit/space/space_ninja/proc/toggle_stealth()
- if(!affecting)
+ if(!affecting || stealth_cooldown > world.time)
return
if(stealth)
cancel_stealth()
@@ -16,26 +16,34 @@ Contents:
if(cell.charge <= 0)
to_chat(affecting, "You don't have enough power to enable Stealth! ")
return
- stealth = !stealth
- animate(affecting, alpha = 10,time = 15)
+ stealth = TRUE
+ stealth_cooldown = world.time + 5 SECONDS
+ animate(affecting, alpha = 15, time = 3 SECONDS)
affecting.visible_message("[affecting.name] vanishes into thin air! ", \
"You are now mostly invisible to normal detection. ")
- RegisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY), .proc/reduce_stealth)
- RegisterSignal(affecting, COMSIG_MOVABLE_BUMP, .proc/bumping_stealth)
+ addtimer(CALLBACK(src, .proc/enable_signals), 3 SECONDS)
-/obj/item/clothing/suit/space/space_ninja/proc/reduce_stealth()
- affecting.alpha = min(affecting.alpha + 30, 80)
+/obj/item/clothing/suit/space/space_ninja/proc/enable_signals()
+ if(!affecting)
+ return
+ RegisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE), .proc/reduce_stealth)
+ RegisterSignal(affecting, COMSIG_MOVABLE_BUMP, .proc/bumping_stealth)
+
+
+/obj/item/clothing/suit/space/space_ninja/proc/reduce_stealth(datum/source)
+ affecting.alpha = min(affecting.alpha + 40, 100)
/obj/item/clothing/suit/space/space_ninja/proc/bumping_stealth(datum/source, atom/A)
if(isliving(A))
- affecting.alpha = min(affecting.alpha + 15, 80)
+ affecting.alpha = min(affecting.alpha + 20, 100)
/obj/item/clothing/suit/space/space_ninja/proc/cancel_stealth()
if(!affecting || !stealth)
return FALSE
stealth = !stealth
- UnregisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_BUMP))
- animate(affecting, alpha = 255, time = 15)
+ stealth_cooldown = world.time + 5 SECONDS
+ UnregisterSignal(affecting, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_PARENT_ATTACKBY, COMSIG_MOVABLE_BUMP, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE))
+ animate(affecting, alpha = 255, time = 3 SECONDS)
affecting.visible_message("[affecting.name] appears from thin air! ", \
"You are now visible. ")
return TRUE
diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm
index ac1ef3b96a..d89bb9edf2 100644
--- a/code/modules/ninja/suit/suit.dm
+++ b/code/modules/ninja/suit/suit.dm
@@ -49,6 +49,7 @@ Contents:
//Support function variables.
var/stealth = FALSE//Stealth off.
+ var/stealth_cooldown = 0
var/s_busy = FALSE//Is the suit busy with a process? Like AI hacking. Used for safety functions.
//Ability function variables.
diff --git a/code/modules/ninja/suit/suit_process.dm b/code/modules/ninja/suit/suit_process.dm
index 850fb837b4..5c1276e29a 100644
--- a/code/modules/ninja/suit/suit_process.dm
+++ b/code/modules/ninja/suit/suit_process.dm
@@ -7,9 +7,9 @@
s_coold--//Checks for ability s_cooldown first.
cell.charge -= s_cost//s_cost is the default energy cost each tick, usually 5.
- if(stealth)//If stealth is active.
+ if(stealth && stealth_cooldown <= world.time)//If stealth is active.
cell.charge -= s_acost
- affecting.alpha = max(affecting.alpha - 10, 10)
+ affecting.alpha = max(affecting.alpha - 10, 15)
else
cell.charge = 0
diff --git a/code/modules/oracle_ui/hookup_procs.dm b/code/modules/oracle_ui/hookup_procs.dm
index e6038744c1..0a092caf30 100644
--- a/code/modules/oracle_ui/hookup_procs.dm
+++ b/code/modules/oracle_ui/hookup_procs.dm
@@ -23,6 +23,8 @@
return TRUE
if(user.incapacitated())
return FALSE
+ if(isobj(src.loc) && get_dist(src, user) < 2)
+ return TRUE
if(isturf(src.loc) && Adjacent(user))
return TRUE
return FALSE
diff --git a/code/modules/paperwork/contract.dm b/code/modules/paperwork/contract.dm
index 676774ff88..3009a3ebfd 100644
--- a/code/modules/paperwork/contract.dm
+++ b/code/modules/paperwork/contract.dm
@@ -173,7 +173,7 @@
attempt_signature(user)
else if(istype(P, /obj/item/stamp))
to_chat(user, "You stamp the paper with your rubber stamp, however the ink ignites as you release the stamp. ")
- else if(P.is_hot())
+ else if(P.get_temperature())
user.visible_message("[user] brings [P] next to [src], but [src] does not catch fire! ", "[src] refuses to ignite! ")
else
return ..()
diff --git a/code/modules/paperwork/filingcabinet.dm b/code/modules/paperwork/filingcabinet.dm
index 907fccdc5b..ccbcf34d8c 100644
--- a/code/modules/paperwork/filingcabinet.dm
+++ b/code/modules/paperwork/filingcabinet.dm
@@ -67,6 +67,9 @@
/obj/structure/filingcabinet/ui_interact(mob/user)
. = ..()
+ if(isobserver(user))
+ return
+
if(contents.len <= 0)
to_chat(user, "[src] is empty. ")
return
diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm
index 059a42bb36..1d6326a3ed 100644
--- a/code/modules/paperwork/paper.dm
+++ b/code/modules/paperwork/paper.dm
@@ -32,6 +32,7 @@
var/contact_poison // Reagent ID to transfer on contact
var/contact_poison_volume = 0
var/datum/oracle_ui/ui = null
+ var/force_stars = FALSE // If we should force the text to get obfuscated with asterisks
/obj/item/paper/pickup(user)
@@ -59,7 +60,8 @@
updateinfolinks()
/obj/item/paper/oui_getcontent(mob/target)
- if(!target.is_literate())
+ if(!target.is_literate() || force_stars)
+ force_stars = FALSE
return "[name] [stars(info)] [stamps]"
else if(istype(target.get_active_held_item(), /obj/item/pen) | istype(target.get_active_held_item(), /obj/item/toy/crayon))
return "[name] [info_links] [stamps]"
@@ -70,8 +72,8 @@
if(check_rights_for(target.client, R_FUN)) //Allows admins to view faxes
return TRUE
if(isAI(target))
- var/mob/living/silicon/ai/ai = target
- return get_dist(src, ai.current) < 2
+ force_stars = TRUE
+ return TRUE
if(iscyborg(target))
return get_dist(src, target) < 2
return ..()
@@ -133,18 +135,8 @@
playsound(loc, 'sound/items/bikehorn.ogg', 50, 1)
addtimer(CALLBACK(src, .proc/reset_spamflag), 20)
-
/obj/item/paper/attack_ai(mob/living/silicon/ai/user)
- var/dist
- if(istype(user) && user.current) //is AI
- dist = get_dist(src, user.current)
- else //cyborg or AI not seeing through a camera
- dist = get_dist(src, user)
- if(dist < 2)
- show_content(user)
- else
- to_chat(user, "You can't quite see it. ")
-
+ show_content(user)
/obj/item/paper/proc/addtofield(id, text, links = 0)
var/locid = 0
@@ -331,7 +323,7 @@
to_chat(user, "You stamp the paper with your rubber stamp. ")
ui.render_all()
- if(P.is_hot())
+ if(P.get_temperature())
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10))
user.visible_message("[user] accidentally ignites [user.p_them()]self! ", \
"You miss the paper and accidentally light yourself on fire! ")
diff --git a/code/modules/paperwork/paperbin.dm b/code/modules/paperwork/paperbin.dm
index e0aeaa106d..6d9c6373ba 100644
--- a/code/modules/paperwork/paperbin.dm
+++ b/code/modules/paperwork/paperbin.dm
@@ -154,7 +154,7 @@
qdel(src)
/obj/item/paper_bin/bundlenatural/attackby(obj/item/W, mob/user)
- if(W.is_sharp())
+ if(W.get_sharpness())
to_chat(user, "You snip \the [src], spilling paper everywhere. ")
var/turf/T = get_turf(src.loc)
while(total_paper > 0)
diff --git a/code/modules/paperwork/paperplane.dm b/code/modules/paperwork/paperplane.dm
index 4b08ccf608..b547089aef 100644
--- a/code/modules/paperwork/paperplane.dm
+++ b/code/modules/paperwork/paperplane.dm
@@ -76,7 +76,7 @@
internalPaper.attackby(P, user) //spoofed attack to update internal paper.
update_icon()
- else if(P.is_hot())
+ else if(P.get_temperature())
if(HAS_TRAIT(user, TRAIT_CLUMSY) && prob(10))
user.visible_message("[user] accidentally ignites [user.p_them()]self! ", \
"You miss [src] and accidentally light yourself on fire! ")
diff --git a/code/modules/paperwork/pen.dm b/code/modules/paperwork/pen.dm
index 5bcb7a60df..fece60f268 100644
--- a/code/modules/paperwork/pen.dm
+++ b/code/modules/paperwork/pen.dm
@@ -158,6 +158,7 @@
if(..())
if(reagents.total_volume)
if(M.reagents)
+ reagents.reaction(M, INJECT)
reagents.trans_to(M, reagents.total_volume)
@@ -200,7 +201,7 @@
throwforce = 35
playsound(user, 'sound/weapons/saberon.ogg', 5, 1)
to_chat(user, "[src] is now active. ")
- GET_COMPONENT_FROM(butchering, /datum/component/butchering, src)
+ var/datum/component/butchering/butchering = src.GetComponent(/datum/component/butchering)
butchering.butchering_enabled = on
update_icon()
diff --git a/code/modules/photography/photos/album.dm b/code/modules/photography/photos/album.dm
index bd77d468d7..3400ed6de0 100644
--- a/code/modules/photography/photos/album.dm
+++ b/code/modules/photography/photos/album.dm
@@ -13,7 +13,7 @@
/obj/item/storage/photo_album/Initialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.can_hold = typecacheof(list(/obj/item/photo))
STR.max_combined_w_class = 42
STR.max_items = 21
diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm
index d837f0d420..5fc29cb813 100644
--- a/code/modules/power/apc.dm
+++ b/code/modules/power/apc.dm
@@ -802,8 +802,6 @@
if(!ui)
ui = new(user, src, ui_key, "apc", name, 535, 515, master_ui, state)
ui.open()
- if(ui)
- ui.set_autoupdate(state = (failure_timer ? 1 : 0))
/obj/machinery/power/apc/ui_data(mob/user)
var/list/data = list(
diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm
index 3e93d9f42b..bbbf8edae5 100644
--- a/code/modules/power/cell.dm
+++ b/code/modules/power/cell.dm
@@ -20,6 +20,7 @@
var/self_recharge = 0 //does it self recharge, over time, or not?
var/ratingdesc = TRUE
var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it.
+ rad_flags = RAD_NO_CONTAMINATE // Prevent the same cheese as with the stock parts
/obj/item/stock_parts/cell/get_cell()
return src
@@ -191,7 +192,7 @@
/obj/item/stock_parts/cell/secborg
name = "security borg rechargeable D battery"
- maxcharge = 1750 //35/17/8 disabler/laser/taser shots.
+ maxcharge = 1250 //25/12/6 disabler/laser/taser shots.
materials = list(MAT_GLASS=40)
/obj/item/stock_parts/cell/secborg/empty/Initialize()
@@ -201,7 +202,7 @@
/obj/item/stock_parts/cell/lascarbine
name = "laser carbine power supply"
- maxcharge = 2500
+ maxcharge = 1500 //20 laser shots.
/obj/item/stock_parts/cell/pulse //200 pulse shots
name = "pulse rifle power cell"
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 4d6ede69d1..71a8565d26 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -199,6 +199,7 @@
if(prob(35))
sparks.start()
P.firer = user ? user : src
+ P.fired_from = src
if(last_projectile_params)
P.p_x = last_projectile_params[2]
P.p_y = last_projectile_params[3]
diff --git a/code/modules/power/supermatter/supermatter.dm b/code/modules/power/supermatter/supermatter.dm
index 3c151d4e77..e6fa1e0ee4 100644
--- a/code/modules/power/supermatter/supermatter.dm
+++ b/code/modules/power/supermatter/supermatter.dm
@@ -29,7 +29,7 @@
#define MOLE_HEAT_PENALTY 350 //Heat damage scales around this. Too hot setups with this amount of moles do regular damage, anything above and below is scaled
#define POWER_PENALTY_THRESHOLD 5000 //Higher == Engine can generate more power before triggering the high power penalties.
#define SEVERE_POWER_PENALTY_THRESHOLD 7000 //Same as above, but causes more dangerous effects
-#define CRITICAL_POWER_PENALTY_THRESHOLD 9000 //Even more dangerous effects, threshold for tesla delamination
+#define CRITICAL_POWER_PENALTY_THRESHOLD 12000 //Even more dangerous effects, threshold for tesla delamination
#define HEAT_PENALTY_THRESHOLD 40 //Higher == Crystal safe operational temperature is higher.
#define DAMAGE_HARDCAP 0.002
#define DAMAGE_INCREASE_MULTIPLIER 0.25
@@ -329,6 +329,12 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(power)
soundloop.volume = min(40, (round(power/100)/50)+1) // 5 +1 volume per 20 power. 2500 power is max
+ if(isclosedturf(T))
+ var/turf/did_it_melt = T.Melt()
+ if(!isclosedturf(did_it_melt)) //In case some joker finds way to place these on indestructible walls
+ visible_message("[src] melts through [T]! ")
+ return
+
//Ok, get the air from the turf
var/datum/gas_mixture/env = T.return_air()
@@ -415,7 +421,7 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
if(prob(50))
radiation_pulse(src, power * (1 + (tritiumcomp * TRITIUM_RADIOACTIVITY_MODIFIER) + ((pluoxiumcomp * PLUOXIUM_RADIOACTIVITY_MODIFIER) * pluoxiumbonus) * (power_transmission_bonus/(10-(bzcomp * BZ_RADIOACTIVITY_MODIFIER))))) // Rad Modifiers BZ(500%), Tritium(300%), and Pluoxium(-200%)
if(bzcomp >= 0.4 && prob(30 * bzcomp))
- src.fire_nuclear_particles() // Start to emit radballs at a maximum of 30% chance per tick
+ fire_nuclear_particle() // Start to emit radballs at a maximum of 30% chance per tick
var/device_energy = power * REACTION_POWER_MODIFIER
diff --git a/code/modules/projectiles/ammunition/_firing.dm b/code/modules/projectiles/ammunition/_firing.dm
index 441088c78c..a83042c90a 100644
--- a/code/modules/projectiles/ammunition/_firing.dm
+++ b/code/modules/projectiles/ammunition/_firing.dm
@@ -1,8 +1,8 @@
-/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread)
+/obj/item/ammo_casing/proc/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from)
distro += variance
for (var/i = max(1, pellets), i > 0, i--)
var/targloc = get_turf(target)
- ready_proj(target, user, quiet, zone_override)
+ ready_proj(target, user, quiet, zone_override, fired_from)
if(distro) //We have to spread a pixel-precision bullet. throw_proj was called before so angles should exist by now...
if(randomspread)
spread = round((rand() - 0.5) * distro)
@@ -20,11 +20,12 @@
update_icon()
return 1
-/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override = "")
+/obj/item/ammo_casing/proc/ready_proj(atom/target, mob/living/user, quiet, zone_override = "", fired_from)
if (!BB)
return
BB.original = target
BB.firer = user
+ BB.fired_from = fired_from
if (zone_override)
BB.def_zone = zone_override
else
diff --git a/code/modules/projectiles/ammunition/caseless/_caseless.dm b/code/modules/projectiles/ammunition/caseless/_caseless.dm
index a6b65f79e3..11f7b8670d 100644
--- a/code/modules/projectiles/ammunition/caseless/_caseless.dm
+++ b/code/modules/projectiles/ammunition/caseless/_caseless.dm
@@ -3,7 +3,7 @@
firing_effect_type = null
heavy_metal = FALSE
-/obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread)
+/obj/item/ammo_casing/caseless/fire_casing(atom/target, mob/living/user, params, distro, quiet, zone_override, spread, atom/fired_from)
if (..()) //successfully firing
moveToNullspace()
QDEL_NULL(src)
diff --git a/code/modules/projectiles/ammunition/energy/laser.dm b/code/modules/projectiles/ammunition/energy/laser.dm
index 638711e8d4..0940144721 100644
--- a/code/modules/projectiles/ammunition/energy/laser.dm
+++ b/code/modules/projectiles/ammunition/energy/laser.dm
@@ -71,9 +71,3 @@
projectile_type = /obj/item/projectile/beam/mindflayer
select_name = "MINDFUCK"
fire_sound = 'sound/weapons/laser.ogg'
-
-/obj/item/ammo_casing/energy/laser/weak
- projectile_type = /obj/item/projectile/beam/weak/minigun
- e_cost = 10
- fire_sound = 'sound/weapons/gatling.ogg'
- click_cooldown_override = 1
diff --git a/code/modules/projectiles/ammunition/energy/stun.dm b/code/modules/projectiles/ammunition/energy/stun.dm
index c9e60ddc1d..36d6e16496 100644
--- a/code/modules/projectiles/ammunition/energy/stun.dm
+++ b/code/modules/projectiles/ammunition/energy/stun.dm
@@ -25,3 +25,6 @@
fire_sound = 'sound/weapons/taser2.ogg'
harmful = FALSE
click_cooldown_override = 3.5
+
+/obj/item/ammo_casing/energy/disabler/secborg
+ e_cost = 50
\ No newline at end of file
diff --git a/code/modules/projectiles/boxes_magazines/external/smg.dm b/code/modules/projectiles/boxes_magazines/external/smg.dm
index 65724e503a..783b8b895b 100644
--- a/code/modules/projectiles/boxes_magazines/external/smg.dm
+++ b/code/modules/projectiles/boxes_magazines/external/smg.dm
@@ -3,11 +3,11 @@
icon_state = "46x30mmt-20"
ammo_type = /obj/item/ammo_casing/c46x30mm
caliber = "4.6x30mm"
- max_ammo = 20
+ max_ammo = 32
/obj/item/ammo_box/magazine/wt550m9/update_icon()
..()
- icon_state = "46x30mmt-[round(ammo_count(),4)]"
+ icon_state = "46x30mmt-[round(20*(ammo_count()/max_ammo),4)]"
/obj/item/ammo_box/magazine/wt550m9/wtap
name = "wt550 magazine (Armour Piercing 4.6x30mm)"
@@ -16,7 +16,7 @@
/obj/item/ammo_box/magazine/wt550m9/wtap/update_icon()
..()
- icon_state = "46x30mmtA-[round(ammo_count(),4)]"
+ icon_state = "46x30mmtA-[round(20*(ammo_count()/max_ammo),4)]"
/obj/item/ammo_box/magazine/wt550m9/wtic
name = "wt550 magazine (Incendiary 4.6x30mm)"
@@ -25,7 +25,7 @@
/obj/item/ammo_box/magazine/wt550m9/wtic/update_icon()
..()
- icon_state = "46x30mmtI-[round(ammo_count(),4)]"
+ icon_state = "46x30mmtI-[round(20*(ammo_count()/max_ammo),4)]"
/obj/item/ammo_box/magazine/uzim9mm
name = "uzi magazine (9mm)"
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index fb3ed19f82..96b396243b 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -34,6 +34,7 @@
var/semicd = 0 //cooldown handler
var/weapon_weight = WEAPON_LIGHT //currently only used for inaccuracy
var/spread = 0 //Spread induced by the gun itself.
+ var/burst_spread = 0 //Spread induced by the gun itself during burst fire per iteration. Only checked if spread is 0.
var/randomspread = 1 //Set to 0 for shotguns. This is used for weapons that don't fire all their bullets at once.
var/inaccuracy_modifier = 1
@@ -62,16 +63,18 @@
var/zoomed = FALSE //Zoom toggle
var/zoom_amt = 3 //Distance in TURFs to move the user's screen forward (the "zoom" effect)
var/zoom_out_amt = 0
- var/datum/action/toggle_scope_zoom/azoom
+ var/datum/action/item_action/toggle_scope_zoom/azoom
+
+ var/dualwield_spread_mult = 1 //dualwield spread multiplier
/obj/item/gun/Initialize()
. = ..()
if(pin)
pin = new pin(src)
if(gun_light)
- alight = new /datum/action/item_action/toggle_gunlight(src)
- build_zooming()
-
+ alight = new (src)
+ if(zoomable)
+ azoom = new (src)
/obj/item/gun/CheckParts(list/parts_list)
..()
@@ -185,7 +188,7 @@
if(G == src || G.weapon_weight >= WEAPON_MEDIUM)
continue
else if(G.can_trigger_gun(user))
- bonus_spread += 24 * G.weapon_weight
+ bonus_spread += 24 * G.weapon_weight * G.dualwield_spread_mult
loop_counter++
addtimer(CALLBACK(G, /obj/item/gun.proc/process_fire, target, user, TRUE, params, null, bonus_spread), loop_counter)
@@ -226,11 +229,11 @@
to_chat(user, " [src] is lethally chambered! You don't want to risk harming anyone... ")
return
if(randomspread)
- sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
+ sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread), 1)
else //Smart spread
- sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread))
+ sprd = round((((rand_spr/burst_size) * iteration) - (0.5 + (rand_spr * 0.25))) * (randomized_gun_spread + randomized_bonus_spread), 1)
- if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd))
+ if(!chambered.fire_casing(target, user, params, ,suppressed, zone_override, sprd, src))
shoot_with_empty_chamber(user)
firing_burst = FALSE
return FALSE
@@ -259,7 +262,9 @@
var/randomized_gun_spread = 0
var/rand_spr = rand()
if(spread)
- randomized_gun_spread = rand(0,spread)
+ randomized_gun_spread = rand(0, spread)
+ else if(burst_size > 1 && burst_spread)
+ randomized_gun_spread = rand(0, burst_spread)
if(HAS_TRAIT(user, TRAIT_POOR_AIM)) //nice shootin' tex
bonus_spread += 25
var/randomized_bonus_spread = rand(0, bonus_spread)
@@ -275,7 +280,7 @@
to_chat(user, " [src] is lethally chambered! You don't want to risk harming anyone... ")
return
sprd = round((rand() - 0.5) * DUALWIELD_PENALTY_EXTRA_MULTIPLIER * (randomized_gun_spread + randomized_bonus_spread))
- if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd))
+ if(!chambered.fire_casing(target, user, params, , suppressed, zone_override, sprd, src))
shoot_with_empty_chamber(user)
return
else
@@ -293,6 +298,7 @@
if(user)
user.update_inv_hands()
+ SEND_SIGNAL(user, COMSIG_LIVING_GUN_PROCESS_FIRE, target, params, zone_override)
SSblackbox.record_feedback("tally", "gun_fired", 1, type)
return TRUE
@@ -372,6 +378,12 @@
else
return ..()
+/obj/item/gun/ui_action_click(mob/user, action)
+ if(istype(action, /datum/action/item_action/toggle_scope_zoom))
+ zoom(user)
+ else if(istype(action, alight))
+ toggle_gunlight()
+
/obj/item/gun/proc/toggle_gunlight()
if(!gun_light)
return
@@ -407,21 +419,10 @@
var/datum/action/A = X
A.UpdateButtonIcon()
-/obj/item/gun/pickup(mob/user)
- ..()
- if(azoom)
- azoom.Grant(user)
- if(alight)
- alight.Grant(user)
-
-/obj/item/gun/dropped(mob/user)
- ..()
- if(zoomed)
- zoom(user,FALSE)
- if(azoom)
- azoom.Remove(user)
- if(alight)
- alight.Remove(user)
+/obj/item/gun/item_action_slot_check(slot, mob/user, datum/action/A)
+ if(istype(A, /datum/action/item_action/toggle_scope_zoom) && slot != SLOT_HANDS)
+ return FALSE
+ return ..()
/obj/item/gun/proc/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer)
if(!ishuman(user) || !ishuman(target))
@@ -468,41 +469,32 @@
// ZOOMING //
/////////////
-/datum/action/toggle_scope_zoom
+/datum/action/item_action/toggle_scope_zoom
name = "Toggle Scope"
- check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_LYING
icon_icon = 'icons/mob/actions/actions_items.dmi'
button_icon_state = "sniper_zoom"
- var/obj/item/gun/gun = null
-/datum/action/toggle_scope_zoom/Trigger()
- gun.zoom(owner)
-
-/datum/action/toggle_scope_zoom/IsAvailable()
+/datum/action/item_action/toggle_scope_zoom/IsAvailable()
. = ..()
- if(!gun)
- return FALSE
if(!.)
- gun.zoom(owner, FALSE)
- if(!owner.get_held_index_of_item(gun))
- return FALSE
-
-/datum/action/toggle_scope_zoom/Remove(mob/living/L)
- gun.zoom(L, FALSE)
- ..()
+ var/obj/item/gun/G = target
+ G.zoom(owner, FALSE)
+/datum/action/item_action/toggle_scope_zoom/Remove(mob/living/L)
+ var/obj/item/gun/G = target
+ G.zoom(L, FALSE)
+ return ..()
/obj/item/gun/proc/zoom(mob/living/user, forced_zoom)
- if(!user || !user.client)
+ if(!(user?.client))
return
- switch(forced_zoom)
- if(FALSE)
- zoomed = FALSE
- if(TRUE)
- zoomed = TRUE
- else
- zoomed = !zoomed
+ if(!isnull(forced_zoom))
+ if(zoomed == forced_zoom)
+ return
+ zoomed = forced_zoom
+ else
+ zoomed = !zoomed
if(zoomed)
var/_x = 0
@@ -524,16 +516,6 @@
user.client.change_view(CONFIG_GET(string/default_view))
user.client.pixel_x = 0
user.client.pixel_y = 0
- return zoomed
-
-//Proc, so that gun accessories/scopes/etc. can easily add zooming.
-/obj/item/gun/proc/build_zooming()
- if(azoom)
- return
-
- if(zoomable)
- azoom = new()
- azoom.gun = src
/obj/item/gun/handle_atom_del(atom/A)
if(A == chambered)
diff --git a/code/modules/projectiles/guns/ballistic.dm b/code/modules/projectiles/guns/ballistic.dm
index 1117bc1000..2f198c1319 100644
--- a/code/modules/projectiles/guns/ballistic.dm
+++ b/code/modules/projectiles/guns/ballistic.dm
@@ -26,7 +26,6 @@
else
icon_state = "[initial(icon_state)][suppressed ? "-suppressed" : ""][sawn_off ? "-sawn" : ""]"
-
/obj/item/gun/ballistic/process_chamber(empty_chamber = 1)
var/obj/item/ammo_casing/AC = chambered //Find chambered round
if(istype(AC)) //there's a chambered round
@@ -170,7 +169,7 @@
if(iscarbon(user))
var/mob/living/carbon/C = user
user_dna = C.dna
- B.add_blood_DNA(user_dna)
+ B.add_blood_DNA(user_dna, C.diseases)
var/datum/callback/gibspawner = CALLBACK(GLOBAL_PROC, /proc/spawn_atom_to_turf, /obj/effect/gibspawner/generic, B, 1, FALSE, list(user_dna))
B.throw_at(target, BRAINS_BLOWN_THROW_RANGE, BRAINS_BLOWN_THROW_SPEED, callback=gibspawner)
return(BRUTELOSS)
diff --git a/code/modules/projectiles/guns/ballistic/automatic.dm b/code/modules/projectiles/guns/ballistic/automatic.dm
index 4bd65a7b20..5182c96671 100644
--- a/code/modules/projectiles/guns/ballistic/automatic.dm
+++ b/code/modules/projectiles/guns/ballistic/automatic.dm
@@ -2,6 +2,7 @@
w_class = WEIGHT_CLASS_NORMAL
var/alarmed = 0
var/select = 1
+ var/automatic_burst_overlay = TRUE
can_suppress = TRUE
burst_size = 3
fire_delay = 2
@@ -19,10 +20,11 @@
/obj/item/gun/ballistic/automatic/update_icon()
..()
- if(!select)
- add_overlay("[initial(icon_state)]semi")
- if(select == 1)
- add_overlay("[initial(icon_state)]burst")
+ if(automatic_burst_overlay)
+ if(!select)
+ add_overlay("[initial(icon_state)]semi")
+ if(select == 1)
+ add_overlay("[initial(icon_state)]burst")
icon_state = "[initial(icon_state)][magazine ? "-[magazine.max_ammo]" : ""][chambered ? "" : "-e"][suppressed ? "-suppressed" : ""]"
/obj/item/gun/ballistic/automatic/attackby(obj/item/A, mob/user, params)
@@ -51,19 +53,20 @@
else
to_chat(user, "You cannot seem to get \the [src] out of your hands! ")
-/obj/item/gun/ballistic/automatic/ui_action_click()
- burst_select()
+/obj/item/gun/ballistic/automatic/ui_action_click(mob/user, action)
+ if(istype(action, /datum/action/item_action/toggle_firemode))
+ burst_select()
+ else
+ return ..()
/obj/item/gun/ballistic/automatic/proc/burst_select()
var/mob/living/carbon/human/user = usr
select = !select
if(!select)
- burst_size = 1
- fire_delay = 0
+ disable_burst()
to_chat(user, "You switch to semi-automatic. ")
else
- burst_size = initial(burst_size)
- fire_delay = initial(fire_delay)
+ enable_burst()
to_chat(user, "You switch to [burst_size]-rnd burst. ")
playsound(user, 'sound/weapons/empty.ogg', 100, 1)
@@ -72,6 +75,14 @@
var/datum/action/A = X
A.UpdateButtonIcon()
+/obj/item/gun/ballistic/automatic/proc/enable_burst()
+ burst_size = initial(burst_size)
+ fire_delay = initial(fire_delay)
+
+/obj/item/gun/ballistic/automatic/proc/disable_burst()
+ burst_size = 1
+ fire_delay = 0
+
/obj/item/gun/ballistic/automatic/can_shoot()
return get_ammo()
@@ -106,7 +117,6 @@
/obj/item/gun/ballistic/automatic/c20r/afterattack()
. = ..()
empty_alarm()
- return
/obj/item/gun/ballistic/automatic/c20r/update_icon()
..()
@@ -118,17 +128,25 @@
icon_state = "wt550"
item_state = "arg"
mag_type = /obj/item/ammo_box/magazine/wt550m9
- fire_delay = 2
can_suppress = FALSE
- burst_size = 0
- actions_types = list()
+ burst_size = 2
+ fire_delay = 1
can_bayonet = TRUE
knife_x_offset = 25
knife_y_offset = 12
+ automatic_burst_overlay = FALSE
+
+/obj/item/gun/ballistic/automatic/wt550/enable_burst()
+ . = ..()
+ spread = 15
+
+/obj/item/gun/ballistic/automatic/wt550/disable_burst()
+ . = ..()
+ spread = 0
/obj/item/gun/ballistic/automatic/wt550/update_icon()
..()
- icon_state = "wt550[magazine ? "-[CEILING(get_ammo(0)/4, 1)*4]" : ""]"
+ icon_state = "wt550[magazine ? "-[CEILING(( (get_ammo(FALSE) / magazine.max_ammo) * 20) /4, 1)*4]" : "-0"]" //Sprites only support up to 20.
/obj/item/gun/ballistic/automatic/mini_uzi
name = "\improper Type U3 Uzi"
diff --git a/code/modules/projectiles/guns/ballistic/revolver.dm b/code/modules/projectiles/guns/ballistic/revolver.dm
index f455e0f138..a5fb8a85aa 100644
--- a/code/modules/projectiles/guns/ballistic/revolver.dm
+++ b/code/modules/projectiles/guns/ballistic/revolver.dm
@@ -277,12 +277,12 @@
..()
if(istype(A, /obj/item/ammo_box) || istype(A, /obj/item/ammo_casing))
chamber_round()
+ if(A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter))
+ sawoff(user)
if(istype(A, /obj/item/melee/transforming/energy))
var/obj/item/melee/transforming/energy/W = A
if(W.active)
sawoff(user)
- if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
- sawoff(user)
/obj/item/gun/ballistic/revolver/doublebarrel/attack_self(mob/living/user)
var/num_unloaded = 0
diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm
index d1b99c0e3c..47ccb6076f 100644
--- a/code/modules/projectiles/guns/ballistic/shotgun.dm
+++ b/code/modules/projectiles/guns/ballistic/shotgun.dm
@@ -95,7 +95,7 @@
/obj/item/gun/ballistic/shotgun/riot/attackby(obj/item/A, mob/user, params)
..()
- if(istype(A, /obj/item/circular_saw) || istype(A, /obj/item/gun/energy/plasmacutter))
+ if(A.tool_behaviour == TOOL_SAW || istype(A, /obj/item/gun/energy/plasmacutter))
sawoff(user)
if(istype(A, /obj/item/melee/transforming/energy))
var/obj/item/melee/transforming/energy/W = A
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 6060ceba99..2cccc57d9e 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -174,9 +174,6 @@
itemState += "[ratio]"
item_state = itemState
-/obj/item/gun/energy/ui_action_click()
- toggle_gunlight()
-
/obj/item/gun/energy/suicide_act(mob/living/user)
if (istype(user) && can_shoot() && can_trigger_gun(user) && user.get_bodypart(BODY_ZONE_HEAD))
user.visible_message("[user] is putting the barrel of [src] in [user.p_their()] mouth. It looks like [user.p_theyre()] trying to commit suicide! ")
diff --git a/code/modules/projectiles/guns/energy/energy_gun.dm b/code/modules/projectiles/guns/energy/energy_gun.dm
index de738c9047..163deae0ed 100644
--- a/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -55,7 +55,7 @@
desc = "This is an expensive, modern recreation of an antique laser gun. This gun has several unique firemodes, but lacks the ability to recharge over time."
icon_state = "hoslaser"
force = 10
- ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/laser/hos, /obj/item/ammo_casing/energy/disabler)
+ ammo_type = list(/obj/item/ammo_casing/energy/electrode/hos, /obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser/hos)
ammo_x_offset = 4
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
@@ -97,7 +97,7 @@
pin = null
can_charge = 0
ammo_x_offset = 1
- ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/laser, /obj/item/ammo_casing/energy/disabler)
+ ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/laser)
selfcharge = EGUN_SELFCHARGE
var/fail_tick = 0
var/fail_chance = 0
diff --git a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
index a4ec979a06..646b4bd57d 100644
--- a/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
+++ b/code/modules/projectiles/guns/energy/kinetic_accelerator.dm
@@ -78,6 +78,12 @@
else
to_chat(user, "There are no modifications currently installed. ")
+/obj/item/gun/energy/kinetic_accelerator/Exited(atom/movable/AM)
+ . = ..()
+ if((AM in modkits) && istype(AM, /obj/item/borg/upgrade/modkit))
+ var/obj/item/borg/upgrade/modkit/M = AM
+ M.uninstall(src, FALSE)
+
/obj/item/gun/energy/kinetic_accelerator/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/borg/upgrade/modkit))
var/obj/item/borg/upgrade/modkit/MK = I
@@ -261,7 +267,7 @@
icon_state = "modkit"
w_class = WEIGHT_CLASS_SMALL
require_module = 1
- module_type = /obj/item/robot_module/miner
+ module_type = list(/obj/item/robot_module/miner)
var/denied_type = null
var/maximum_of_type = 1
var/cost = 30
@@ -287,6 +293,8 @@
/obj/item/borg/upgrade/modkit/proc/install(obj/item/gun/energy/kinetic_accelerator/KA, mob/user)
. = TRUE
+ if(src in KA.modkits) // Sanity check to prevent installing the same modkit twice thanks to occasional click/lag delays.
+ return
if(minebot_upgrade)
if(minebot_exclusive && !istype(KA.loc, /mob/living/simple_animal/hostile/mining_drone))
to_chat(user, "The modkit you're trying to install is only rated for minebot use. ")
@@ -322,11 +330,10 @@
for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA in R.module.modules)
uninstall(KA)
-/obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/gun/energy/kinetic_accelerator/KA)
- forceMove(get_turf(KA))
+/obj/item/borg/upgrade/modkit/proc/uninstall(obj/item/gun/energy/kinetic_accelerator/KA, forcemove = TRUE)
KA.modkits -= src
-
-
+ if(forcemove)
+ forceMove(get_turf(KA))
/obj/item/borg/upgrade/modkit/proc/modify_projectile(obj/item/projectile/kinetic/K)
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index bb97f9cf99..2bb813d793 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -181,7 +181,7 @@
/obj/item/gun/energy/laser/redtag/hitscan/chaplain/Initialize()
. = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
+ AddComponent(/datum/component/anti_magic, TRUE, TRUE, FALSE, null, null, FALSE)
/obj/item/gun/energy/laser/redtag/hitscan/chaplain/handle_suicide(mob/living/carbon/human/user, mob/living/carbon/human/target, params, bypass_timer)
if(!ishuman(user) || !ishuman(target))
diff --git a/code/modules/projectiles/guns/energy/minigun.dm b/code/modules/projectiles/guns/energy/minigun.dm
deleted file mode 100644
index d903cda47c..0000000000
--- a/code/modules/projectiles/guns/energy/minigun.dm
+++ /dev/null
@@ -1,149 +0,0 @@
-//The ammo/gun is stored in a back slot item
-/obj/item/minigunpack2
- name = " Laser Gatling Pack"
- desc = "A massive battery pack with an attached laser gatling gun!"
- icon = 'icons/obj/guns/minigun.dmi'
- icon_state = "holstered"
- item_state = "backpack"
- lefthand_file = 'icons/mob/inhands/equipment/backpack_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/backpack_righthand.dmi'
- slot_flags = ITEM_SLOT_BACK
- w_class = WEIGHT_CLASS_HUGE
- var/obj/item/gun/energy/minigun/gun
- var/armed = 0 //whether the gun is attached, 0 is attached, 1 is the gun is wielded.
- var/overheat = 0
- var/overheat_max = 60
- var/heat_diffusion = 5
-
-/obj/item/minigunpack2/Initialize()
- . = ..()
- gun = new(src)
- START_PROCESSING(SSobj, src)
-
-/obj/item/minigunpack2/Destroy()
- STOP_PROCESSING(SSobj, src)
- return ..()
-
-/obj/item/minigunpack2/process()
- overheat = max(0, overheat - heat_diffusion)
-
-//ATTACK HAND IGNORING PARENT RETURN VALUE
-/obj/item/minigunpack2/attack_hand(var/mob/living/carbon/user)
- if(src.loc == user)
- if(!armed)
- if(user.get_item_by_slot(SLOT_BACK) == src)
- armed = 1
- if(!user.put_in_hands(gun))
- armed = 0
- to_chat(user, "You need a free hand to hold the gun! ")
- return
- update_icon()
- user.update_inv_back()
- else
- to_chat(user, "You are already holding the gun! ")
- else
- ..()
-
-/obj/item/minigunpack2/attackby(obj/item/W, mob/user, params)
- if(W == gun) //Don't need armed check, because if you have the gun assume its armed.
- user.dropItemToGround(gun, TRUE)
- else
- ..()
-
-/obj/item/minigunpack2/dropped(mob/user)
- if(armed)
- user.dropItemToGround(gun, TRUE)
-
-/obj/item/minigunpack2/MouseDrop(atom/over_object)
- . = ..()
- if(armed)
- return
- if(iscarbon(usr))
- var/mob/M = usr
-
- if(!over_object)
- return
-
- if(!M.incapacitated())
-
- if(istype(over_object, /obj/screen/inventory/hand))
- var/obj/screen/inventory/hand/H = over_object
- M.putItemFromInventoryInHandIfPossible(src, H.held_index)
-
-
-/obj/item/minigunpack2/update_icon()
- if(armed)
- icon_state = "notholstered"
- else
- icon_state = "holstered"
-
-/obj/item/minigunpack2/proc/attach_gun(var/mob/user)
- if(!gun)
- gun = new(src)
- gun.forceMove(src)
- armed = 0
- if(user)
- to_chat(user, "You attach the [gun.name] to the [name]. ")
- else
- src.visible_message("The [gun.name] snaps back onto the [name]! ")
- update_icon()
- user.update_inv_back()
-
-
-/obj/item/gun/energy/minigun
- name = "laser gatling gun"
- desc = "An advanced laser cannon with an incredible rate of fire. Requires a bulky backpack power source to use."
- icon = 'icons/obj/guns/minigun.dmi'
- icon_state = "minigun_spin"
- item_state = "minigun"
- flags_1 = CONDUCT_1
- force = 15
- recoil = 2
- slowdown = 1
- slot_flags = null
- w_class = WEIGHT_CLASS_HUGE
- materials = list()
- ammo_type = list(/obj/item/ammo_casing/energy/laser/weak)
- burst_size = 2
- automatic = 1
- can_charge = 0
- selfcharge = EGUN_SELFCHARGE
- charge_tick = 2
- charge_delay = 5
- weapon_weight = WEAPON_HEAVY
- item_flags = NEEDS_PERMIT | SLOWS_WHILE_IN_HAND
- var/obj/item/minigunpack2/ammo_pack
-
-/obj/item/gun/energy/minigun/Initialize()
- if(istype(loc, /obj/item/minigunpack2)) //We should spawn inside an ammo pack so let's use that one.
- ammo_pack = loc
- else
- return INITIALIZE_HINT_QDEL //No pack, no gun
-
- return ..()
-
-/obj/item/gun/energy/minigun/attack_self(mob/living/user)
- return
-
-/obj/item/gun/energy/minigun/dropped(mob/user)
- if(ammo_pack)
- ammo_pack.attach_gun(user)
- else
- qdel(src)
-
-/obj/item/gun/energy/minigun/process_fire(atom/target, mob/living/user, message = TRUE, params = null, zone_override = "", bonus_spread = 0)
- if(ammo_pack)
- if(ammo_pack.overheat < ammo_pack.overheat_max)
- ammo_pack.overheat += burst_size
- ..()
- else
- to_chat(user, "The gun's heat sensor locked the trigger to prevent lens damage.")
-
-/obj/item/gun/energy/minigun/afterattack(atom/target, mob/living/user, flag, params)
- if(!ammo_pack || ammo_pack.loc != user)
- to_chat(user, "You need the backpack power source to fire the gun!")
- . = ..()
-
-/obj/item/gun/energy/minigun/dropped(mob/living/user)
- ammo_pack.attach_gun(user)
-
diff --git a/code/modules/projectiles/guns/energy/stun.dm b/code/modules/projectiles/guns/energy/stun.dm
index 3733dad9a3..c5d4c36813 100644
--- a/code/modules/projectiles/guns/energy/stun.dm
+++ b/code/modules/projectiles/guns/energy/stun.dm
@@ -20,7 +20,7 @@
name = "hybrid taser"
desc = "A dual-mode taser designed to fire both short-range high-power electrodes and long-range disabler beams."
icon_state = "advtaser"
- ammo_type = list(/obj/item/ammo_casing/energy/electrode, /obj/item/ammo_casing/energy/disabler)
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler, /obj/item/ammo_casing/energy/electrode)
ammo_x_offset = 2
/obj/item/gun/energy/e_gun/advtaser/cyborg
@@ -49,6 +49,7 @@
name = "cyborg disabler"
desc = "An integrated disabler that draws from a cyborg's power cell. This one contains a limiter to prevent the cyborg's power cell from overheating."
can_charge = FALSE
+ ammo_type = list(/obj/item/ammo_casing/energy/disabler/secborg)
selfcharge = EGUN_SELFCHARGE_BORG
cell_type = /obj/item/stock_parts/cell/secborg
charge_delay = 5
diff --git a/code/modules/projectiles/guns/magic.dm b/code/modules/projectiles/guns/magic.dm
index 9dd25bf3e3..55f21a5a2b 100644
--- a/code/modules/projectiles/guns/magic.dm
+++ b/code/modules/projectiles/guns/magic.dm
@@ -9,6 +9,7 @@
fire_sound = 'sound/weapons/emitter.ogg'
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_HUGE
+ var/checks_antimagic = FALSE
var/max_charges = 6
var/charges = 0
var/recharge_rate = 4
@@ -31,6 +32,9 @@
return
else
no_den_usage = 0
+ if(checks_antimagic && user.anti_magic_check(TRUE, FALSE, FALSE, 0, TRUE))
+ to_chat(user, "Something is interfering with [src]. ")
+ return
. = ..()
/obj/item/gun/magic/can_shoot()
diff --git a/code/modules/projectiles/guns/magic/wand.dm b/code/modules/projectiles/guns/magic/wand.dm
index 42033d8c88..4cdfc6d70d 100644
--- a/code/modules/projectiles/guns/magic/wand.dm
+++ b/code/modules/projectiles/guns/magic/wand.dm
@@ -87,14 +87,17 @@
max_charges = 10 //10, 5, 5, 4
/obj/item/gun/magic/wand/resurrection/zap_self(mob/living/user)
+ ..()
+ charges--
+ if(user.anti_magic_check())
+ user.visible_message("[src] has no effect on [user]! ")
+ return
user.revive(full_heal = 1)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.regenerate_limbs()
C.regenerate_organs()
to_chat(user, "You feel great! ")
- charges--
- ..()
/obj/item/gun/magic/wand/resurrection/debug //for testing
name = "debug wand of healing"
diff --git a/code/modules/projectiles/guns/misc/beam_rifle.dm b/code/modules/projectiles/guns/misc/beam_rifle.dm
index e4d13ad315..92fe91c222 100644
--- a/code/modules/projectiles/guns/misc/beam_rifle.dm
+++ b/code/modules/projectiles/guns/misc/beam_rifle.dm
@@ -45,7 +45,7 @@
var/aiming_lastangle = 0
var/mob/current_user = null
var/list/obj/effect/projectile/tracer/current_tracers
-
+
var/structure_piercing = 1
var/structure_bleed_coeff = 0.7
var/wall_pierce_amount = 0
@@ -76,7 +76,7 @@
var/static/image/drained_overlay = image(icon = 'icons/obj/guns/energy.dmi', icon_state = "esniper_empty")
var/datum/action/item_action/zoom_lock_action/zoom_lock_action
- var/datum/component/mobhook
+ var/mob/listeningTo
/obj/item/gun/energy/beam_rifle/debug
delay = 0
@@ -111,7 +111,9 @@
to_chat(owner, "You switch [src]'s zooming processor to center mode. ")
if(ZOOM_LOCK_OFF)
to_chat(owner, "You disable [src]'s zooming system. ")
- reset_zooming()
+ reset_zooming()
+ else
+ return ..()
/obj/item/gun/energy/beam_rifle/proc/set_autozoom_pixel_offsets_immediate(current_angle)
if(zoom_lock == ZOOM_LOCK_CENTER_VIEW || zoom_lock == ZOOM_LOCK_OFF)
@@ -172,7 +174,7 @@
STOP_PROCESSING(SSfastprocess, src)
set_user(null)
QDEL_LIST(current_tracers)
- QDEL_NULL(mobhook)
+ listeningTo = null
return ..()
/obj/item/gun/energy/beam_rifle/emp_act(severity)
@@ -259,14 +261,17 @@
if(user == current_user)
return
stop_aiming(current_user)
- QDEL_NULL(mobhook)
+ if(listeningTo)
+ UnregisterSignal(listeningTo, COMSIG_MOVABLE_MOVED)
+ listeningTo = null
if(istype(current_user))
LAZYREMOVE(current_user.mousemove_intercept_objects, src)
current_user = null
if(istype(user))
current_user = user
LAZYOR(current_user.mousemove_intercept_objects, src)
- mobhook = user.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_mob_move)))
+ RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/on_mob_move)
+ listeningTo = user
/obj/item/gun/energy/beam_rifle/onMouseDrag(src_object, over_object, src_location, over_location, params, mob)
if(aiming)
diff --git a/code/modules/projectiles/guns/misc/syringe_gun.dm b/code/modules/projectiles/guns/misc/syringe_gun.dm
index 26e66b1987..342ceecbc2 100644
--- a/code/modules/projectiles/guns/misc/syringe_gun.dm
+++ b/code/modules/projectiles/guns/misc/syringe_gun.dm
@@ -122,3 +122,32 @@
else
to_chat(user, "You can't put the [A] into \the [src]! ")
return FALSE
+
+/obj/item/gun/syringe/dart/rapiddart
+ name = "Repeating dart gun"
+ icon_state = "rapiddartgun"
+ item_state = "rapiddartgun"
+
+/obj/item/gun/syringe/dart/rapiddart/CheckParts(list/parts_list)
+ var/obj/item/reagent_containers/glass/beaker/B = locate(/obj/item/reagent_containers/glass/beaker) in parts_list
+
+ if(istype(B, /obj/item/reagent_containers/glass/beaker/large))
+ desc = "[initial(desc)] A modification of the dart gun's pressure chamber has been perfomed using a [B], extending it's holding size to [max_syringes]."
+ max_syringes = 2
+ return
+ else if(istype(B, /obj/item/reagent_containers/glass/beaker/plastic))
+ desc = "[initial(desc)] A modification of the dart gun's pressure chamber has been perfomed using a [B], extending it's holding size to [max_syringes]."
+ max_syringes = 3
+ return
+ else if(istype(B, /obj/item/reagent_containers/glass/beaker/meta))
+ desc = "[initial(desc)] A modification of the dart gun's pressure chamber has been perfomed using a [B], extending it's holding size to [max_syringes]."
+ max_syringes = 4
+ return
+ else if(istype(B, /obj/item/reagent_containers/glass/beaker/bluespace))
+ desc = "[initial(desc)] A modification of the dart gun's pressure chamber has been perfomed using a [B], extending it's holding size to [max_syringes]."
+ max_syringes = 6
+ return
+ else
+ max_syringes = 1
+ desc = "[initial(desc)] It has a [B] strapped to it, but it doesn't seem to be doing anything."
+ ..()
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index efae090707..88e766edfc 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -17,6 +17,7 @@
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/def_zone = "" //Aiming at
var/atom/movable/firer = null//Who shot it
+ var/atom/fired_from = null // the atom that the projectile was fired from (gun, turret)
var/suppressed = FALSE //Attack message
var/candink = FALSE //Can this projectile play the dink sound when hitting the head?
var/yo = null
@@ -88,6 +89,8 @@
//Effects
var/stun = 0
var/knockdown = 0
+ var/knockdown_stamoverride
+ var/knockdown_stam_max
var/unconscious = 0
var/irradiate = 0
var/stutter = 0
@@ -129,6 +132,8 @@
return TRUE
/obj/item/projectile/proc/on_hit(atom/target, blocked = FALSE)
+ if(fired_from)
+ SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_ON_HIT, firer, target, Angle)
var/turf/target_loca = get_turf(target)
var/hitx
@@ -161,15 +166,26 @@
var/splatter_dir = dir
if(starting)
splatter_dir = get_dir(starting, target_loca)
- if(isalien(L))
+ var/obj/item/bodypart/B = L.get_bodypart(def_zone)
+ if(B && B.status == BODYPART_ROBOTIC) // So if you hit a robotic, it sparks instead of bloodspatters
+ do_sparks(2, FALSE, target.loc)
+ if(prob(25))
+ new /obj/effect/decal/cleanable/oil(target_loca)
+ else if(isalien(L))
new /obj/effect/temp_visual/dir_setting/bloodsplatter/xenosplatter(target_loca, splatter_dir)
else
- new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color(H.dna.blood_type))
+ else
+ new /obj/effect/temp_visual/dir_setting/bloodsplatter(target_loca, splatter_dir, bloodtype_to_color())
+
if(iscarbon(L))
var/mob/living/carbon/C = L
C.bleed(damage)
else
L.add_splatter_floor(target_loca)
+
else if(impact_effect_type && !hitscan)
new impact_effect_type(target_loca, hitx, hity)
@@ -202,7 +218,7 @@
else
L.log_message("has been shot by [firer] with [src]", LOG_ATTACK, color="orange")
- return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter)
+ return L.apply_effects(stun, knockdown, unconscious, irradiate, slur, stutter, eyeblur, drowsy, blocked, stamina, jitter, knockdown_stamoverride, knockdown_stam_max)
/obj/item/projectile/proc/vol_by_damage()
if(src.damage)
@@ -219,8 +235,8 @@
beam_segments[beam_index] = null
/obj/item/projectile/Bump(atom/A)
- var/datum/point/pcache = trajectory.copy_to()
- if(check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
+ if(trajectory && check_ricochet(A) && check_ricochet_flag(A) && ricochets < ricochets_max)
+ var/datum/point/pcache = trajectory.copy_to()
ricochets++
if(A.handle_ricochet(src))
on_ricochet(A)
@@ -343,6 +359,8 @@
pixel_move(1, FALSE)
/obj/item/projectile/proc/fire(angle, atom/direct_target)
+ if(fired_from)
+ SEND_SIGNAL(fired_from, COMSIG_PROJECTILE_BEFORE_FIRE, src, original)
//If no angle needs to resolve it from xo/yo!
if(!log_override && firer && original)
log_combat(firer, original, "fired at", src, "from [get_area_name(src, TRUE)]")
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index d8154b367d..e43eb5a3bc 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -39,14 +39,6 @@
/obj/item/projectile/beam/weak
damage = 15
-/obj/item/projectile/beam/weak/minigun
- damage = 12.5
- armour_penetration = 40
-
-/obj/item/projectile/beam/weak/minigun/Initialize()
- .=..()
- speed = pick(0.7,0.75,0.8,0.85,0.9,0.95,1,1.05,1.1,1.15)
-
/obj/item/projectile/beam/weak/penetrator
armour_penetration = 50
diff --git a/code/modules/projectiles/projectile/bullets/smg.dm b/code/modules/projectiles/projectile/bullets/smg.dm
index dfc6df537d..94ec2d3c2b 100644
--- a/code/modules/projectiles/projectile/bullets/smg.dm
+++ b/code/modules/projectiles/projectile/bullets/smg.dm
@@ -1,60 +1,69 @@
-// .45 (M1911 & C20r)
-
-/obj/item/projectile/bullet/c45
- name = ".45 bullet"
- damage = 20
- stamina = 65
-
-/obj/item/projectile/bullet/c45_nostamina
- name = ".45 bullet"
- damage = 30
-
-/obj/item/projectile/bullet/c45_cleaning
- name = ".45 bullet"
- damage = 24
- stamina = 10
-
-/obj/item/projectile/bullet/c45_cleaning/on_hit(atom/target, blocked = FALSE)
- . = ..()
- var/turf/T = get_turf(target)
-
- //section shamelessly copypasta'd from the clean component
- SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- for(var/A in T)
- if(is_cleanable(A))
- qdel(A)
- else if(istype(A, /obj/item))
- var/obj/item/I = A
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(ismob(I.loc))
- var/mob/M = I.loc
- M.regenerate_icons()
- else if(ishuman(A))
- var/mob/living/carbon/human/cleaned_human = A
- if(cleaned_human.head)
- SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(cleaned_human.wear_suit)
- SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- else if(cleaned_human.w_uniform)
- SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- if(cleaned_human.shoes)
- SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
- cleaned_human.wash_cream()
- cleaned_human.regenerate_icons()
-
-// 4.6x30mm (Autorifles)
-
-/obj/item/projectile/bullet/c46x30mm
- name = "4.6x30mm bullet"
- damage = 20
-
-/obj/item/projectile/bullet/c46x30mm_ap
- name = "4.6x30mm armor-piercing bullet"
- damage = 15
- armour_penetration = 40
-
-/obj/item/projectile/bullet/incendiary/c46x30mm
- name = "4.6x30mm incendiary bullet"
- damage = 10
- fire_stacks = 1
+// .45 (M1911 & C20r)
+
+/obj/item/projectile/bullet/c45
+ name = ".45 bullet"
+ damage = 20
+ stamina = 65
+
+/obj/item/projectile/bullet/c45_nostamina
+ name = ".45 bullet"
+ damage = 30
+
+/obj/item/projectile/bullet/c45_cleaning
+ name = ".45 bullet"
+ damage = 24
+ stamina = 10
+
+/obj/item/projectile/bullet/c45_cleaning/on_hit(atom/target, blocked = FALSE)
+ . = ..()
+ var/turf/T = get_turf(target)
+ SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ for(var/A in T)
+ if(is_cleanable(A))
+ qdel(A)
+ else if(isitem(A))
+ var/obj/item/cleaned_item = A
+ SEND_SIGNAL(cleaned_item, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_item.clean_blood()
+ if(ismob(cleaned_item.loc))
+ var/mob/M = cleaned_item.loc
+ M.regenerate_icons()
+ else if(ishuman(A))
+ var/mob/living/carbon/human/cleaned_human = A
+ if(cleaned_human.lying)
+ if(cleaned_human.head)
+ SEND_SIGNAL(cleaned_human.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.head.clean_blood()
+ cleaned_human.update_inv_head()
+ if(cleaned_human.wear_suit)
+ SEND_SIGNAL(cleaned_human.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.wear_suit.clean_blood()
+ cleaned_human.update_inv_wear_suit()
+ else if(cleaned_human.w_uniform)
+ SEND_SIGNAL(cleaned_human.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.w_uniform.clean_blood()
+ cleaned_human.update_inv_w_uniform()
+ if(cleaned_human.shoes)
+ SEND_SIGNAL(cleaned_human.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.shoes.clean_blood()
+ cleaned_human.update_inv_shoes()
+ SEND_SIGNAL(cleaned_human, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ cleaned_human.clean_blood()
+ cleaned_human.wash_cream()
+ cleaned_human.regenerate_icons()
+
+// 4.6x30mm (Autorifles)
+
+/obj/item/projectile/bullet/c46x30mm
+ name = "4.6x30mm bullet"
+ damage = 15
+
+/obj/item/projectile/bullet/c46x30mm_ap
+ name = "4.6x30mm armor-piercing bullet"
+ damage = 12.5
+ armour_penetration = 40
+
+/obj/item/projectile/bullet/incendiary/c46x30mm
+ name = "4.6x30mm incendiary bullet"
+ damage = 7.5
+ fire_stacks = 1
diff --git a/code/modules/projectiles/projectile/energy/nuclear_particle.dm b/code/modules/projectiles/projectile/energy/nuclear_particle.dm
index 1753587ad3..e08f806fe5 100644
--- a/code/modules/projectiles/projectile/energy/nuclear_particle.dm
+++ b/code/modules/projectiles/projectile/energy/nuclear_particle.dm
@@ -3,10 +3,9 @@
name = "nuclear particle"
icon_state = "nuclear_particle"
pass_flags = PASSTABLE | PASSGLASS | PASSGRILLE
- damage = 20
- damage_type = TOX
- irradiate = 2500 //enough to knockdown and induce vomiting
- speed = 0.4
+ flag = "rad"
+ irradiate = 5000
+ speed = 0.4
hitsound = 'sound/weapons/emitter2.ogg'
impact_type = /obj/effect/projectile/impact/xray
var/static/list/particle_colors = list(
@@ -25,22 +24,6 @@
add_atom_colour(particle_colors[our_color], FIXED_COLOUR_PRIORITY)
set_light(4, 3, particle_colors[our_color]) //Range of 4, brightness of 3 - Same range as a flashlight
-/atom/proc/fire_nuclear_particles(power_ratio) //used by fusion to fire random # of nuclear particles - power ratio determines about how many are fired
- var/random_particles = rand(3,6)
- var/particles_to_fire
- var/particles_fired
- switch(power_ratio) //multiply random_particles * factor for whatever tier
- if(0 to FUSION_MID_TIER_THRESHOLD)
- particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_LOW
- if(FUSION_MID_TIER_THRESHOLD to FUSION_HIGH_TIER_THRESHOLD)
- particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_MID
- if(FUSION_HIGH_TIER_THRESHOLD to FUSION_SUPER_TIER_THRESHOLD)
- particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_HIGH
- if(FUSION_SUPER_TIER_THRESHOLD to INFINITY)
- particles_to_fire = random_particles * FUSION_PARTICLE_FACTOR_SUPER
- while(particles_to_fire)
- particles_fired++
- var/angle = rand(0,360)
- var/obj/item/projectile/energy/nuclear_particle/P = new /obj/item/projectile/energy/nuclear_particle(src)
- addtimer(CALLBACK(P, /obj/item/projectile.proc/fire, angle), particles_fired) //multiply particles fired * delay so the particles end up stagnated (once every decisecond)
- particles_to_fire--
\ No newline at end of file
+/atom/proc/fire_nuclear_particle(angle = rand(0,360)) //used by fusion to fire random nuclear particles. Fires one particle in a random direction.
+ var/obj/item/projectile/energy/nuclear_particle/P = new /obj/item/projectile/energy/nuclear_particle(src)
+ P.fire(angle)
diff --git a/code/modules/projectiles/projectile/energy/stun.dm b/code/modules/projectiles/projectile/energy/stun.dm
index 895a165f49..d7c8b8b082 100644
--- a/code/modules/projectiles/projectile/energy/stun.dm
+++ b/code/modules/projectiles/projectile/energy/stun.dm
@@ -3,7 +3,9 @@
icon_state = "spark"
color = "#FFFF00"
nodamage = 1
- knockdown = 100
+ knockdown = 60
+ knockdown_stamoverride = 36
+ knockdown_stam_max = 50
stutter = 5
jitter = 20
hitsound = 'sound/weapons/taserhit.ogg'
@@ -11,6 +13,7 @@
tracer_type = /obj/effect/projectile/tracer/stun
muzzle_type = /obj/effect/projectile/muzzle/stun
impact_type = /obj/effect/projectile/impact/stun
+ var/tase_duration = 50
/obj/item/projectile/energy/electrode/on_hit(atom/target, blocked = FALSE)
. = ..()
@@ -23,6 +26,7 @@
if(C.dna && C.dna.check_mutation(HULK))
C.say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ), forced = "hulk")
else if((C.status_flags & CANKNOCKDOWN) && !HAS_TRAIT(C, TRAIT_STUNIMMUNE))
+ C.apply_status_effect(STATUS_EFFECT_TASED, tase_duration)
addtimer(CALLBACK(C, /mob/living/carbon.proc/do_jitter_animation, jitter), 5)
/obj/item/projectile/energy/electrode/on_range() //to ensure the bolt sparks when it reaches the end of its range if it didn't hit a target yet
diff --git a/code/modules/projectiles/projectile/special/mindflayer.dm b/code/modules/projectiles/projectile/special/mindflayer.dm
index d717bed39e..ac4488cae0 100644
--- a/code/modules/projectiles/projectile/special/mindflayer.dm
+++ b/code/modules/projectiles/projectile/special/mindflayer.dm
@@ -5,5 +5,5 @@
. = ..()
if(ishuman(target))
var/mob/living/carbon/human/M = target
- M.adjustBrainLoss(20)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
M.hallucination += 30
diff --git a/code/modules/projectiles/projectile/special/neurotoxin.dm b/code/modules/projectiles/projectile/special/neurotoxin.dm
index baf1495abb..1d359585c0 100644
--- a/code/modules/projectiles/projectile/special/neurotoxin.dm
+++ b/code/modules/projectiles/projectile/special/neurotoxin.dm
@@ -8,7 +8,7 @@
if(isalien(target))
knockdown = 0
nodamage = TRUE
- else if(isliving(target))
+ else if(iscarbon(target))
var/mob/living/L = target
L.Knockdown(100, TRUE, FALSE, 30, 25)
return ..()
diff --git a/code/modules/reagents/chem_wiki_render.dm b/code/modules/reagents/chem_wiki_render.dm
new file mode 100644
index 0000000000..efb6bdecfd
--- /dev/null
+++ b/code/modules/reagents/chem_wiki_render.dm
@@ -0,0 +1,387 @@
+//Generates a markdown txt file for use with the wiki
+
+/proc/find_reagent(input)
+ . = FALSE
+ if(GLOB.chemical_reagents_list[input]) //prefer IDs!
+ var/datum/reagent/R = GLOB.chemical_reagents_list[input]
+ return R
+ else
+ for(var/X in GLOB.chemical_reagents_list)
+ var/datum/reagent/R = GLOB.chemical_reagents_list[X]
+ if(input == replacetext(lowertext(R.name), " ", ""))
+ return R
+ if(input == replacetext(lowertext(R.id), " ", ""))
+ return R
+
+
+
+
+/client/proc/generate_wikichem_list()
+ set name = "Generate Wikichems"
+ set category = "Debug"
+ set desc = "Generate a huge loglist of all the chems. Do not click unless you want lag."
+
+
+
+ var/prefix = "|Name | Reagents | Reaction vars | Description | Chem properties |\n|---|---|---|-----------|---|\n"
+ var/input_reagent = replacetext(lowertext(input("Input the name/id of a reagent to get it's description on it's own, or leave blank to parse every chem.", "Input") as text), " ", "") //95% of the time, the reagent id is a lowercase/no spaces version of the name
+ if(input_reagent)
+ var/input_reagent2 = find_reagent(input_reagent)
+ if(!input_reagent2)
+ to_chat(usr, "Unable to find reagent, stopping proc.")
+ var/single_parse = generate_chemwiki_line(input_reagent2, input_reagent, FALSE)
+ text2file(single_parse, "[GLOB.log_directory]/chem_parse.md")
+ to_chat(usr, "[single_parse].")
+
+ single_parse = generate_chemwiki_line(input_reagent2, input_reagent, FALSE)
+ text2file(single_parse, "[GLOB.log_directory]/chem_parse.md")
+ to_chat(usr, "[single_parse].")
+ to_chat(usr, "Saved line to (wherever your root folder is, i.e. where the DME is)/[GLOB.log_directory]/chem_parse.md OR use the Get Current Logs verb under the Admin tab. (if you click Open, and it does nothing, that's because you've not set a .md default program! Try downloading it instead, and use that file to set a default program! Also have a cute day.)")
+ //Do things here
+ return
+ to_chat(usr, "Generating big list")
+ message_admins("Someone pressed the lag button. (Generate Wikichems)")
+ ///datum/reagent/medicine, /datum/reagent/toxin, /datum/reagent/consumable, /datum/reagent/plantnutriment, /datum/reagent/uranium,
+ ///datum/reagent/colorful_reagent, /datum/reagent/mutationtoxin, /datum/reagent/fermi, /datum/reagent/drug, /datum/reagent/impure
+
+ //Probably not the most eligant of solutions.
+ to_chat(usr, "Attempting reagent scan. Length of list [LAZYLEN(GLOB.chemical_reagents_list)*2]")
+ var/datum/reagent/R
+ var/tally = 0
+ var/processCR = TRUE //Process reactions first
+ var/medicine = ""
+ var/toxin = ""
+ var/consumable = ""
+ var/plant = ""
+ var/uranium = ""
+ var/colours = ""
+ var/muta = ""
+ var/fermi = ""
+ var/remainder = ""
+ var/drug = ""
+ var/basic = ""
+ var/upgraded = ""
+ var/drinks = ""
+ var/alco = ""
+ var/grinded = ""
+ var/blob = ""
+ var/impure = ""
+
+ //Chem_dispencer
+ var/list/dispensable_reagents = list(
+ "hydrogen",
+ "lithium",
+ "carbon",
+ "nitrogen",
+ "oxygen",
+ "fluorine",
+ "sodium",
+ "aluminium",
+ "silicon",
+ "phosphorus",
+ "sulfur",
+ "chlorine",
+ "potassium",
+ "iron",
+ "copper",
+ "mercury",
+ "radium",
+ "water",
+ "ethanol",
+ "sugar",
+ "sacid",
+ "welding_fuel",
+ "silver",
+ "iodine",
+ "bromine",
+ "stable_plasma"
+ )
+ var/list/components = list(
+ "oil",
+ "ammonia",
+ "ash",
+ "acetone",
+ "phenol",
+ "diethylamine",
+ "saltpetre",
+ "sodiumchloride",
+ "lye"
+ )
+
+ var/list/grind = list(
+ "bluespace",
+ "gold",
+ "plasma",
+ "uranium"
+ )
+
+ //Bartender
+ var/dispence_drinks = list(
+ "water",
+ "ice",
+ "coffee",
+ "cream",
+ "tea",
+ "icetea",
+ "cola",
+ "spacemountainwind",
+ "dr_gibb",
+ "space_up",
+ "tonic",
+ "sodawater",
+ "lemon_lime",
+ "pwr_game",
+ "shamblers",
+ "sugar",
+ "orangejuice",
+ "grenadine",
+ "limejuice",
+ "tomatojuice",
+ "lemonjuice",
+ "menthol"
+ )
+ var/dispence_alco = list(
+ "beer",
+ "kahlua",
+ "whiskey",
+ "wine",
+ "vodka",
+ "gin",
+ "rum",
+ "tequila",
+ "vermouth",
+ "cognac",
+ "ale",
+ "absinthe",
+ "hcider",
+ "creme_de_menthe",
+ "creme_de_cacao",
+ "triple_sec",
+ "sake",
+ "applejack"
+ )
+
+ var/breakout = FALSE
+ for(var/i = 1, i <= 2, i+=1)
+ for(var/X in GLOB.chemical_reagents_list)
+ R = GLOB.chemical_reagents_list[X]
+ if(!R.description) //No description? It's not worth my time.
+ continue
+
+ for(var/Y in dispensable_reagents) //Why do you have to do this
+ if(R.id == Y)
+ basic += generate_chemwiki_line(R, X, processCR)
+ breakout = TRUE
+ continue
+
+ for(var/Y in components)
+ if(R.id == Y)
+ upgraded += generate_chemwiki_line(R, X, processCR)
+ breakout = TRUE
+ continue
+
+ for(var/Y in dispence_drinks)
+ if(R.id == Y)
+ drinks += generate_chemwiki_line(R, X, processCR)
+ breakout = TRUE
+ continue
+
+ for(var/Y in dispence_alco)
+ if(R.id == Y)
+ alco += generate_chemwiki_line(R, X, processCR)
+ breakout = TRUE
+ continue
+
+ for(var/Y in grind)
+ if(R.id == Y)
+ grinded += generate_chemwiki_line(R, X, processCR)
+ breakout = TRUE
+ continue
+
+ if(breakout)
+ breakout = FALSE
+ continue
+
+ if(istype(R, /datum/reagent/medicine))
+ medicine += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/toxin))
+ toxin += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/consumable))
+ consumable += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/plantnutriment))
+ plant += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/uranium))
+ uranium += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/colorful_reagent))
+ colours += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/mutationtoxin))
+ muta += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/fermi))
+ fermi += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/drug))
+ drug += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/blob))
+ blob += generate_chemwiki_line(R, X, processCR)
+
+ else if(istype(R, /datum/reagent/impure))
+ impure += generate_chemwiki_line(R, X, processCR)
+
+ else
+ remainder += generate_chemwiki_line(R, X, processCR)
+
+ tally++
+ if((tally%50)==0)
+ to_chat(usr, "[tally] of [LAZYLEN(GLOB.chemical_reagents_list)*2] done.")
+
+ processCR = FALSE
+
+ to_chat(usr, "finished chems")
+
+ var/wholeString = ("\n# DISPENCEABLE REAGENTS\n\n[prefix][basic]\n\n# COMPONENT REAGENTS\n\n[prefix][upgraded]\n\n# GROUND REAGENTS\n\n[prefix][grinded]\n")
+ wholeString += ("\n# MEDICINE:\n\n[prefix][medicine]\n\n# TOXIN:\n\n[prefix][toxin]\n\n# DRUGS\n\n[prefix][drug]\n\n# FERMI\n\nThese chems lie on the cutting edge of chemical technology, and as such are not recommended for beginners!\n\n[prefix][fermi]\n\n# IMPURE REAGENTS\n\n[prefix][impure]\n\n# GENERAL REAGENTS\n\n[prefix][remainder]\n\n# DISPENCEABLE SOFT DRINKS\n\n[prefix][drinks]\n\n# DISPENCEABLE HARD DRINKS\n\n[prefix][alco]\n\n# CONSUMABLE\n\n[prefix][consumable]\n\n# PLANTS\n\n[prefix][plant]\n\n# URANIUM\n\n[prefix][uranium]\n\n# COLOURS\n\n[prefix][colours]\n\n# RACE MUTATIONS\n\n[prefix][muta]\n\n\n# BLOB REAGENTS\n\n[prefix][blob]\n")
+
+ prefix = "|Name | Reagents | Reaction vars | Description |\n|---|---|---|----------|\n"
+ var/CRparse = ""
+ to_chat(usr, "starting reactions")
+
+ //generate the reactions that we missed from before
+ for(var/reagent in GLOB.chemical_reactions_list)
+ for(var/datum/chemical_reaction/CR in GLOB.chemical_reactions_list[reagent])
+ CRparse += generate_chemreactwiki_line(CR)
+
+ wholeString += ("\n# CHEMICAL REACTIONS\n\n[prefix][CRparse]\n")
+ text2file(wholeString, "[GLOB.log_directory]/chem_parse.md")
+ to_chat(usr, "finished reactions")
+ to_chat(usr, "Saved file to (wherever your root folder is, i.e. where the DME is)/[GLOB.log_directory]/chem_parse.md OR use the Get Current Logs verb under the Admin tab. (if you click Open, and it does nothing, that's because you've not set a .md default program! Try downloading it instead, and use that file to set a default program! Also have a cute day.)")
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+//Generate the big list of reagent based reactions.
+/proc/generate_chemwiki_line(datum/reagent/R, X, processCR)
+ //name | Reagent pH | reagents | reaction temp | explosion temp | pH range | Kinetics | description | OD level | Addiction level | Metabolism rate | impure chem | inverse chem
+
+ var/datum/chemical_reaction/CR = get_chemical_reaction(R.id)
+ if((!CR && processCR) || (CR && !processCR)) // Do reactions first.
+ return ""
+
+
+ var/outstring = "|!\[[R.color]\](https://placehold.it/15/[copytext(R.color, 2, 8)]/000000?text=+)[R.name] pH: [R.pH] | "
+ var/datum/reagent/R3
+ if(CR)
+ outstring += ""
+ for(var/R2 in CR.required_reagents)
+ R3 = GLOB.chemical_reagents_list[R2]//What a convoluted mess
+ outstring += "[R3.name] : [CR.required_reagents[R3.id]]u "
+ if(CR.required_catalysts)
+ for(var/R2 in CR.required_catalysts)
+ R3 = GLOB.chemical_reagents_list[R2]
+ outstring += "Catalyst: [R3.name] : [CR.required_catalysts[R3.id]]u "
+ outstring += " | "
+ else
+ outstring += "N/A | "
+
+
+ //Temp, Explosions and pH
+ if(CR)
+ outstring += "[(CR.FermiChem?"Min react temp: [CR.OptimalTempMin]K ":"[(CR.required_temp?"Min react temp: [CR.required_temp]K ":"")]")] [(CR.FermiChem?"Explosion_temp: [CR.ExplodeTemp]K ":"")] [(CR.FermiChem?"pH range: [max((CR.OptimalpHMin - CR.ReactpHLim), 0)] to [min((CR.OptimalpHMax + CR.ReactpHLim), 14)] ":"")] "
+ if(CR.FermiChem)
+ outstring += "[(CR.PurityMin?"Min explosive purity: [CR.PurityMin] ":"")] [(CR.FermiExplode?"Special explosion: Yes ":"")]"
+ else
+ outstring += ""
+
+ //Kinetics
+ if(CR)
+ if(CR.FermiChem)
+ switch(CR.ThermicConstant)
+ if(-INFINITY to -9.9)
+ outstring += "Extremely endothermic "
+ if(-9.9 to -4.9)
+ outstring += "Very endothermic "
+ if(-4.9 to -0.1)
+ outstring += "Endothermic "
+ if(-0.1 to 0.1)
+ outstring += "Neutral "
+ if(0.1 to 4.9)
+ outstring += "Exothermic "
+ if(4.9 to 9.9)
+ outstring += "Very exothermic "
+ if(9.9 to 19.9)
+ outstring += "Extremely exothermic "
+ if(19.9 to INFINITY )
+ outstring += "**Dangerously exothermic** "
+ //if("cheesey")
+ //outstring += "Dangerously Cheesey "
+
+ outstring += " | "
+ else
+ outstring += " | "
+
+ //Description, OD, Addict, Meta
+ outstring += "[R.description] | Metabolism rate: [R.metabolization_rate/2]u/s [(R.overdose_threshold?"Overdose: [R.overdose_threshold]u ":"")] [(R.addiction_threshold?"Addiction: [R.addiction_threshold]u ":"")] "
+
+ if(R.impure_chem && R.impure_chem != "fermiTox")
+ R3 = GLOB.chemical_reagents_list[R.impure_chem]
+ outstring += "Impure chem:[R3.name] "
+
+ if(R.inverse_chem && R.impure_chem != "fermiTox")
+ R3 = GLOB.chemical_reagents_list[R.inverse_chem]
+ outstring += "Inverse chem:[R3.name] [(R3.inverse_chem_val?"Inverse purity: [R3.inverse_chem_val] ":"")] "
+
+ if(CR)
+ if(CR.required_container)
+ /*var/obj/item/I
+ I = istype(I, CR.required_container) if you can work out how to get this to work, by all means.
+ outstring += "Required container: [I.name] "*/
+ outstring += "Required container: [CR.required_container] "
+
+ outstring += " |\n"
+ return outstring
+
+//Generate the big list of reaction based reactions.
+//|Name | Reagents | Reaction vars | Description | Chem properties
+/proc/generate_chemreactwiki_line(datum/chemical_reaction/CR)
+ if(CR.results.len) //Handled prior
+ return
+ var/outstring = "|[CR.name] | "
+
+ //reagents
+ var/datum/reagent/R3
+ for(var/R2 in CR.required_reagents)
+ R3 = GLOB.chemical_reagents_list[R2]
+ outstring += "[R3.name] : [CR.required_reagents[R3.id]]u "
+ if(CR.required_catalysts)
+ for(var/R2 in CR.required_catalysts)
+ R3 = GLOB.chemical_reagents_list[R2]
+ outstring += "Catalyst: [R3.name] : [CR.required_catalysts[R3.id]]u "
+ outstring += " | "
+
+ //Reaction vars
+ if(CR.required_temp)
+ outstring += "Min react temp: [CR.required_temp]K "
+ if(CR.FermiChem)
+ outstring += "[(CR.FermiChem?"Min react temp: [CR.OptimalTempMin]K ":"[(CR.required_temp?"Min react temp: [CR.required_temp]K ":"")]")] [(CR.FermiChem?"Explosion temp: [CR.ExplodeTemp]K ":"")] [(CR.FermiChem?"pH range: [max((CR.OptimalpHMin - CR.ReactpHLim), 0)] to [min((CR.OptimalpHMax + CR.ReactpHLim), 14)] ":"")] Minimum purity: [CR.PurityMin] [(CR.FermiExplode?" Special explosion: Yes ":"")]"
+ if(CR.is_cold_recipe)
+ outstring += "Cold: Yes "
+ if(CR.required_container)
+ outstring += "Required container: [CR.required_container] "
+ if(CR.mob_react)
+ outstring += "Can react in mob: Yes "
+
+ //description
+ outstring += " | fill in manually "
+
+ outstring += "|\n"
+ return outstring
diff --git a/code/modules/reagents/chemistry/fermi/readme.md b/code/modules/reagents/chemistry/fermi/readme.md
new file mode 100644
index 0000000000..4b897b6c4b
--- /dev/null
+++ b/code/modules/reagents/chemistry/fermi/readme.md
@@ -0,0 +1,23 @@
+How to code fermichem reactions:
+First off, probably read though the readme for standard reagent mechanisms, this builds on top of that.
+
+#bitflags
+for `datum/reagent/` you have the following options with `var/chemical_flags`:
+
+```
+REAGENT_DEAD_PROCESS calls on_mob_dead() if present in a dead body
+REAGENT_DONOTSPLIT Do not split the chem at all during processing
+REAGENT_ONLYINVERSE Only invert chem, no splitting
+REAGENT_ONMOBMERGE Call on_mob_life proc when reagents are merging.
+REAGENT_INVISIBLE Doesn't appear on handheld health analyzers.
+REAGENT_FORCEONNEW Forces a on_new() call without a data overhead
+REAGENT_SNEAKYNAME When inverted, the inverted chem uses the name of the original chem
+REAGENT_SPLITRETAINVOL Retains initial volume of chem when splitting
+```
+
+for `datum/chemical_reaction/` under `var/clear_conversion`
+
+```
+REACTION_CLEAR_IMPURE Convert into impure/pure on reaction completion
+REACTION_CLEAR_INVERSE Convert into inverse on reaction completion when purity is low enough
+```
diff --git a/code/modules/reagents/chemistry/holder.dm b/code/modules/reagents/chemistry/holder.dm
index ce7819ed7a..fb064b6146 100644
--- a/code/modules/reagents/chemistry/holder.dm
+++ b/code/modules/reagents/chemistry/holder.dm
@@ -63,7 +63,7 @@
var/targetVol = 0 //the target volume, i.e. the total amount that can be created during a fermichem reaction.
var/reactedVol = 0 //how much of the reagent is reacted during a fermireaction
var/fermiIsReacting = FALSE //that prevents multiple reactions from occurring (i.e. add_reagent calls to process_reactions(), this stops any extra reactions.)
- var/fermiReactID = null //ID of the chem being made during a fermireaction, kept here so it's cache isn't lost between loops/procs.
+ var/fermiReactID //ID of the chem being made during a fermireaction, kept here so it's cache isn't lost between loops/procs.
/datum/reagents/New(maximum=100, new_flags)
maximum_volume = maximum
@@ -128,14 +128,12 @@
/datum/reagents/proc/remove_all(amount = 1)
var/list/cached_reagents = reagent_list
- if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash.
- pH = 7
if(total_volume > 0)
var/part = amount / total_volume
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
remove_reagent(R.id, R.volume * part, ignore_pH = TRUE)
-
+ pH = REAGENT_NORMAL_PH
update_total()
handle_reactions()
return amount
@@ -365,7 +363,7 @@
/datum/reagents/proc/handle_reactions()//HERE EDIT HERE THE MAIN REACTION
- if(fermiIsReacting == TRUE)
+ if(fermiIsReacting) //This ARRESTS other reactions. If you don't want this, then remove it.
return
if(reagents_holder_flags & NO_REACT)
@@ -404,7 +402,7 @@
for(var/B in cached_required_reagents)
- if(!has_reagent(B, cached_required_reagents[B]))
+ if(!has_reagent(B, cached_required_reagents[B]))//Allows vols at less than 1 to react.
break
total_matching_reagents++
for(var/B in cached_required_catalysts)
@@ -464,39 +462,36 @@
//Temperature plays into a larger role too.
var/datum/chemical_reaction/C = selected_reaction
- if (C.FermiChem == TRUE && !continue_reacting)
+ if (C.FermiChem && !continue_reacting)
if (chem_temp > C.ExplodeTemp) //This is first to ensure explosions.
- var/datum/chemical_reaction/fermi/Ferm = selected_reaction
+ var/datum/chemical_reaction/Ferm = selected_reaction
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[Ferm] explosion"))
Ferm.FermiExplode(src, my_atom, volume = total_volume, temp = chem_temp, pH = pH)
return 0
+ //This is just to calc the on_reaction multiplier, and is a candidate for removal.
for(var/B in cached_required_reagents)
- multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), CHEMICAL_QUANTISATION_LEVEL))
+ multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.0001))
for(var/P in selected_reaction.results)
targetVol = cached_results[P]*multiplier
- if( (chem_temp <= C.ExplodeTemp) && (chem_temp >= C.OptimalTempMin))
- if( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )//To prevent pointless reactions
-
- if (fermiIsReacting == TRUE)
- return 0
- else
- START_PROCESSING(SSprocessing, src)
- selected_reaction.on_reaction(src, my_atom, multiplier)
- fermiIsReacting = TRUE
- fermiReactID = selected_reaction
- reaction_occurred = 1
-
- else //It's a little bit of a confusing nest, but esstentially we check if it's a fermireaction, then temperature, then pH. If this is true, the remainer of this handler is run.
- return 0 //If pH is out of range
+ if(!((chem_temp <= C.ExplodeTemp) && (chem_temp >= C.OptimalTempMin)))
+ return 0 //Not hot enough
+ if(! ((pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) ))//To prevent pointless reactions
+ return 0
+ if (fermiIsReacting)
+ return 0
else
- return 0 //If not hot enough
+ START_PROCESSING(SSprocessing, src)
+ selected_reaction.on_reaction(src, my_atom, multiplier)
+ fermiIsReacting = TRUE
+ fermiReactID = selected_reaction
+ reaction_occurred = 1
//Standard reaction mechanics:
else
- if (C.FermiChem == TRUE)//Just to make sure, should only proc when grenades are combining.
+ if (C.FermiChem)//Just to make sure, should only proc when grenades are combining.
if (chem_temp > C.ExplodeTemp) //To allow fermigrenades
var/datum/chemical_reaction/fermi/Ferm = selected_reaction
fermiIsReacting = FALSE
@@ -507,6 +502,7 @@
for(var/B in cached_required_reagents) //
multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), CHEMICAL_QUANTISATION_LEVEL))
+
for(var/B in cached_required_reagents)
remove_reagent(B, (multiplier * cached_required_reagents[B]), safety = 1, ignore_pH = TRUE)
@@ -544,59 +540,67 @@
return 0
/datum/reagents/process()
- var/datum/chemical_reaction/fermi/C = fermiReactID
+ var/datum/chemical_reaction/C = fermiReactID
var/list/cached_required_reagents = C.required_reagents//update reagents list
var/list/cached_results = C.results//resultant chemical list
var/multiplier = INFINITY
-
for(var/B in cached_required_reagents) //
- multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.001))
- if (multiplier == 0)
+ multiplier = min(multiplier, round((get_reagent_amount(B) / cached_required_reagents[B]), 0.0001))
+ if (multiplier <= 0)//clarity
fermiEnd()
return
- for(var/P in cached_results)
- targetVol = cached_results[P]*multiplier
- if (fermiIsReacting == FALSE)
- CRASH("Fermi has refused to stop reacting even though we asked her nicely.")
-
- if (chem_temp > C.OptimalTempMin && fermiIsReacting == TRUE)//To prevent pointless reactions
- if( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )
- if (reactedVol < targetVol)
- reactedVol = fermiReact(fermiReactID, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
- else//Volume is used up
+ if(C.required_catalysts)
+ for(var/P in C.required_catalysts)
+ if(!has_reagent(P))
fermiEnd()
return
- else//pH is out of range
- fermiEnd()
- return
- else//Temperature is too low, or reaction has stopped.
+
+ if (!fermiIsReacting)
+ CRASH("Fermi has refused to stop reacting even though we asked her nicely.")
+
+ if (!(chem_temp >= C.OptimalTempMin))//To prevent pointless reactions
fermiEnd()
return
+ if (!( (pH >= (C.OptimalpHMin - C.ReactpHLim)) && (pH <= (C.OptimalpHMax + C.ReactpHLim)) )) //if pH is too far out, (could possibly allow reactions at this point, after the reaction has started, but make purity = 0)
+ fermiEnd()
+ return
+
+ reactedVol = fermiReact(fermiReactID, chem_temp, pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
+ if(round(reactedVol, CHEMICAL_QUANTISATION_LEVEL) == round(targetVol, CHEMICAL_QUANTISATION_LEVEL))
+ fermiEnd()
+ if(!reactedVol)//Maybe unnessicary.
+ fermiEnd()
+ return
+
/datum/reagents/proc/fermiEnd()
- var/datum/chemical_reaction/fermi/C = fermiReactID
+ var/datum/chemical_reaction/C = fermiReactID
STOP_PROCESSING(SSprocessing, src)
fermiIsReacting = FALSE
reactedVol = 0
targetVol = 0
+ //Cap off values
+ for(var/datum/reagent/R in reagent_list)
+ R.volume = round(R.volume, CHEMICAL_QUANTISATION_LEVEL)//To prevent runaways.
//pH check, handled at the end to reduce calls.
if(istype(my_atom, /obj/item/reagent_containers))
var/obj/item/reagent_containers/RC = my_atom
RC.pH_check()
- C.FermiFinish(src, my_atom)
+ C.FermiFinish(src, my_atom, reactedVol)
+ reactedVol = 0
+ targetVol = 0
handle_reactions()
update_total()
//Reaction sounds and words
- playsound(get_turf(my_atom), C.mix_sound, 80, 1)
var/list/seen = viewers(5, get_turf(my_atom))
var/iconhtml = icon2html(my_atom, seen)
for(var/mob/M in seen)
to_chat(M, "[iconhtml] [C.mix_message] ")
/datum/reagents/proc/fermiReact(selected_reaction, cached_temp, cached_pH, reactedVol, targetVol, cached_required_reagents, cached_results, multiplier)
- var/datum/chemical_reaction/fermi/C = selected_reaction
+ var/datum/chemical_reaction/C = selected_reaction
var/deltaT = 0
var/deltapH = 0
var/stepChemAmmount = 0
@@ -646,16 +650,18 @@
//ONLY WORKS FOR ONE PRODUCT AT THE MOMENT
//Calculate how much product to make and how much reactant to remove factors..
for(var/P in cached_results)
- //stepChemAmmount = CLAMP(((deltaT * multiplier), 0, ((targetVol - reactedVol)/cached_results[P])) //used to have multipler, now it does
stepChemAmmount = (multiplier*cached_results[P])
- if (stepChemAmmount >= C.RateUpLim)
- stepChemAmmount = (C.RateUpLim)
+ if (stepChemAmmount > C.RateUpLim)
+ stepChemAmmount = C.RateUpLim
addChemAmmount = deltaT * stepChemAmmount
if (addChemAmmount >= (targetVol - reactedVol))
addChemAmmount = (targetVol - reactedVol)
if (addChemAmmount < CHEMICAL_QUANTISATION_LEVEL)
addChemAmmount = CHEMICAL_QUANTISATION_LEVEL
removeChemAmmount = (addChemAmmount/cached_results[P])
+ //keep limited.
+ addChemAmmount = round(addChemAmmount, CHEMICAL_QUANTISATION_LEVEL)
+ removeChemAmmount = round(removeChemAmmount, CHEMICAL_QUANTISATION_LEVEL)
//This is kept for future bugtesters.
//message_admins("Reaction vars: PreReacted: [reactedVol] of [targetVol]. deltaT [deltaT], multiplier [multiplier], Step [stepChemAmmount], uncapped Step [deltaT*(multiplier*cached_results[P])], addChemAmmount [addChemAmmount], removeFactor [removeChemAmmount] Pfactor [cached_results[P]], adding [addChemAmmount]")
@@ -668,7 +674,7 @@
for(var/P in cached_results)
SSblackbox.record_feedback("tally", "chemical_reaction", addChemAmmount, P)//log
SSblackbox.record_feedback("tally", "fermi_chem", addChemAmmount, P)
- add_reagent(P, (addChemAmmount), null, cached_temp, purity)//add reagent function!! I THINK I can do this:
+ add_reagent(P, (addChemAmmount), null, cached_temp, purity)
TotalStep += addChemAmmount//for multiple products
//Above should reduce yeild based on holder purity.
//Purity Check
@@ -677,11 +683,11 @@
if (R.purity < C.PurityMin)//If purity is below the min, blow it up.
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[P] explosion"))
- C.FermiExplode(src, my_atom, (reactedVol+targetVol), cached_temp, pH)
+ C.FermiExplode(src, my_atom, (total_volume), cached_temp, pH)
STOP_PROCESSING(SSprocessing, src)
- return 0
+ return
- C.FermiCreate(src)//proc that calls when step is done
+ C.FermiCreate(src, addChemAmmount, purity)//proc that calls when step is done
//Apply pH changes and thermal output of reaction to beaker
chem_temp = round(cached_temp + (C.ThermicConstant * addChemAmmount))
@@ -694,18 +700,18 @@
//go to explode proc
fermiIsReacting = FALSE
SSblackbox.record_feedback("tally", "fermi_chem", 1, ("[C] explosions"))
- C.FermiExplode(src, my_atom, (reactedVol+targetVol), chem_temp, pH)
+ C.FermiExplode(src, my_atom, (total_volume), chem_temp, pH)
STOP_PROCESSING(SSprocessing, src)
return
- //Make sure things are limited.
+ //Make sure things are limited, but superacids/bases can push forward the reaction
pH = CLAMP(pH, 0, 14)
//return said amount to compare for next step.
return (reactedVol)
//Currently calculates it irrespective of required reagents at the start
-/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/fermi/C, holder)
+/datum/reagents/proc/reactant_purity(var/datum/chemical_reaction/C, holder)
var/list/cached_reagents = reagent_list
var/i = 0
var/cachedPurity
@@ -713,8 +719,18 @@
if (R in cached_reagents)
cachedPurity += R.purity
i++
+ if(!i)//I've never seen it get here with 0, but in case
+ CRASH("No reactants found mid reaction for [fermiReactID]/[C], how it got here is beyond me. Beaker: [holder]")
return cachedPurity/i
+/datum/reagents/proc/uncache_purity(id)
+ var/datum/reagent/R = has_reagent("[id]")
+ if(!R)
+ return
+ if(R.cached_purity == 1)
+ return
+ R.purity = R.cached_purity
+
/datum/reagents/proc/isolate_reagent(reagent)
var/list/cached_reagents = reagent_list
for(var/_reagent in cached_reagents)
@@ -746,10 +762,14 @@
total_volume = 0
for(var/reagent in cached_reagents)
var/datum/reagent/R = reagent
+ if(R.volume <= 0)//For clarity
+ del_reagent(R.id)
if((R.volume < 0.01) && !fermiIsReacting)
del_reagent(R.id)
else
total_volume += R.volume
+ if(!reagent_list || !total_volume)
+ pH = REAGENT_NORMAL_PH
return 0
/datum/reagents/proc/clear_reagents()
@@ -814,7 +834,7 @@
if(!isnum(amount) || !amount)
return FALSE
- if(amount <= CHEMICAL_QUANTISATION_LEVEL)//To prevent small ammount problems.
+ if(amount < CHEMICAL_QUANTISATION_LEVEL)//To prevent small ammount problems.
return FALSE
var/datum/reagent/D = GLOB.chemical_reagents_list[reagent]
@@ -822,7 +842,7 @@
WARNING("[my_atom] attempted to add a reagent called '[reagent]' which doesn't exist. ([usr])")
return FALSE
- if (D.id == "water" && no_react == FALSE && !istype(my_atom, /obj/item/reagent_containers/food)) //Do like an otter, add acid to water, but also don't blow up botany.
+ if (D.id == "water" && !no_react && !istype(my_atom, /obj/item/reagent_containers/food)) //Do like an otter, add acid to water, but also don't blow up botany.
if (pH <= 2)
SSblackbox.record_feedback("tally", "fermi_chem", 1, "water-acid explosions")
var/datum/effect_system/smoke_spread/chem/s = new
@@ -848,7 +868,6 @@
var/new_total = cached_total + amount
var/cached_temp = chem_temp
var/list/cached_reagents = reagent_list
-
var/cached_pH = pH
@@ -865,7 +884,7 @@
chem_temp = thermal_energy / (specific_heat * new_total)
//cacluate reagent based pH shift.
- if(ignore_pH == TRUE)
+ if(ignore_pH)
pH = ((cached_pH * cached_total)+(other_pH * amount))/(cached_total + amount)//should be right
else
pH = ((cached_pH * cached_total)+(D.pH * amount))/(cached_total + amount)//should be right
@@ -885,10 +904,8 @@
if(my_atom)
my_atom.on_reagent_change(ADD_REAGENT)
if(isliving(my_atom))
- if(R.OnMobMergeCheck == TRUE)//Forces on_mob_add proc when a chem is merged
+ if(R.chemical_flags & REAGENT_ONMOBMERGE)//Forces on_mob_add proc when a chem is merged
R.on_mob_add(my_atom, amount)
- //else
- // R.on_merge(data, amount, my_atom, other_purity)
R.on_merge(data, amount, my_atom, other_purity)
if(!no_react)
handle_reactions()
@@ -906,7 +923,7 @@
if(data)
R.data = data
R.on_new(data)
- if(R.addProc == TRUE)//Allows on new without data overhead.
+ if(R.chemical_flags & REAGENT_FORCEONNEW)//Allows on new without data overhead.
R.on_new(pH) //Add more as desired.
@@ -944,9 +961,9 @@
var/datum/reagent/R = A
if (R.id == reagent)
if((total_volume - amount) <= 0)//Because this can result in 0, I don't want it to crash.
- pH = 7
+ pH = REAGENT_NORMAL_PH
//In practice this is really confusing and players feel like it randomly melts their beakers, but I'm not sure how else to handle it. We'll see how it goes and I can remove this if it confuses people.
- else if (ignore_pH == FALSE)
+ else if (!ignore_pH)
//if (((pH > R.pH) && (pH <= 7)) || ((pH < R.pH) && (pH >= 7)))
pH = (((pH - R.pH) / total_volume) * amount) + pH
if(istype(my_atom, /obj/item/reagent_containers/))
diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
index 9a228b28e3..b5bfa06786 100644
--- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm
@@ -157,8 +157,8 @@
if(beaker)
beaker.ex_act(severity, target)
-/obj/machinery/chem_dispenser/handle_atom_del(atom/A)
- ..()
+/obj/machinery/chem_dispenser/Exited(atom/movable/A, atom/newloc)
+ . = ..()
if(A == beaker)
beaker = null
cut_overlays()
@@ -252,7 +252,7 @@
if(!is_operational())
return
var/amount = text2num(params["amount"])
- if(beaker && amount in beaker.possible_transfer_amounts)
+ if(beaker && (amount in beaker.possible_transfer_amounts))
beaker.reagents.remove_all(amount)
work_animation()
. = TRUE
diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm
index 85cf5e5011..f540ae850d 100644
--- a/code/modules/reagents/chemistry/machinery/chem_master.dm
+++ b/code/modules/reagents/chemistry/machinery/chem_master.dm
@@ -175,7 +175,7 @@
data["chosenPillStyle"] = chosenPillStyle
data["isPillBottleLoaded"] = bottle ? 1 : 0
if(bottle)
- GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
+ var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
data["pillBotContent"] = bottle.contents.len
data["pillBotMaxContent"] = STRB.max_items
@@ -263,7 +263,7 @@
var/target_loc = bottle ? bottle : drop_location()
var/drop_threshold = INFINITY
if(bottle)
- GET_COMPONENT_FROM(STRB, /datum/component/storage, bottle)
+ var/datum/component/storage/STRB = bottle.GetComponent(/datum/component/storage)
if(STRB)
drop_threshold = STRB.max_items - bottle.contents.len
@@ -384,6 +384,38 @@
adjust_item_drop_location(P)
reagents.trans_to(P, vol_part)
. = TRUE
+
+ if("createDart")
+ for(var/datum/reagent/R in reagents.reagent_list)
+ if(!(istype(R, /datum/reagent/medicine)))
+ visible_message("The [src] beeps, \"SmartDarts are insoluble with non-medicinal compounds.\" ")
+ return
+
+ var/many = params["many"]
+ if(reagents.total_volume == 0)
+ return
+ var/amount = 1
+ var/vol_each = min(reagents.total_volume, 20)
+ if(text2num(many))
+ amount = CLAMP(round(input(usr, "Max 10. Buffer content will be split evenly.", "How many darts?", amount) as num|null), 0, 10)
+ if(!amount)
+ return
+ vol_each = min(reagents.total_volume / amount, 20)
+
+ var/name = stripped_input(usr,"Name:","Name your SmartDart!", "[reagents.get_master_reagent_name()] ([vol_each]u)", MAX_NAME_LEN)
+ if(!name || !reagents.total_volume || !src || QDELETED(src) || !usr.canUseTopic(src, !issilicon(usr)))
+ return
+
+ var/obj/item/reagent_containers/syringe/dart/D
+ for(var/i = 0; i < amount; i++)
+ D = new /obj/item/reagent_containers/syringe/dart(drop_location())
+ D.name = trim("[name] SmartDart")
+ adjust_item_drop_location(D)
+ reagents.trans_to(D, vol_each)
+ D.mode=!mode
+ D.update_icon()
+ . = TRUE
+
//END CITADEL ADDITIONS
if("analyzeBeak")
var/datum/reagent/R = GLOB.chemical_reagents_list[params["id"]]
@@ -405,7 +437,7 @@
if(!targetReagent)
CRASH("Tried to find a reagent that doesn't exist in the chem_master!")
- analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
+ analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
@@ -432,7 +464,7 @@
if(!targetReagent)
CRASH("Tried to find a reagent that doesn't exist in the chem_master!")
- analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.InverseChemVal), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
+ analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold), "purityF" = targetReagent.purity, "inverseRatioF" = initial(R.inverse_chem_val), "purityE" = initial(Rcr.PurityMin), "minTemp" = initial(Rcr.OptimalTempMin), "maxTemp" = initial(Rcr.OptimalTempMax), "eTemp" = initial(Rcr.ExplodeTemp), "pHpeak" = pHpeakCache)
else
fermianalyze = FALSE
analyzeVars = list("name" = initial(R.name), "state" = state, "color" = initial(R.color), "description" = initial(R.description), "metaRate" = T, "overD" = initial(R.overdose_threshold), "addicD" = initial(R.addiction_threshold))
diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm
index 0e482f8cec..05fa4d382a 100644
--- a/code/modules/reagents/chemistry/machinery/pandemic.dm
+++ b/code/modules/reagents/chemistry/machinery/pandemic.dm
@@ -125,12 +125,6 @@
else
cut_overlays()
-/obj/machinery/computer/pandemic/proc/eject_beaker()
- if(beaker)
- beaker.forceMove(drop_location())
- beaker = null
- update_icon()
-
/obj/machinery/computer/pandemic/ui_interact(mob/user, ui_key = "main", datum/tgui/ui, force_open = FALSE, datum/tgui/master_ui, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -165,7 +159,7 @@
return
switch(action)
if("eject_beaker")
- eject_beaker()
+ replace_beaker(usr)
. = TRUE
if("empty_beaker")
if(beaker)
@@ -174,7 +168,7 @@
if("empty_eject_beaker")
if(beaker)
beaker.reagents.clear_reagents()
- eject_beaker()
+ replace_beaker(usr)
. = TRUE
if("rename_disease")
var/id = get_virus_id_by_index(text2num(params["index"]))
@@ -194,13 +188,15 @@
to_chat(usr, "ERROR: Cannot replicate virus strain. ")
return
A = A.Copy()
- var/list/data = list("viruses" = list(A))
+ var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY", "viruses" = list(A))
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
B.name = "[A.name] culture bottle"
B.desc = "A small bottle. Contains [A.agent] culture in synthblood medium."
B.reagents.add_reagent("blood", 20, data)
wait = TRUE
update_icon()
+ var/turf/source_turf = get_turf(src)
+ log_virus("A culture bottle was printed for the virus [A.admin_details()] at [loc_name(source_turf)] by [key_name(usr)]")
addtimer(CALLBACK(src, .proc/reset_replicator_cooldown), 50)
. = TRUE
if("create_vaccine_bottle")
@@ -232,18 +228,32 @@
. = TRUE //no afterattack
if(stat & (NOPOWER|BROKEN))
return
- if(beaker)
- to_chat(user, "A container is already loaded into [src]! ")
+ var/obj/item/reagent_containers/B = I
+ if(!user.transferItemToLoc(B, src))
return
- if(!user.transferItemToLoc(I, src))
- return
-
- beaker = I
+ replace_beaker(user, B)
to_chat(user, "You insert [I] into [src]. ")
- update_icon()
else
return ..()
+/obj/machinery/computer/pandemic/AltClick(mob/living/user)
+ if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
+ return
+ replace_beaker(user)
+ return
+
+/obj/machinery/computer/pandemic/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker)
+ if(beaker)
+ if(user && Adjacent(user) && !issiliconoradminghost(user))
+ if(!user.put_in_hands(beaker))
+ beaker.forceMove(drop_location())
+ if(new_beaker)
+ beaker = new_beaker
+ else
+ beaker = null
+ update_icon()
+ return TRUE
+
/obj/machinery/computer/pandemic/on_deconstruction()
- eject_beaker()
+ replace_beaker(usr)
. = ..()
diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm
index 520148848c..52d3ba7822 100644
--- a/code/modules/reagents/chemistry/reagents.dm
+++ b/code/modules/reagents/chemistry/reagents.dm
@@ -32,20 +32,18 @@
var/addiction_stage3_end = 30
var/addiction_stage4_end = 40
var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick.
- var/self_consuming = FALSE
- var/metabolizing = FALSE
- var/invisible = FALSE //Set to true if it doesn't appear on handheld health analyzers.
+ var/self_consuming = FALSE //I think this uhhh, makes weird stuff happen when metabolising, but... doesn't seem to do what I think, so I'm gonna leave it.
//Fermichem vars:
- var/purity = 1 //How pure a chemical is from 0 - 1.
- var/addProc = FALSE //If the chemical should force an on_new() call
- var/turf/loc = null //Should be the creation location!
+ var/purity = 1 //How pure a chemical is from 0 - 1.
+ var/cached_purity = 1
+ var/turf/loc = null //Should be the creation location!
var/pH = 7 //pH of the specific reagent, used for calculating the sum pH of a holder.
- var/SplitChem = FALSE //If the chem splits on metabolism
- var/ImpureChem = "fermiTox"// What chemical is metabolised with an inpure reaction
- var/InverseChemVal = 0.25 // If the impurity is below 0.5, replace ALL of the chem with InverseChem upon metabolising
- var/InverseChem = "fermiTox"// What chem is metabolised when purity is below InverseChemVal, this shouldn't be made, but if it does, well, I guess I'll know about it.
- var/DoNotSplit = FALSE // If impurity is handled within the main chem itself
- var/OnMobMergeCheck = FALSE //Call on_mob_life proc when reagents are merging.
+ //var/SplitChem = FALSE //If the chem splits on metabolism
+ var/impure_chem // What chemical is metabolised with an inpure reaction
+ var/inverse_chem_val = 0 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising
+ var/inverse_chem // What chem is metabolised when purity is below inverse_chem_val, this shouldn't be made, but if it does, well, I guess I'll know about it.
+ var/metabolizing = FALSE
+ var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME
/datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references
@@ -75,28 +73,47 @@
holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
return
+//called when a mob processes chems when dead.
+/datum/reagent/proc/on_mob_dead(mob/living/carbon/M)
+ if(!(chemical_flags & REAGENT_DEAD_PROCESS)) //justincase
+ return
+ current_cycle++
+ if(holder)
+ holder.remove_reagent(src.id, metabolization_rate * M.metabolism_efficiency) //By default it slowly disappears.
+ return
+
// Called when this reagent is first added to a mob
/datum/reagent/proc/on_mob_add(mob/living/L, amount)
- if(SplitChem)
- var/mob/living/carbon/M = L
- if(!M)
- return
- if(purity < 0)
- CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
- if (purity == 1 || DoNotSplit == TRUE)
- log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [id]")
- return
- else if (InverseChemVal > purity)//Turns all of a added reagent into the inverse chem
- M.reagents.remove_reagent(id, amount, FALSE)
- M.reagents.add_reagent(InverseChem, amount, FALSE, other_purity = 1)
- log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [InverseChem]")
- return
- else
- var/impureVol = amount * (1 - purity) //turns impure ratio into impure chem
+ if(!iscarbon(L))
+ return
+ var/mob/living/carbon/M = L
+ if (purity == 1)
+ log_game("CHEM: [L] ckey: [L.key] has ingested [volume]u of [id]")
+ return
+ if(cached_purity == 1)
+ cached_purity = purity
+ else if(purity < 0)
+ CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
+ if(chemical_flags & REAGENT_DONOTSPLIT)
+ return
+
+ if ((inverse_chem_val > purity) && (inverse_chem))//Turns all of a added reagent into the inverse chem
+ M.reagents.remove_reagent(id, amount, FALSE)
+ M.reagents.add_reagent(inverse_chem, amount, FALSE, other_purity = 1-cached_purity)
+ var/datum/reagent/R = M.reagents.has_reagent("[inverse_chem]")
+ if(R.chemical_flags & REAGENT_SNEAKYNAME)
+ R.name = name//Negative effects are hidden
+ if(R.chemical_flags & REAGENT_INVISIBLE)
+ R.chemical_flags |= (REAGENT_INVISIBLE)
+ log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [inverse_chem]")
+ return
+ else if (impure_chem)
+ var/impureVol = amount * (1 - purity) //turns impure ratio into impure chem
+ if(!(chemical_flags & REAGENT_SPLITRETAINVOL))
M.reagents.remove_reagent(id, (impureVol), FALSE)
- M.reagents.add_reagent(ImpureChem, impureVol, FALSE, other_purity = 1)
- log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume - impureVol]u of [id]")
- log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [ImpureChem]")
+ M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity)
+ log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume - impureVol]u of [id]")
+ log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [impure_chem]")
return
// Called when this reagent is removed while inside a mob
@@ -120,31 +137,34 @@
// Called when two reagents of the same are mixing.
/datum/reagent/proc/on_merge(data, amount, mob/living/carbon/M, purity)
- if(SplitChem)
- if(!ishuman(M))
- return
- if (purity < 0)
- CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
- if (purity == 1 || DoNotSplit == TRUE)
- log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [id] in themselves")
- return
- else if (InverseChemVal > purity)
- M.reagents.remove_reagent(id, amount, FALSE)
- M.reagents.add_reagent(InverseChem, amount, FALSE, other_purity = 1)
- for(var/datum/reagent/fermi/R in M.reagents.reagent_list)
- if(R.name == "")
- R.name = name//Negative effects are hidden
- log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [InverseChem]")
- return
- else
- var/impureVol = amount * (1 - purity)
+ if(!iscarbon(M))
+ return
+ if (purity == 1)
+ log_game("FERMICHEM: [M] ckey: [M.key] has ingested [volume]u of [id]")
+ return
+ cached_purity = purity //purity SHOULD be precalculated from the add_reagent, update cache.
+ if (purity < 0)
+ CRASH("Purity below 0 for chem: [id], Please let Fermis Know!")
+ if(chemical_flags & REAGENT_DONOTSPLIT)
+ return
+
+ if ((inverse_chem_val > purity) && (inverse_chem)) //INVERT
+ M.reagents.remove_reagent(id, amount, FALSE)
+ M.reagents.add_reagent(inverse_chem, amount, FALSE, other_purity = 1-cached_purity)
+ var/datum/reagent/R = M.reagents.has_reagent("[inverse_chem]")
+ if(R.chemical_flags & REAGENT_SNEAKYNAME)
+ R.name = name//Negative effects are hidden
+ if(R.chemical_flags & REAGENT_INVISIBLE)
+ R.chemical_flags |= (REAGENT_INVISIBLE)
+ log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [inverse_chem]")
+ return
+ else if (impure_chem) //SPLIT
+ var/impureVol = amount * (1 - purity)
+ if(!(chemical_flags & REAGENT_SPLITRETAINVOL))
M.reagents.remove_reagent(id, impureVol, FALSE)
- M.reagents.add_reagent(ImpureChem, impureVol, FALSE, other_purity = 1)
- for(var/datum/reagent/fermi/R in M.reagents.reagent_list)
- if(R.name == "")
- R.name = name//Negative effects are hidden
- log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume - impureVol]u of [id]")
- log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [ImpureChem]")
+ M.reagents.add_reagent(impure_chem, impureVol, FALSE, other_purity = 1-cached_purity)
+ log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume - impureVol]u of [id]")
+ log_game("FERMICHEM: [M] ckey: [M.key] has merged [volume]u of [impure_chem]")
return
/datum/reagent/proc/on_update(atom/A)
diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
index 88073ca5f3..94aca411be 100644
--- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm
@@ -1383,10 +1383,10 @@ All effects don't start immediately, but rather get worse over time; the rate is
glass_icon_state = "neurotoxinglass"
glass_name = "Neurotoxin"
glass_desc = "A drink that is guaranteed to knock you silly."
- SplitChem = TRUE
- ImpureChem = "neuroweak"
- InverseChemVal = 0 //Clear conversion
- InverseChem = "neuroweak"
+ //SplitChem = TRUE
+ impure_chem = "neuroweak"
+ inverse_chem_val = 0.5 //Clear conversion
+ inverse_chem = "neuroweak"
/datum/reagent/consumable/ethanol/neurotoxin/proc/pickt()
return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG))
@@ -1394,7 +1394,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/neurotoxin/on_mob_life(mob/living/carbon/M)
M.set_drugginess(50)
M.dizziness +=2
- M.adjustBrainLoss(1*REM, 150)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 150)
if(prob(20) && !holder.has_reagent("neuroweak"))
M.adjustStaminaLoss(10)
M.drop_all_held_items()
@@ -1405,7 +1405,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
ADD_TRAIT(M, t, type)
M.adjustStaminaLoss(10)
if(current_cycle > 30)
- M.adjustBrainLoss(2*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
if(current_cycle > 50 && prob(15))
if(!M.undergoing_cardiac_arrest() && M.can_heartattack())
M.set_heartattack(TRUE)
@@ -1431,13 +1431,13 @@ All effects don't start immediately, but rather get worse over time; the rate is
/datum/reagent/consumable/ethanol/neuroweak/on_mob_life(mob/living/carbon/M)
if(holder.has_reagent("neurotoxin"))
- M.adjustBrainLoss(-1*REM, 150)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REM, 150)
M.reagents.remove_reagent("neurotoxin", 1.5 * REAGENTS_METABOLISM, FALSE)
if(holder.has_reagent("fentanyl"))
- M.adjustBrainLoss(-1*REM, 150)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1*REM, 150)
M.reagents.remove_reagent("fentanyl", 0.75 * REAGENTS_METABOLISM, FALSE)
else
- M.adjustBrainLoss(-0.5*REM, 150)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -0.5*REM, 150)
M.dizziness +=2
..()
diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
index dd51ce2bc7..1afbed3533 100644
--- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm
@@ -407,10 +407,10 @@
/datum/reagent/consumable/nuka_cola/on_mob_metabolize(mob/living/L)
..()
- ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
+ L.add_movespeed_modifier(id, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
/datum/reagent/consumable/nuka_cola/on_mob_end_metabolize(mob/living/L)
- REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id)
+ L.remove_movespeed_modifier(id)
..()
/datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/M)
diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
index 5b06710472..15d517a0f5 100644
--- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm
@@ -80,14 +80,14 @@
. = 1
/datum/reagent/drug/crank/overdose_process(mob/living/M)
- M.adjustBrainLoss(2*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
M.adjustToxLoss(2*REM, 0)
M.adjustBruteLoss(2*REM, 0)
..()
. = 1
/datum/reagent/drug/crank/addiction_act_stage1(mob/living/M)
- M.adjustBrainLoss(5*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5*REM)
..()
/datum/reagent/drug/crank/addiction_act_stage2(mob/living/M)
@@ -101,7 +101,7 @@
. = 1
/datum/reagent/drug/crank/addiction_act_stage4(mob/living/M)
- M.adjustBrainLoss(3*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REM)
M.adjustToxLoss(5*REM, 0)
M.adjustBruteLoss(5*REM, 0)
..()
@@ -125,13 +125,13 @@
..()
/datum/reagent/drug/krokodil/overdose_process(mob/living/M)
- M.adjustBrainLoss(0.25*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.25*REM)
M.adjustToxLoss(0.25*REM, 0)
..()
. = 1
/datum/reagent/drug/krokodil/addiction_act_stage1(mob/living/M)
- M.adjustBrainLoss(2*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
M.adjustToxLoss(2*REM, 0)
..()
. = 1
@@ -192,7 +192,7 @@
if(jitter)
M.Jitter(2)
if(brain_damage)
- M.adjustBrainLoss(rand(1,4))
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, rand(1,4))
M.heal_overall_damage(2, 2)
if(prob(5))
M.emote(pick("twitch", "shiver"))
@@ -210,7 +210,7 @@
M.drop_all_held_items()
..()
M.adjustToxLoss(1, 0)
- M.adjustBrainLoss(pick(0.5, 0.6, 0.7, 0.8, 0.9, 1))
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, pick(0.5, 0.6, 0.7, 0.8, 0.9, 1))
. = 1
/datum/reagent/drug/methamphetamine/addiction_act_stage1(mob/living/M)
@@ -289,7 +289,7 @@
if(prob(5))
to_chat(M, "[high_message] ")
M.adjustStaminaLoss(-5, 0)
- M.adjustBrainLoss(4)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4)
M.hallucination += 5
if(M.canmove && !ismovableatom(M.loc))
step(M, pick(GLOB.cardinals))
@@ -314,7 +314,7 @@
for(var/i = 0, i < 8, i++)
step(M, pick(GLOB.cardinals))
M.Jitter(5)
- M.adjustBrainLoss(10)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
if(prob(20))
M.emote(pick("twitch","drool","moan"))
..()
@@ -326,7 +326,7 @@
step(M, pick(GLOB.cardinals))
M.Jitter(10)
M.Dizzy(10)
- M.adjustBrainLoss(10)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
if(prob(30))
M.emote(pick("twitch","drool","moan"))
..()
@@ -338,7 +338,7 @@
step(M, pick(GLOB.cardinals))
M.Jitter(15)
M.Dizzy(15)
- M.adjustBrainLoss(10)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
if(prob(40))
M.emote(pick("twitch","drool","moan"))
..()
@@ -351,7 +351,7 @@
M.Jitter(50)
M.Dizzy(50)
M.adjustToxLoss(5, 0)
- M.adjustBrainLoss(10)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 10)
if(prob(50))
M.emote(pick("twitch","drool","moan"))
..()
@@ -401,7 +401,7 @@
M.jitteriness = 0
M.confused = 0
M.disgust = 0
- M.adjustBrainLoss(0.2)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2)
..()
. = 1
@@ -418,12 +418,12 @@
if(3)
M.emote("frown")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "happiness_drug", /datum/mood_event/happiness_drug_bad_od)
- M.adjustBrainLoss(0.5)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)
..()
. = 1
/datum/reagent/drug/happiness/addiction_act_stage1(mob/living/M)// all work and no play makes jack a dull boy
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_DISTURBED))
M.Jitter(5)
if(prob(20))
@@ -431,7 +431,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage2(mob/living/M)
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_UNSTABLE))
M.Jitter(10)
if(prob(30))
@@ -439,7 +439,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage3(mob/living/M)
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(min(mood.sanity, SANITY_CRAZY))
M.Jitter(15)
if(prob(40))
@@ -447,7 +447,7 @@
..()
/datum/reagent/drug/happiness/addiction_act_stage4(mob/living/carbon/human/M)
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
mood.setSanity(SANITY_INSANE)
M.Jitter(20)
if(prob(50))
@@ -469,7 +469,7 @@
/datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L)
. = ..()
- ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
+ L.add_movespeed_modifier(id, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
L.next_move_modifier *= 2
if(ishuman(L))
var/mob/living/carbon/human/H = L
@@ -480,7 +480,7 @@
/datum/reagent/drug/skooma/on_mob_end_metabolize(mob/living/L)
. = ..()
- REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id)
+ L.remove_movespeed_modifier(id)
L.next_move_modifier *= 0.5
if(ishuman(L))
var/mob/living/carbon/human/H = L
@@ -490,7 +490,7 @@
H.dna.species.punchdamagehigh *= 0.2
/datum/reagent/drug/skooma/on_mob_life(mob/living/carbon/M)
- M.adjustBrainLoss(1*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM)
M.adjustToxLoss(1*REM)
if(prob(10))
M.adjust_blurriness(2)
@@ -522,7 +522,7 @@
M.Dizzy(50)
M.adjust_blurriness(10)
if(prob(50)) //This proc will be called about 200 times and the adjustbrainloss() below only has to be called 40 times to kill. This will make surviving skooma addiction pretty rare without mannitol usage.
- M.adjustBrainLoss(5)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
if(prob(40))
M.emote(pick("twitch","drool","moan"))
..()
diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm
index 5e68f84792..056c5b1901 100644
--- a/code/modules/reagents/chemistry/reagents/food_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm
@@ -691,7 +691,7 @@
. = 1
if(prob(20))
M.losebreath += 4
- M.adjustBrainLoss(2*REM, 150)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM, 150)
M.adjustToxLoss(3*REM,0)
M.adjustStaminaLoss(10*REM,0)
M.blur_eyes(5)
diff --git a/code/modules/reagents/chemistry/reagents/impure_reagents.dm b/code/modules/reagents/chemistry/reagents/impure_reagents.dm
new file mode 100644
index 0000000000..c96347cda2
--- /dev/null
+++ b/code/modules/reagents/chemistry/reagents/impure_reagents.dm
@@ -0,0 +1,26 @@
+//Reagents produced by metabolising/reacting fermichems inoptimally, i.e. inverse_chems or impure_chems
+//Inverse = Splitting
+//Invert = Whole conversion
+
+/datum/reagent/impure
+ chemical_flags = REAGENT_INVISIBLE | REAGENT_SNEAKYNAME //by default, it will stay hidden on splitting, but take the name of the source on inverting
+
+
+/datum/reagent/impure/fermiTox
+ name = "Chemical Isomers"
+ id = "fermiTox"
+ description = "Toxic chemical isomers made from impure reactions. At low volumes will cause light toxin damage, but as the volume increases, it deals larger amounts, damages the liver, then eventually the heart. This is default impure chem for all chems, and changes only if stated."
+ data = "merge"
+ color = "FFFFFF"
+ can_synth = FALSE
+ var/potency = 1 //potency multiplies the volume when added.
+
+
+//I'm concerned this is too weak, but I also don't want deathmixes.
+//TODO: liver damage, 100+ heart
+/datum/reagent/impure/fermiTox/on_mob_life(mob/living/carbon/C, method)
+ if(C.dna && istype(C.dna.species, /datum/species/jelly))
+ C.adjustToxLoss(-2)
+ else
+ C.adjustToxLoss(2)
+ ..()
diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
index 4dc0d145dc..592f7bc592 100644
--- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm
@@ -44,7 +44,7 @@
M.heal_bodypart_damage(5,5)
M.adjustToxLoss(-5, 0, TRUE)
M.hallucination = 0
- M.setBrainLoss(0)
+ M.setOrganLoss(ORGAN_SLOT_BRAIN, 0)
REMOVE_TRAITS_NOT_IN(M, list(SPECIES_TRAIT, ROUNDSTART_TRAIT, ORGAN_TRAIT))
M.set_blurriness(0)
M.set_blindness(0)
@@ -64,6 +64,10 @@
if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
M.blood_volume = (BLOOD_VOLUME_NORMAL*M.blood_ratio)
+ for(var/organ in M.internal_organs)
+ var/obj/item/organ/O = organ
+ O.setOrganDamage(0)
+
for(var/thing in M.diseases)
var/datum/disease/D = thing
if(D.severity == DISEASE_SEVERITY_POSITIVE)
@@ -232,10 +236,12 @@
/datum/reagent/medicine/silver_sulfadiazine
name = "Silver Sulfadiazine"
id = "silver_sulfadiazine"
- description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. If ingested through other means, deals minor toxin damage."
+ description = "If used in touch-based applications, immediately restores burn wounds as well as restoring more over time. It is mildly poisonous taken orally or by injection. If overdosed, deals brute and minor liver damage."
reagent_state = LIQUID
pH = 7.2
color = "#ffeac9"
+ metabolization_rate = 5 * REAGENTS_METABOLISM
+ overdose_threshold = 50
/datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
@@ -256,6 +262,15 @@
..()
. = 1
+/datum/reagent/medicine/silver_sulfadiazine/overdose_start(mob/living/M)
+ metabolization_rate = 15 * REAGENTS_METABOLISM
+ M.adjustBruteLoss(2*REM, 0)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.applyLiverDamage(1)
+ ..()
+ . = 1
+
/datum/reagent/medicine/oxandrolone
name = "Oxandrolone"
id = "oxandrolone"
@@ -267,7 +282,7 @@
pH = 10.7
/datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/carbon/M)
- if(M.getFireLoss() > 50)
+ if(M.getFireLoss() > 25)
M.adjustFireLoss(-4*REM, 0) //Twice as effective as silver sulfadiazine for severe burns
else
M.adjustFireLoss(-0.5*REM, 0) //But only a quarter as effective for more minor ones
@@ -283,10 +298,12 @@
/datum/reagent/medicine/styptic_powder
name = "Styptic Powder"
id = "styptic_powder"
- description = "If used in touch-based applications, immediately restores bruising as well as restoring more over time. If ingested through other means, deals minor toxin damage."
+ description = "If used in touch-based applications, immediately restores bruising as well as restoring more over time. It is poisonous if taken orally or by injection. If overdosed, deals brute and minor liver damage."
reagent_state = LIQUID
color = "#FF9696"
pH = 6.7
+ metabolization_rate = 5 * REAGENTS_METABOLISM
+ overdose_threshold = 50
/datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1)
if(iscarbon(M) && M.stat != DEAD)
@@ -308,6 +325,15 @@
..()
. = 1
+datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M)
+ metabolization_rate = 15 * REAGENTS_METABOLISM
+ M.adjustBruteLoss(2*REM, 0)
+ if(iscarbon(M))
+ var/mob/living/carbon/C = M
+ C.applyLiverDamage(1)
+ ..()
+ . = 1
+
/datum/reagent/medicine/salglu_solution
name = "Saline-Glucose Solution"
id = "salglu_solution"
@@ -394,23 +420,35 @@
/datum/reagent/medicine/synthflesh
name = "Synthflesh"
id = "synthflesh"
- description = "Has a 100% chance of instantly healing brute and burn damage. One unit of the chemical will heal one point of damage. Touch application only."
+ description = "Has a 100% chance of healing large amounts of brute and burn damage very quickly. One unit of the chemical will heal one point of damage. Touch application only."
reagent_state = LIQUID
color = "#FFEBEB"
pH = 11.5
+ metabolization_rate = 5 * REAGENTS_METABOLISM
+ overdose_threshold = 40
/datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1)
if(iscarbon(M))
if (M.stat == DEAD)
show_message = 0
- if(method in list(PATCH, TOUCH))
- M.adjustBruteLoss(-1.25 * reac_volume)
- M.adjustFireLoss(-1.25 * reac_volume)
+ if(method in list(INGEST, VAPOR))
+ var/mob/living/carbon/C = M
+ C.losebreath++
+ C.emote("cough")
+ to_chat(M, "You feel your throat closing up! ")
+ else if(method == INJECT)
+ return
+ else if(method in list(PATCH, TOUCH))
+ M.adjustBruteLoss(-1 * reac_volume)
+ M.adjustFireLoss(-1 * reac_volume)
if(show_message)
to_chat(M, "You feel your burns and bruises healing! It stings like hell! ")
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
..()
+/datum/reagent/medicine/synthflesh/overdose_start(mob/living/M)
+ metabolization_rate = 15 * REAGENTS_METABOLISM
+
/datum/reagent/medicine/charcoal
name = "Charcoal"
id = "charcoal"
@@ -541,7 +579,7 @@
/datum/reagent/medicine/sal_acid/on_mob_life(mob/living/carbon/M)
- if(M.getBruteLoss() > 50)
+ if(M.getBruteLoss() > 25)
M.adjustBruteLoss(-4*REM, 0) //Twice as effective as styptic powder for severe bruising
else
M.adjustBruteLoss(-0.5*REM, 0) //But only a quarter as effective for more minor ones
@@ -852,10 +890,16 @@
if(M.notify_ghost_cloning(source = M))
spawn (100) //so the ghost has time to re-enter
return
+
else
M.adjustOxyLoss(-20, 0)
M.adjustToxLoss(-20, 0)
+ var/mob/living/carbon/H = M
+ for(var/organ in H.internal_organs)
+ var/obj/item/organ/O = organ
+ O.setOrganDamage(0)
M.updatehealth()
+
if(M.revive())
M.emote("gasp")
log_combat(M, M, "revived", src)
@@ -875,7 +919,7 @@
pH = 10.4
/datum/reagent/medicine/mannitol/on_mob_life(mob/living/carbon/C)
- C.adjustBrainLoss(-2*REM)
+ C.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2*REM)
if(prob(10))
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
..()
@@ -940,10 +984,10 @@
/datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L)
..()
- ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
+ L.add_movespeed_modifier(id, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
/datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/L)
- REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id)
+ L.remove_movespeed_modifier(id)
..()
/datum/reagent/medicine/stimulants/on_mob_life(mob/living/carbon/M)
@@ -1130,7 +1174,7 @@
M.adjustFireLoss(-5*REM, 0)
M.adjustOxyLoss(-15, 0)
M.adjustToxLoss(-5*REM, 0)
- M.adjustBrainLoss(-15*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -15*REM)
M.adjustCloneLoss(-3*REM, 0)
M.adjustStaminaLoss(-20*REM,0)
..()
@@ -1175,7 +1219,7 @@
M.adjustFireLoss(-3 * REM, 0)
M.adjustOxyLoss(-15 * REM, 0)
M.adjustToxLoss(-3 * REM, 0, TRUE) //Heals TOXINLOVERS
- M.adjustBrainLoss(2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2 * REM, 150) //This does, after all, come from ambrosia, and the most powerful ambrosia in existence, at that!
M.adjustCloneLoss(-1 * REM, 0)
M.adjustStaminaLoss(-13 * REM, 0)
M.jitteriness = min(max(0, M.jitteriness + 3), 30)
@@ -1207,7 +1251,7 @@
if (M.hallucination >= 5)
M.hallucination -= 5
if(prob(20))
- M.adjustBrainLoss(1*REM, 50)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1*REM, 50)
M.adjustStaminaLoss(2.5*REM, 0)
..()
return TRUE
@@ -1264,10 +1308,10 @@
/datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L)
..()
- ADD_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id)
+ L.add_movespeed_modifier(id, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING))
/datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/L)
- REMOVE_TRAIT(L, TRAIT_GOTTAGOREALLYFAST, id)
+ L.remove_movespeed_modifier(id)
..()
/datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/M)
@@ -1287,10 +1331,12 @@
/datum/reagent/medicine/corazone/on_mob_metabolize(mob/living/M)
..()
- ADD_TRAIT(M, TRAIT_STABLEHEART, id)
+ ADD_TRAIT(M, TRAIT_STABLEHEART, type)
+ ADD_TRAIT(M, TRAIT_STABLELIVER, type)
/datum/reagent/medicine/corazone/on_mob_end_metabolize(mob/living/M)
- REMOVE_TRAIT(M, TRAIT_STABLEHEART, id)
+ REMOVE_TRAIT(M, TRAIT_STABLEHEART, type)
+ REMOVE_TRAIT(M, TRAIT_STABLELIVER, type)
..()
/datum/reagent/medicine/muscle_stimulant
@@ -1397,7 +1443,7 @@
M.dizziness = max(0, M.dizziness-6)
M.confused = max(0, M.confused-6)
M.disgust = max(0, M.disgust-6)
- GET_COMPONENT_FROM(mood, /datum/component/mood, M)
+ var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
if(mood.sanity <= SANITY_NEUTRAL) // only take effect if in negative sanity and then...
mood.setSanity(min(mood.sanity+5, SANITY_NEUTRAL)) // set minimum to prevent unwanted spiking over neutral
..()
diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 2f7a8652ba..af6a65ebe1 100644
--- a/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -1,8 +1,9 @@
/datum/reagent/blood
- data = list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
name = "Blood"
id = "blood"
- color = "#C80000" // rgb: 200, 0, 0
+ color = BLOOD_COLOR_HUMAN // rgb: 200, 0, 0
+ description = "Blood from some creature."
metabolization_rate = 5 //fast rate so it disappears fast.
taste_description = "iron"
taste_mult = 1.3
@@ -27,27 +28,75 @@
if(iscarbon(L))
var/mob/living/carbon/C = L
- if(C.get_blood_id() == "blood" && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
- if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type)))
- C.reagents.add_reagent("toxin", reac_volume * 0.5)
- else
- C.blood_volume = min(C.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM)
+ var/blood_id = C.get_blood_id()
+ if((blood_id == "blood" || blood_id == "jellyblood") && (method == INJECT || (method == INGEST && C.dna && C.dna.species && (DRINKSBLOOD in C.dna.species.species_traits))))
+ C.blood_volume = min(C.blood_volume + round(reac_volume, 0.1), BLOOD_VOLUME_MAXIMUM * C.blood_ratio)
+ // we don't care about bloodtype here, we're just refilling the mob
- if(reac_volume >= 10 && istype(L))
+ if(reac_volume >= 10 && istype(L) && method != INJECT)
L.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
+/datum/reagent/blood/on_mob_life(mob/living/carbon/C) //Because lethals are preferred over stamina. damnifino.
+ var/blood_id = C.get_blood_id()
+ if((blood_id == "blood" || blood_id == "jellyblood"))
+ if(!data || !(data["blood_type"] in get_safe_blood(C.dna.blood_type))) //we only care about bloodtype here because this is where the poisoning should be
+ C.adjustToxLoss(rand(2,8)*REM, TRUE, TRUE) //forced to ensure people don't use it to gain beneficial toxin as slime person
+ ..()
+
/datum/reagent/blood/reaction_obj(obj/O, volume)
if(volume >= 3 && istype(O))
- O.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
+ O.add_blood_DNA(data)
+
+/datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place
+ if(!istype(T))
+ return
+ if(reac_volume < 3)
+ return
+
+ var/obj/effect/decal/cleanable/blood/B = locate() in T //find some blood here
+ if(!B)
+ B = new(T)
+ if(data["blood_DNA"])
+ B.blood_DNA[data["blood_DNA"]] = data["blood_type"]
+ if(!B.reagents)
+ B.reagents.add_reagent(id, reac_volume)
+ B.update_icon()
/datum/reagent/blood/on_new(list/data)
if(istype(data))
SetViruses(src, data)
+ color = bloodtype_to_color(data["blood_type"])
+ if(data["blood_type"] == "SY")
+ name = "Synthetic Blood"
+ taste_description = "oily"
+
+ if(data["blood_type"] == "X*")
+ name = "Xenomorph Blood"
+ taste_description = "acidic heresy"
+ shot_glass_icon_state = "shotglassgreen"
+ pH = 2.5
+
+ if(data["blood_type"] == "HF")
+ name = "Hydraulic Blood"
+ taste_description = "burnt oil"
+ pH = 9.75
+
+ if(data["blood_type"] == "BUG")
+ name = "Insect Blood"
+ taste_description = "greasy"
+ pH = 7.25
+
+ if(data["blood_type"] == "L")
+ name = "Lizard Blood"
+ taste_description = "spicy"
+ pH = 6.85
+
+
/datum/reagent/blood/on_merge(list/mix_data)
if(data && mix_data)
if(data["blood_DNA"] != mix_data["blood_DNA"])
- data["cloneable"] = 0 //On mix, consider the genetic sampling unviable for pod cloning if the DNA sample doesn't match.
+ data["cloneable"] = FALSE //On mix, consider the genetic sampling unviable for pod cloning if the DNA sample doesn't match.
if(data["viruses"] || mix_data["viruses"])
var/list/mix1 = data["viruses"]
@@ -77,27 +126,111 @@
var/datum/disease/D = thing
. += D
-/datum/reagent/blood/reaction_turf(turf/T, reac_volume)//splash the blood all over the place
- if(!istype(T))
- return
- if(reac_volume < 3)
- return
+/datum/reagent/blood/synthetics
+ data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Synthetic Blood"
+ id = "syntheticblood"
+ taste_description = "oily"
+ color = BLOOD_COLOR_SYNTHETIC // rgb: 11, 7, 48
- var/obj/effect/decal/cleanable/blood/B = locate() in T //find some blood here
- if(!B)
- B = new(T)
- if(data["blood_DNA"])
- B.add_blood_DNA(list(data["blood_DNA"] = data["blood_type"]))
+/datum/reagent/blood/lizard
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_LIZARD, "blood_type"="L","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Lizard Blood"
+ id = "lizardblood"
+ taste_description = "spicy"
+ color = BLOOD_COLOR_LIZARD // rgb: 11, 7, 48
+ pH = 6.85
+
+/datum/reagent/blood/jellyblood
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Slime Jelly Blood"
+ id = "jellyblood"
+ description = "A gooey semi-liquid produced from one of the deadliest lifeforms in existence. SO REAL."
+ color = BLOOD_COLOR_SLIME
+ taste_description = "slime"
+ taste_mult = 1.3
+ pH = 4
+
+/datum/reagent/blood/xenomorph
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Xenomorph Blood"
+ id = "xenoblood"
+ taste_description = "acidic heresy"
+ color = BLOOD_COLOR_XENO // greenish yellow ooze
+ shot_glass_icon_state = "shotglassgreen"
+ pH = 2.5
+
+/datum/reagent/blood/oil
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Hydraulic Blood"
+ id = "oilblood"
+ taste_description = "burnt oil"
+ color = BLOOD_COLOR_OIL // dark, y'know, expected batman colors.
+ pH = 9.75
+
+/datum/reagent/blood/insect
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_BUG, "blood_type"="BUG","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ name = "Insectoid Blood"
+ id = "bugblood"
+ taste_description = "waxy"
+ color = BLOOD_COLOR_BUG // Bug colored, I guess.
+ pH = 7.25
+
+
+/datum/reagent/blood/jellyblood/on_mob_life(mob/living/carbon/M)
+ if(prob(10))
+ if(M.dna?.species?.exotic_bloodtype != "GEL")
+ to_chat(M, "Your insides are burning! ")
+ M.adjustToxLoss(rand(20,60)*REM, 0)
+ . = 1
+ else if(prob(40) && isjellyperson(M))
+ M.heal_bodypart_damage(2*REM)
+ . = 1
+ ..()
/datum/reagent/liquidgibs
name = "Liquid gibs"
id = "liquidgibs"
- color = "#FF9966"
+ color = BLOOD_COLOR_HUMAN
description = "You don't even want to think about what's in here."
taste_description = "gross iron"
shot_glass_icon_state = "shotglassred"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= "O+","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
pH = 7.45
+/datum/reagent/liquidgibs/xeno
+ name = "Liquid xeno gibs"
+ id = "liquidxenogibs"
+ color = BLOOD_COLOR_XENO
+ taste_description = "blended heresy"
+ shot_glass_icon_state = "shotglassgreen"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_XENO, "blood_type"="X*","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ pH = 2.5
+
+/datum/reagent/liquidgibs/slime
+ name = "Slime sludge"
+ id = "liquidslimegibs"
+ color = BLOOD_COLOR_SLIME
+ taste_description = "slime"
+ shot_glass_icon_state = "shotglassgreen"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ pH = 4
+
+/datum/reagent/liquidgibs/synth
+ name = "Synthetic sludge"
+ id = "liquidsyntheticgibs"
+ color = BLOOD_COLOR_SYNTHETIC
+ taste_description = "jellied plastic"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+
+/datum/reagent/liquidgibs/oil
+ name = "Hydraulic sludge"
+ id = "liquidoilgibs"
+ color = BLOOD_COLOR_OIL
+ taste_description = "chunky burnt oil"
+ data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_OIL, "blood_type"="HF","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null)
+ pH = 9.75
+
/datum/reagent/vaccine
//data must contain virus type
name = "Vaccine"
@@ -296,7 +429,7 @@
if(ishuman(M) && M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
M.blood_volume += 3
else // Will deal about 90 damage when 50 units are thrown
- M.adjustBrainLoss(3, 150)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150)
M.adjustToxLoss(2, 0)
M.adjustFireLoss(2, 0)
M.adjustOxyLoss(2, 0)
@@ -315,7 +448,7 @@
M.IgniteMob() //Only problem with igniting people is currently the commonly availible fire suits make you immune to being on fire
M.adjustToxLoss(1, 0)
M.adjustFireLoss(1, 0) //Hence the other damages... ain't I a bastard?
- M.adjustBrainLoss(5, 150)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5, 150)
holder.remove_reagent(id, 1)
pH = 0.1
@@ -584,6 +717,30 @@
race = /datum/species/android
mutationtext = "The pain subsides. You feel... artificial. "
+//Citadel Races
+/datum/reagent/mutationtoxin/mammal
+ name = "Mammal Mutation Toxin"
+ id = "mammalmutationtoxin"
+ description = "A glowing toxin."
+ color = "#5EFF3B" //RGB: 94, 255, 59
+ race = /datum/species/mammal
+ mutationtext = "The pain subsides. You feel... fluffier. "
+
+/datum/reagent/mutationtoxin/insect
+ name = "Insect Mutation Toxin"
+ id = "insectmutationtoxin"
+ description = "A glowing toxin."
+ color = "#5EFF3B" //RGB: 94, 255, 59
+ race = /datum/species/insect
+ mutationtext = "The pain subsides. You feel... attracted to dark, moist areas. "
+
+/datum/reagent/mutationtoxin/xenoperson
+ name = "Xeno-Hybrid Mutation Toxin"
+ id = "xenopersonmutationtoxin"
+ description = "A glowing toxin."
+ color = "#5EFF3B" //RGB: 94, 255, 59
+ race = /datum/species/xeno
+ mutationtext = "The pain subsides. You feel... oddly longing for the Queen. " //sadly, not the British one.
//BLACKLISTED RACES
/datum/reagent/mutationtoxin/skeleton
@@ -805,7 +962,7 @@
step(M, pick(GLOB.cardinals))
if(prob(5))
M.emote(pick("twitch","drool","moan"))
- M.adjustBrainLoss(1)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
..()
/datum/reagent/sulfur
@@ -946,12 +1103,12 @@
reagent_state = SOLID
taste_description = "iron"
pH = 6
-
+ overdose_threshold = 30
color = "#c2391d"
/datum/reagent/iron/on_mob_life(mob/living/carbon/C)
if(C.blood_volume < (BLOOD_VOLUME_NORMAL*C.blood_ratio))
- C.blood_volume += 0.5
+ C.blood_volume += 0.01 //we'll have synthetics from medbay.
..()
/datum/reagent/iron/reaction_mob(mob/living/M, method=TOUCH, reac_volume)
@@ -960,6 +1117,17 @@
M.reagents.add_reagent("toxin", reac_volume)
..()
+/datum/reagent/iron/overdose_start(mob/living/M)
+ to_chat(M, "You start feeling your guts twisting painfully! ")
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "[id]_overdose", /datum/mood_event/overdose, name)
+
+/datum/reagent/iron/overdose_process(mob/living/carbon/C)
+ if(prob(20))
+ var/obj/item/organ/liver/L = C.getorganslot(ORGAN_SLOT_LIVER)
+ if (istype(L))
+ C.applyLiverDamage(2) //mild until the fabled med rework comes out. the organ damage galore
+ ..()
+
/datum/reagent/gold
name = "Gold"
id = "gold"
@@ -1076,17 +1244,19 @@
pH = 5.5
/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
- if(istype(O, /obj/effect/decal/cleanable))
+ if(istype(O, /obj/effect/decal/cleanable) || istype(O, /obj/item/projectile/bullet/reusable/foam_dart) || istype(O, /obj/item/ammo_casing/caseless/foam_dart))
qdel(O)
else
if(O)
O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ O.clean_blood()
/datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume)
if(reac_volume >= 1)
T.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(T, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ T.clean_blood()
for(var/obj/effect/decal/cleanable/C in T)
qdel(C)
@@ -1104,26 +1274,33 @@
H.lip_style = null
H.update_body()
for(var/obj/item/I in C.held_items)
- SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(I, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ I.clean_blood()
if(C.wear_mask)
- if(SEND_SIGNAL(C.wear_mask, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(C.wear_mask, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(C.wear_mask.clean_blood())
C.update_inv_wear_mask()
if(ishuman(M))
var/mob/living/carbon/human/H = C
if(H.head)
- if(SEND_SIGNAL(H.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(H.head, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(H.head.clean_blood())
H.update_inv_head()
if(H.wear_suit)
- if(SEND_SIGNAL(H.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(H.wear_suit, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(H.wear_suit.clean_blood())
H.update_inv_wear_suit()
else if(H.w_uniform)
- if(SEND_SIGNAL(H.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(H.w_uniform, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(H.w_uniform.clean_blood())
H.update_inv_w_uniform()
if(H.shoes)
- if(SEND_SIGNAL(H.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
+ SEND_SIGNAL(H.shoes, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ if(H.shoes.clean_blood())
H.update_inv_shoes()
H.wash_cream()
- SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
+ SEND_SIGNAL(M, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_WEAK)
+ M.clean_blood()
/datum/reagent/space_cleaner/ez_clean
name = "EZ Clean"
@@ -1172,7 +1349,7 @@
/datum/reagent/impedrezene/on_mob_life(mob/living/carbon/M)
M.jitteriness = max(M.jitteriness-5,0)
if(prob(80))
- M.adjustBrainLoss(2*REM)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2*REM)
if(prob(50))
M.drowsyness = max(M.drowsyness, 3)
if(prob(10))
@@ -1222,7 +1399,7 @@
description = "A perfluoronated sulfonic acid that forms a foam when mixed with water."
color = "#9E6B38" // rgb: 158, 107, 56
taste_description = "metal"
- pH = 13
+ pH = 11
/datum/reagent/foaming_agent// Metal foaming agent. This is lithium hydride. Add other recipes (e.g. LiH + H2O -> LiOH + H2) eventually.
name = "Foaming agent"
@@ -1231,7 +1408,7 @@
reagent_state = SOLID
color = "#664B63" // rgb: 102, 75, 99
taste_description = "metal"
- pH = 12.5
+ pH = 11.5
/datum/reagent/smart_foaming_agent //Smart foaming agent. Functions similarly to metal foam, but conforms to walls.
name = "Smart foaming agent"
@@ -1352,10 +1529,10 @@
/datum/reagent/nitryl/on_mob_metabolize(mob/living/L)
..()
- ADD_TRAIT(L, TRAIT_GOTTAGOFAST, id)
+ L.add_movespeed_modifier(id, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
/datum/reagent/nitryl/on_mob_end_metabolize(mob/living/L)
- REMOVE_TRAIT(L, TRAIT_GOTTAGOFAST, id)
+ L.remove_movespeed_modifier(id)
..()
/////////////////////////Coloured Crayon Powder////////////////////////////
@@ -1519,20 +1696,6 @@
taste_description = "metal"
pH = 4.5
-/datum/reagent/carpet
- name = "Carpet"
- id = "carpet"
- description = "For those that need a more creative way to roll out a red carpet."
- reagent_state = LIQUID
- color = "#b51d05"
- taste_description = "carpet" // Your tounge feels furry.
-
-/datum/reagent/carpet/reaction_turf(turf/T, reac_volume)
- if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
- var/turf/open/floor/F = T
- F.PlaceOnTop(/turf/open/floor/carpet)
- ..()
-
/datum/reagent/bromine
name = "Bromine"
id = "bromine"
@@ -1665,7 +1828,7 @@
reagent_state = LIQUID
color = "#FFFFD6" // very very light yellow
taste_description = "alkali" //who put ACID for NaOH ????
- pH = 13
+ pH = 11.9
/datum/reagent/drying_agent
name = "Drying agent"
@@ -1686,6 +1849,143 @@
qdel(O)
new /obj/item/clothing/shoes/galoshes/dry(t_loc)
+// Liquid Carpets
+/datum/reagent/carpet
+ name = "Liquid Carpet"
+ id = "carpet"
+ description = "For those that need a more creative way to roll out a carpet."
+ reagent_state = LIQUID
+ color = "#b51d05"
+ taste_description = "carpet" // Your tounge feels furry.
+
+/datum/reagent/carpet/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet)
+ ..()
+
+/datum/reagent/carpet/black
+ name = "Liquid Black Carpet"
+ id = "blackcarpet"
+ color = "#363636"
+
+/datum/reagent/carpet/black/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/black)
+ ..()
+
+/datum/reagent/carpet/blackred
+ name = "Liquid Red Black Carpet"
+ id = "blackredcarpet"
+ color = "#342125"
+
+/datum/reagent/carpet/blackred/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/blackred)
+ ..()
+
+/datum/reagent/carpet/monochrome
+ name = "Liquid Monochrome Carpet"
+ id = "monochromecarpet"
+ color = "#b4b4b4"
+
+/datum/reagent/carpet/monochrome/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/monochrome)
+ ..()
+
+/datum/reagent/carpet/blue
+ name = "Liquid Blue Carpet"
+ id = "bluecarpet"
+ color = "#1256ff"
+
+/datum/reagent/carpet/blue/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/blue)
+ ..()
+
+/datum/reagent/carpet/cyan
+ name = "Liquid Cyan Carpet"
+ id = "cyancarpet"
+ color = "#3acfb9"
+
+/datum/reagent/carpet/cyan/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/cyan)
+ ..()
+
+/datum/reagent/carpet/green
+ name = "Liquid Green Carpet"
+ id = "greencarpet"
+ color = "#619b62"
+
+/datum/reagent/carpet/green/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/green)
+ ..()
+
+/datum/reagent/carpet/orange
+ name = "Liquid Orange Carpet"
+ id = "orangecarpet"
+ color = "#cc7900"
+
+/datum/reagent/carpet/orange/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/orange)
+ ..()
+
+/datum/reagent/carpet/purple
+ name = "Liquid Purple Carpet"
+ id = "purplecarpet"
+ color = "#6d3392"
+
+/datum/reagent/carpet/purple/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/purple)
+ ..()
+
+/datum/reagent/carpet/red
+ name = "Liquid Red Carpet"
+ id = "redcarpet"
+ color = "#871515"
+
+/datum/reagent/carpet/red/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/red)
+ ..()
+
+/datum/reagent/carpet/royalblack
+ name = "Liquid Royal Black Carpet"
+ id = "royalblackcarpet"
+ color = "#483d05"
+
+/datum/reagent/carpet/royalblack/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/royalblack)
+ ..()
+
+/datum/reagent/carpet/royalblue
+ name = "Liquid Royal Blue Carpet"
+ id = "royalbluecarpet"
+ color = "#24227e"
+
+/datum/reagent/carpet/royalblue/reaction_turf(turf/T, reac_volume)
+ if(isplatingturf(T) || istype(T, /turf/open/floor/plasteel))
+ var/turf/open/floor/F = T
+ F.PlaceOnTop(/turf/open/floor/carpet/royalblue)
+ ..()
+
+
// Virology virus food chems.
/datum/reagent/toxin/mutagen/mutagenvirusfood
@@ -1965,24 +2265,6 @@
M.emote("nya")
..()
-//Kept for legacy, I think it will break everything if you enable it.
-/datum/reagent/penis_enlargement
- name = "Penis Enlargement"
- id = "penis_enlargement"
- description = "A patented chemical forumula by Doctor Ronald Hyatt that is guaranteed to bring maximum GROWTH and LENGTH to your penis, today!"
- color = "#888888"
- taste_description = "chinese dragon powder"
- metabolization_rate = INFINITY //So it instantly removes all of itself. Don't want to put strain on the system.
-
-/datum/reagent/penis_enlargement/on_mob_life(mob/living/carbon/C)
- var/obj/item/organ/genital/penis/P = C.getorganslot(ORGAN_SLOT_PENIS)
- if(P)
- var/added_length = round(volume/30,0.01) //Every 30u gives an extra inch. Rounded to the nearest 0.01 so float fuckery doesn't occur with the division by 30.
- if(added_length >= 0.20) //Only add the length if it's greater than or equal to 0.2. This is to prevent people from smoking the reagents and causing the penis to update constantly.
- P.length += added_length
- P.update()
- ..()
-
/datum/reagent/changeling_string
name = "UNKNOWN"
id = "changeling_sting_real"
@@ -1992,29 +2274,25 @@
can_synth = FALSE
var/datum/dna/original_dna
var/reagent_ticks = 0
- invisible = TRUE
+ chemical_flags = REAGENT_INVISIBLE
/datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C)
- if(C && C.dna && data["desired_dna"])
+ if(ishuman(C) && C.dna && data["desired_dna"])
original_dna = new C.dna.type
C.dna.copy_dna(original_dna)
var/datum/dna/new_dna = data["desired_dna"]
- new_dna.copy_dna(C.dna)
+ new_dna.transfer_identity(C, TRUE)
C.real_name = new_dna.real_name
- C.updateappearance(mutcolor_update=1)
- C.update_body()
+ C.updateappearance(mutcolor_update = TRUE)
C.domutcheck()
- C.regenerate_icons()
..()
/datum/reagent/changeling_string/on_mob_end_metabolize(mob/living/carbon/C)
if(original_dna)
- original_dna.copy_dna(C.dna)
+ original_dna.transfer_identity(C, TRUE)
C.real_name = original_dna.real_name
- C.updateappearance(mutcolor_update=1)
- C.update_body()
+ C.updateappearance(mutcolor_update = TRUE)
C.domutcheck()
- C.regenerate_icons()
..()
/datum/reagent/changeling_string/Destroy()
diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
index 77600dec0f..2b50ecc0f1 100644
--- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
+++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm
@@ -471,7 +471,7 @@
toxpwr = 0
/datum/reagent/toxin/fentanyl/on_mob_life(mob/living/carbon/M)
- M.adjustBrainLoss(3*REM, 150)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3*REM, 150)
if(M.toxloss <= 60)
M.adjustToxLoss(1*REM, 0)
if(current_cycle >= 18)
@@ -950,3 +950,20 @@
to_chat(M, "Your missing arm aches from wherever you left it. ")
M.emote("sigh")
return ..()
+
+/datum/reagent/toxin/brainhurtingjuice //oof ouch
+ name = "Brain Hurting Juice"
+ id = "brainhurtingjuice"
+ color = "#AAAAAA77" //RGBA: 170, 170, 170, 77
+ toxpwr = 0
+ taste_description = "brain hurting"
+ metabolization_rate = 5
+
+/datum/reagent/toxin/brainhurtingjuice/on_mob_life(mob/living/carbon/M)
+ if(prob(50))
+ M.gain_trauma_type(BRAIN_TRAUMA_MILD)
+ else if(prob(50))
+ M.gain_trauma_type(BRAIN_TRAUMA_SEVERE)
+ else
+ M.gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
+ ..()
diff --git a/code/modules/reagents/chemistry/recipes.dm b/code/modules/reagents/chemistry/recipes.dm
index 32155c9b89..a915087428 100644
--- a/code/modules/reagents/chemistry/recipes.dm
+++ b/code/modules/reagents/chemistry/recipes.dm
@@ -32,6 +32,7 @@
var/RateUpLim = 10 // Optimal/max rate possible if all conditions are perfect
var/FermiChem = FALSE // If the chemical uses the Fermichem reaction mechanics//If the chemical uses the Fermichem reaction mechanics
var/FermiExplode = FALSE // If the chemical explodes in a special way
+ var/clear_conversion //bitflags for clear conversions; REACTION_CLEAR_IMPURE or REACTION_CLEAR_INVERSE
var/PurityMin = 0.15 //If purity is below 0.15, it explodes too. Set to 0 to disable this.
diff --git a/code/modules/reagents/chemistry/recipes/medicine.dm b/code/modules/reagents/chemistry/recipes/medicine.dm
index 59865dd1da..374f7715bb 100644
--- a/code/modules/reagents/chemistry/recipes/medicine.dm
+++ b/code/modules/reagents/chemistry/recipes/medicine.dm
@@ -68,6 +68,44 @@
results = list("synthflesh" = 3)
required_reagents = list("blood" = 1, "carbon" = 1, "styptic_powder" = 1)
+/datum/chemical_reaction/synthtissue
+ name = "Synthtissue"
+ id = "synthtissue"
+ results = list("synthtissue" = 5)
+ required_reagents = list("synthflesh" = 1)
+ required_catalysts = list("nutriment" = 0.1)
+ //FermiChem vars:
+ OptimalTempMin = 305 // Lower area of bell curve for determining heat based rate reactions
+ OptimalTempMax = 315 // Upper end for above
+ ExplodeTemp = 1050 // Temperature at which reaction explodes
+ OptimalpHMin = 8.5 // Lowest value of pH determining pH a 1 value for pH based rate reactions (Plateu phase)
+ OptimalpHMax = 9.5 // Higest value for above
+ ReactpHLim = 2 // How far out pH wil react, giving impurity place (Exponential phase)
+ CatalystFact = 0 // How much the catalyst affects the reaction (0 = no catalyst)
+ CurveSharpT = 1 // How sharp the temperature exponential curve is (to the power of value)
+ CurveSharppH = 2.5 // How sharp the pH exponential curve is (to the power of value)
+ ThermicConstant = 0.01 // Temperature change per 1u produced
+ HIonRelease = 0.015 // pH change per 1u reaction (inverse for some reason)
+ RateUpLim = 0.05 // Optimal/max rate possible if all conditions are perfect
+ FermiChem = TRUE // If the chemical uses the Fermichem reaction mechanics
+ PurityMin = 0
+
+/datum/chemical_reaction/synthtissue/FermiCreate(datum/reagents/holder, added_volume, added_purity)
+ var/datum/reagent/synthtissue/St = holder.has_reagent("synthtissue")
+ var/datum/reagent/N = holder.has_reagent("nutriment")
+ if(!St)
+ return
+ if(holder.chem_temp > 320)
+ var/temp_ratio = 1-(330 - holder.chem_temp)/10
+ holder.remove_reagent(src.id, added_volume*temp_ratio)
+ if(St.purity < 1)
+ St.volume *= St.purity
+ St.purity = 1
+ var/amount = CLAMP(0.002, 0, N.volume)
+ N.volume -= amount
+ St.data["grown_volume"] = St.data["grown_volume"] + added_volume
+ St.name = "[initial(St.name)] [round(St.data["grown_volume"], 0.1)]u colony"
+
/datum/chemical_reaction/styptic_powder
name = "Styptic Powder"
id = "styptic_powder"
@@ -245,6 +283,12 @@
results = list("regen_jelly" = 2)
required_reagents = list("tricordrazine" = 1, "slimejelly" = 1)
+/datum/chemical_reaction/jelly_convert
+ name = "Blood Jelly Conversion"
+ id = "blood_jelly"
+ results = list("slimejelly" = 1)
+ required_reagents = list("toxin" = 1, "jellyblood" = 1)
+
/datum/chemical_reaction/corazone
name = "Corazone"
id = "corazone"
diff --git a/code/modules/reagents/chemistry/recipes/others.dm b/code/modules/reagents/chemistry/recipes/others.dm
index b4e42aa973..eaae548d68 100644
--- a/code/modules/reagents/chemistry/recipes/others.dm
+++ b/code/modules/reagents/chemistry/recipes/others.dm
@@ -494,12 +494,6 @@
results = list("acetone" = 3)
required_reagents = list("oil" = 1, "welding_fuel" = 1, "oxygen" = 1)
-/datum/chemical_reaction/carpet
- name = "carpet"
- id = "carpet"
- results = list("carpet" = 2)
- required_reagents = list("space_drugs" = 1, "blood" = 1)
-
/datum/chemical_reaction/oil
name = "Oil"
id = "oil"
@@ -641,3 +635,77 @@
results = list("shadowmutationtoxin" = 1)
required_reagents = list("liquid_dark_matter" = 5, "synaptizine" = 10, "oculine" = 10, "stablemutationtoxin" = 1)
required_temp = 600
+
+// Liquid Carpets
+
+/datum/chemical_reaction/carpet
+ name = "carpet"
+ id = "carpet"
+ results = list("carpet" = 2)
+ required_reagents = list("space_drugs" = 1, "blood" = 1)
+
+/datum/chemical_reaction/carpet/black
+ name = "liquid black carpet"
+ id = "blackcarpet"
+ results = list("blackcarpet" = 2)
+ required_reagents = list("carpet" = 1, "carbon" = 1)
+
+/datum/chemical_reaction/carpet/blackred
+ name = "liquid red black carpet"
+ id = "blackredcarpet"
+ results = list("blackredcarpet" = 2)
+ required_reagents = list("carpet" = 1, "charcoal" = 1)
+
+/datum/chemical_reaction/carpet/monochrome
+ name = "liquid monochrome carpet"
+ id = "monochromecarpet"
+ results = list("monochromecarpet" = 2)
+ required_reagents = list("carpet" = 1, "oil" = 1)
+
+/datum/chemical_reaction/carpet/blue
+ name = "liquid blue carpet"
+ id = "bluecarpet"
+ results = list("bluecarpet" = 2)
+ required_reagents = list("carpet" = 1, "tonic" = 1)
+
+/datum/chemical_reaction/carpet/cyan
+ name = "liquid cyan carpet"
+ id = "cyancarpet"
+ results = list("cyancarpet" = 2)
+ required_reagents = list("carpet" = 1, "ice" = 1)
+
+/datum/chemical_reaction/carpet/green
+ name = "liquid green carpet"
+ id = "greencarpet"
+ results = list("greencarpet" = 2)
+ required_reagents = list("carpet" = 1, "sacid" = 1)
+
+/datum/chemical_reaction/carpet/orange
+ name = "liquid orange carpet"
+ id = "orangecarpet"
+ results = list("orangecarpet" = 2)
+ required_reagents = list("carpet" = 1, "orangejuice" = 1)
+
+/datum/chemical_reaction/carpet/purple
+ name = "liquid purple carpet"
+ id = "purplecarpet"
+ results = list("purplecarpet" = 2)
+ required_reagents = list("carpet" = 1, "stable_plasma" = 1)
+
+/datum/chemical_reaction/carpet/red
+ name = "liquid red carpet"
+ id = "redcarpet"
+ results = list("redcarpet" = 2)
+ required_reagents = list("carpet" = 1, "welding_fuel" = 1)
+
+/datum/chemical_reaction/carpet/royalblack
+ name = "liquid royal black carpet"
+ id = "royalblackcarpet"
+ results = list("royalblackcarpet" = 2)
+ required_reagents = list("carpet" = 1, "blackpepper" = 1)
+
+/datum/chemical_reaction/carpet/royalblue
+ name = "liquid royal blue carpet"
+ id = "royalbluecarpet"
+ results = list("royalbluecarpet" = 2)
+ required_reagents = list("carpet" = 1, "clonexadone" = 1)
diff --git a/code/modules/reagents/reagent_containers.dm b/code/modules/reagents/reagent_containers.dm
index b3f9591f64..d475b118b2 100644
--- a/code/modules/reagents/reagent_containers.dm
+++ b/code/modules/reagents/reagent_containers.dm
@@ -26,7 +26,7 @@
create_reagents(volume, reagent_flags)
if(spawned_disease)
var/datum/disease/F = new spawned_disease()
- var/list/data = list("viruses"= list(F))
+ var/list/data = list("blood_DNA" = "UNKNOWN DNA", "blood_type" = "SY","viruses"= list(F))
reagents.add_reagent("blood", disease_amount, data)
add_initial_reagents()
diff --git a/code/modules/reagents/reagent_containers/blood_pack.dm b/code/modules/reagents/reagent_containers/blood_pack.dm
index 3e555f385f..fe35981bfe 100644
--- a/code/modules/reagents/reagent_containers/blood_pack.dm
+++ b/code/modules/reagents/reagent_containers/blood_pack.dm
@@ -4,13 +4,16 @@
icon = 'icons/obj/bloodpack.dmi'
icon_state = "bloodpack"
volume = 200
+ reagent_flags = DRAINABLE
var/blood_type = null
var/labelled = 0
+ var/color_to_apply = "#FFFFFF"
+ var/mutable_appearance/fill_overlay
/obj/item/reagent_containers/blood/Initialize()
. = ..()
if(blood_type != null)
- reagents.add_reagent("blood", 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
+ reagents.add_reagent("blood", 200, list("donor"=null,"viruses"=null,"blood_DNA"=null,"blood_colour"=color, "blood_type"=blood_type,"resistances"=null,"trace_chem"=null))
update_icon()
/obj/item/reagent_containers/blood/on_reagent_change(changetype)
@@ -18,6 +21,7 @@
var/datum/reagent/blood/B = reagents.has_reagent("blood")
if(B && B.data && B.data["blood_type"])
blood_type = B.data["blood_type"]
+ color_to_apply = bloodtype_to_color(blood_type)
else
blood_type = null
update_pack_name()
@@ -45,7 +49,7 @@
/obj/item/reagent_containers/blood/random/Initialize()
icon_state = "bloodpack"
- blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L")
+ blood_type = pick("A+", "A-", "B+", "B-", "O+", "O-", "L", "SY", "HF", "GEL", "BUG")
return ..()
/obj/item/reagent_containers/blood/APlus
@@ -72,6 +76,18 @@
/obj/item/reagent_containers/blood/universal
blood_type = "U"
+/obj/item/reagent_containers/blood/synthetics
+ blood_type = "SY"
+
+/obj/item/reagent_containers/blood/oilblood
+ blood_type = "HF"
+
+/obj/item/reagent_containers/blood/jellyblood
+ blood_type = "GEL"
+
+/obj/item/reagent_containers/blood/insect
+ blood_type = "BUG"
+
/obj/item/reagent_containers/blood/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/pen) || istype(I, /obj/item/toy/crayon))
if(!user.is_literate())
diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm
index 249ed56d20..afe48ab3fb 100644
--- a/code/modules/reagents/reagent_containers/bottle.dm
+++ b/code/modules/reagents/reagent_containers/bottle.dm
@@ -404,3 +404,25 @@
/obj/item/reagent_containers/glass/bottle/bromine
name = "bromine bottle"
list_reagents = list("bromine" = 30)
+
+//Lewd Stuff
+
+/obj/item/reagent_containers/glass/bottle/crocin
+ name = "Crocin bottle"
+ desc = "A bottle of mild aphrodisiac. Increases libido."
+ list_reagents = list("aphro" = 30)
+
+/obj/item/reagent_containers/glass/bottle/hexacrocin
+ name = "Hexacrocin bottle"
+ desc = "A bottle of strong aphrodisiac. Increases libido."
+ list_reagents = list("aphro+" = 30)
+
+/obj/item/reagent_containers/glass/bottle/camphor
+ name = "Camphor bottle"
+ desc = "A bottle of mild anaphrodisiac. Reduces libido."
+ list_reagents = list("anaphro" = 30)
+
+/obj/item/reagent_containers/glass/bottle/hexacamphor
+ name = "Hexacamphor bottle"
+ desc = "A bottle of strong anaphrodisiac. Reduces libido."
+ list_reagents = list("anaphro+" = 30)
\ No newline at end of file
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 257106aaa7..3ed505c360 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -89,7 +89,7 @@
reagents.clear_reagents()
/obj/item/reagent_containers/glass/attackby(obj/item/I, mob/user, params)
- var/hotness = I.is_hot()
+ var/hotness = I.get_temperature()
if(hotness && reagents)
reagents.expose_temperature(hotness)
to_chat(user, "You heat [name] with [I]! ")
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index a96ba006c9..432b9289dd 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -196,3 +196,318 @@
volume = 250
list_reagents = list("holywater" = 150, "tiresolution" = 50, "dizzysolution" = 50)
amount_per_transfer_from_this = 50
+
+#define HYPO_SPRAY 0
+#define HYPO_INJECT 1
+
+#define WAIT_SPRAY 25
+#define WAIT_INJECT 25
+#define SELF_SPRAY 15
+#define SELF_INJECT 15
+
+#define DELUXE_WAIT_SPRAY 20
+#define DELUXE_WAIT_INJECT 20
+#define DELUXE_SELF_SPRAY 10
+#define DELUXE_SELF_INJECT 10
+
+#define COMBAT_WAIT_SPRAY 0
+#define COMBAT_WAIT_INJECT 0
+#define COMBAT_SELF_SPRAY 0
+#define COMBAT_SELF_INJECT 0
+
+//A vial-loaded hypospray. Cartridge-based!
+/obj/item/hypospray/mkii
+ name = "hypospray mk.II"
+ icon_state = "hypo2"
+ icon = 'icons/obj/syringe.dmi'
+ desc = "A new development from DeForest Medical, this hypospray takes 30-unit vials as the drug supply for easy swapping."
+ w_class = WEIGHT_CLASS_TINY
+ var/list/allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/tiny, /obj/item/reagent_containers/glass/bottle/vial/small)
+ var/mode = HYPO_INJECT
+ var/obj/item/reagent_containers/glass/bottle/vial/vial
+ var/start_vial = /obj/item/reagent_containers/glass/bottle/vial/small
+ var/spawnwithvial = TRUE
+ var/inject_wait = WAIT_INJECT
+ var/spray_wait = WAIT_SPRAY
+ var/spray_self = SELF_SPRAY
+ var/inject_self = SELF_INJECT
+ var/quickload = FALSE
+ var/penetrates = FALSE
+
+/obj/item/hypospray/mkii/brute
+ start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/bicaridine
+
+/obj/item/hypospray/mkii/toxin
+ start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/antitoxin
+
+/obj/item/hypospray/mkii/oxygen
+ start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/dexalin
+
+/obj/item/hypospray/mkii/burn
+ start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/kelotane
+
+/obj/item/hypospray/mkii/tricord
+ start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/tricord
+
+/obj/item/hypospray/mkii/enlarge
+ spawnwithvial = FALSE
+
+/obj/item/hypospray/mkii/CMO
+ name = "hypospray mk.II deluxe"
+ allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/tiny, /obj/item/reagent_containers/glass/bottle/vial/small, /obj/item/reagent_containers/glass/bottle/vial/large)
+ icon_state = "cmo2"
+ desc = "The Deluxe Hypospray can take larger-size vials. It also acts faster and delivers more reagents per spray."
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
+ start_vial = /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/CMO
+ inject_wait = DELUXE_WAIT_INJECT
+ spray_wait = DELUXE_WAIT_SPRAY
+ spray_self = DELUXE_SELF_SPRAY
+ inject_self = DELUXE_SELF_INJECT
+
+/obj/item/hypospray/mkii/CMO/combat
+ name = "combat hypospray mk.II"
+ desc = "A combat-ready deluxe hypospray that acts almost instantly. It can be tactically reloaded by using a vial on it."
+ icon_state = "combat2"
+ start_vial = /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/combat
+ inject_wait = COMBAT_WAIT_INJECT
+ spray_wait = COMBAT_WAIT_SPRAY
+ spray_self = COMBAT_SELF_SPRAY
+ inject_self = COMBAT_SELF_INJECT
+ quickload = TRUE
+ penetrates = TRUE
+
+/obj/item/hypospray/mkii/Initialize()
+ . = ..()
+ if(!spawnwithvial)
+ update_icon()
+ return
+ if(start_vial)
+ vial = new start_vial
+ update_icon()
+
+/obj/item/hypospray/mkii/update_icon()
+ ..()
+ icon_state = "[initial(icon_state)][vial ? "" : "-e"]"
+ if(ismob(loc))
+ var/mob/M = loc
+ M.update_inv_hands()
+ return
+
+/obj/item/hypospray/mkii/examine(mob/user)
+ . = ..()
+ if(vial)
+ to_chat(user, "[vial] has [vial.reagents.total_volume]u remaining.")
+ else
+ to_chat(user, "It has no vial loaded in.")
+ to_chat(user, "[src] is set to [mode ? "Inject" : "Spray"] contents on application.")
+
+/obj/item/hypospray/mkii/proc/unload_hypo(obj/item/I, mob/user)
+ if((istype(I, /obj/item/reagent_containers/glass/bottle/vial)))
+ var/obj/item/reagent_containers/glass/bottle/vial/V = I
+ V.forceMove(user.loc)
+ user.put_in_hands(V)
+ to_chat(user, "You remove [vial] from [src]. ")
+ vial = null
+ update_icon()
+ playsound(loc, 'sound/weapons/empty.ogg', 50, 1)
+ else
+ to_chat(user, "This hypo isn't loaded! ")
+ return
+
+/obj/item/hypospray/mkii/attackby(obj/item/I, mob/living/user)
+ if((istype(I, /obj/item/reagent_containers/glass/bottle/vial) && vial != null))
+ if(!quickload)
+ to_chat(user, "[src] can not hold more than one vial! ")
+ return FALSE
+ unload_hypo(vial, user)
+ if((istype(I, /obj/item/reagent_containers/glass/bottle/vial)))
+ var/obj/item/reagent_containers/glass/bottle/vial/V = I
+ if(!is_type_in_list(V, allowed_containers))
+ to_chat(user, "[src] doesn't accept this type of vial. ")
+ return FALSE
+ if(!user.transferItemToLoc(V,src))
+ return FALSE
+ vial = V
+ user.visible_message("[user] has loaded a vial into [src]. ","You have loaded [vial] into [src]. ")
+ update_icon()
+ playsound(loc, 'sound/weapons/autoguninsert.ogg', 35, 1)
+ return TRUE
+ else
+ to_chat(user, "This doesn't fit in [src]. ")
+ return FALSE
+ return FALSE
+
+/obj/item/hypospray/mkii/AltClick(mob/user)
+ if(vial)
+ vial.attack_self(user)
+
+// Gunna allow this for now, still really don't approve - Pooj
+/obj/item/hypospray/mkii/emag_act(mob/user)
+ . = ..()
+ if(obj_flags & EMAGGED)
+ to_chat(user, "[src] happens to be already overcharged.")
+ return
+ inject_wait = COMBAT_WAIT_INJECT
+ spray_wait = COMBAT_WAIT_SPRAY
+ spray_self = COMBAT_SELF_INJECT
+ inject_self = COMBAT_SELF_SPRAY
+ penetrates = TRUE
+ to_chat(user, "You overcharge [src]'s control circuit.")
+ obj_flags |= EMAGGED
+ return TRUE
+
+/obj/item/hypospray/mkii/attack_hand(mob/user)
+ . = ..() //Don't bother changing this or removing it from containers will break.
+
+/obj/item/hypospray/mkii/attack(obj/item/I, mob/user, params)
+ return
+
+/obj/item/hypospray/mkii/afterattack(atom/target, mob/user, proximity)
+ if(!vial)
+ return
+
+ if(!proximity)
+ return
+
+ if(!ismob(target))
+ return
+
+ var/mob/living/L
+ if(isliving(target))
+ L = target
+ if(!penetrates && !L.can_inject(user, 1)) //This check appears another four times, since otherwise the penetrating sprays will break in do_mob.
+ return
+
+ if(!L && !target.is_injectable()) //only checks on non-living mobs, due to how can_inject() handles
+ to_chat(user, "You cannot directly fill [target]! ")
+ return
+
+ if(target.reagents.total_volume >= target.reagents.maximum_volume)
+ to_chat(user, "[target] is full. ")
+ return
+
+ if(ishuman(L))
+ var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected))
+ if(!affecting)
+ to_chat(user, "The limb is missing! ")
+ return
+ if(affecting.status != BODYPART_ORGANIC)
+ to_chat(user, "Medicine won't work on a robotic limb! ")
+ return
+
+ var/contained = vial.reagents.log_list()
+ log_combat(user, L, "attemped to inject", src, addition="which had [contained]")
+//Always log attemped injections for admins
+ if(vial != null)
+ switch(mode)
+ if(HYPO_INJECT)
+ if(L) //living mob
+ if(L != user)
+ L.visible_message("[user] is trying to inject [L] with [src]! ", \
+ "[user] is trying to inject [L] with [src]! ")
+ if(!do_mob(user, L, inject_wait))
+ return
+ if(!penetrates && !L.can_inject(user, 1))
+ return
+ if(!vial.reagents.total_volume)
+ return
+ if(L.reagents.total_volume >= L.reagents.maximum_volume)
+ return
+ L.visible_message("[user] uses the [src] on [L]! ", \
+ "[user] uses the [src] on [L]! ")
+ else
+ if(!do_mob(user, L, inject_self))
+ return
+ if(!penetrates && !L.can_inject(user, 1))
+ return
+ if(!vial.reagents.total_volume)
+ return
+ if(L.reagents.total_volume >= L.reagents.maximum_volume)
+ return
+ log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode]) ")
+ L.log_message("applied [src] to themselves ([contained]). ", INDIVIDUAL_ATTACK_LOG)
+
+ var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1)
+ vial.reagents.reaction(L, INJECT, fraction)
+ vial.reagents.trans_to(target, vial.amount_per_transfer_from_this)
+ if(vial.amount_per_transfer_from_this >= 15)
+ playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1)
+ if(vial.amount_per_transfer_from_this < 15)
+ playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1)
+ to_chat(user, "You inject [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units. ")
+
+ if(HYPO_SPRAY)
+ if(L) //living mob
+ if(L != user)
+ L.visible_message("[user] is trying to spray [L] with [src]! ", \
+ "[user] is trying to spray [L] with [src]! ")
+ if(!do_mob(user, L, spray_wait))
+ return
+ if(!penetrates && !L.can_inject(user, 1))
+ return
+ if(!vial.reagents.total_volume)
+ return
+ if(L.reagents.total_volume >= L.reagents.maximum_volume)
+ return
+ L.visible_message("[user] uses the [src] on [L]! ", \
+ "[user] uses the [src] on [L]! ")
+ else
+ if(!do_mob(user, L, spray_self))
+ return
+ if(!penetrates && !L.can_inject(user, 1))
+ return
+ if(!vial.reagents.total_volume)
+ return
+ if(L.reagents.total_volume >= L.reagents.maximum_volume)
+ return
+ log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode]) ")
+ L.log_message("applied [src] to themselves ([contained]). ", INDIVIDUAL_ATTACK_LOG)
+ var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1)
+ vial.reagents.reaction(L, PATCH, fraction)
+ vial.reagents.trans_to(target, vial.amount_per_transfer_from_this)
+ if(vial.amount_per_transfer_from_this >= 15)
+ playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1)
+ if(vial.amount_per_transfer_from_this < 15)
+ playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1)
+ to_chat(user, "You spray [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units. ")
+ else
+ to_chat(user, "[src] doesn't work here! ")
+ return
+
+/obj/item/hypospray/mkii/attack_self(mob/living/user)
+ if(user)
+ if(user.incapacitated())
+ return
+ else if(!vial)
+ to_chat(user, "This Hypo needs to be loaded first!")
+ return
+ else
+ unload_hypo(vial,user)
+
+/obj/item/hypospray/mkii/verb/modes()
+ set name = "Toggle Application Mode"
+ set category = "Object"
+ set src in usr
+ var/mob/M = usr
+ switch(mode)
+ if(HYPO_SPRAY)
+ mode = HYPO_INJECT
+ to_chat(M, "[src] is now set to inject contents on application.")
+ if(HYPO_INJECT)
+ mode = HYPO_SPRAY
+ to_chat(M, "[src] is now set to spray contents on application.")
+
+#undef HYPO_SPRAY
+#undef HYPO_INJECT
+#undef WAIT_SPRAY
+#undef WAIT_INJECT
+#undef SELF_SPRAY
+#undef SELF_INJECT
+#undef DELUXE_WAIT_SPRAY
+#undef DELUXE_WAIT_INJECT
+#undef DELUXE_SELF_SPRAY
+#undef DELUXE_SELF_INJECT
+#undef COMBAT_WAIT_SPRAY
+#undef COMBAT_WAIT_INJECT
+#undef COMBAT_SELF_SPRAY
+#undef COMBAT_SELF_INJECT
diff --git a/modular_citadel/code/modules/reagents/reagent container/hypovial.dm b/code/modules/reagents/reagent_containers/hypovial.dm
old mode 100755
new mode 100644
similarity index 96%
rename from modular_citadel/code/modules/reagents/reagent container/hypovial.dm
rename to code/modules/reagents/reagent_containers/hypovial.dm
index c1e0d6ff01..ba5ce48a4a
--- a/modular_citadel/code/modules/reagents/reagent container/hypovial.dm
+++ b/code/modules/reagents/reagent_containers/hypovial.dm
@@ -1,7 +1,8 @@
+//hypovials used with the MkII hypospray. See hypospray.dm.
+
/obj/item/reagent_containers/glass/bottle/vial
name = "broken hypovial"
desc = "A hypovial compatible with most hyposprays."
- icon = 'modular_citadel/icons/obj/vial.dmi'
icon_state = "hypovial"
spillable = FALSE
var/comes_with = list() //Easy way of doing this.
@@ -34,7 +35,7 @@
/obj/item/reagent_containers/glass/bottle/vial/update_icon()
cut_overlays()
if(reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('modular_citadel/icons/obj/vial.dmi', "hypovial10")
+ var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "hypovial10")
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
@@ -86,7 +87,7 @@
/obj/item/reagent_containers/glass/bottle/vial/large/update_icon()
cut_overlays()
if(reagents.total_volume)
- var/mutable_appearance/filling = mutable_appearance('modular_citadel/icons/obj/vial.dmi', "hypoviallarge10")
+ var/mutable_appearance/filling = mutable_appearance('icons/obj/reagentfillings.dmi', "hypoviallarge10")
var/percent = round((reagents.total_volume / volume) * 100)
switch(percent)
diff --git a/code/modules/reagents/reagent_containers/medspray.dm b/code/modules/reagents/reagent_containers/medspray.dm
index 54a38eef86..df7c7af225 100644
--- a/code/modules/reagents/reagent_containers/medspray.dm
+++ b/code/modules/reagents/reagent_containers/medspray.dm
@@ -19,8 +19,8 @@
var/can_fill_from_container = TRUE
var/apply_type = PATCH
var/apply_method = "spray"
- var/self_delay = 30
- var/squirt_mode = 0
+ var/self_delay = 3 SECONDS
+ var/squirt_mode = FALSE
var/squirt_amount = 5
/obj/item/reagent_containers/medspray/attack_self(mob/user)
@@ -31,40 +31,51 @@
amount_per_transfer_from_this = initial(amount_per_transfer_from_this)
to_chat(user, "You will now apply the medspray's contents in [squirt_mode ? "short bursts":"extended sprays"]. You'll now use [amount_per_transfer_from_this] units per use. ")
-/obj/item/reagent_containers/medspray/attack(mob/M, mob/user, def_zone)
+/obj/item/reagent_containers/medspray/attack(mob/living/L, mob/user, def_zone)
if(!reagents || !reagents.total_volume)
to_chat(user, "[src] is empty! ")
return
- if(M == user)
- M.visible_message("[user] attempts to [apply_method] [src] on [user.p_them()]self. ")
+ if(ishuman(L))
+ var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected))
+ if(!affecting)
+ to_chat(user, "The limb is missing! ")
+ return
+ if(!L.can_inject(user, TRUE, user.zone_selected, FALSE, TRUE)) //stopped by clothing, like patches
+ return
+ if(affecting.status != BODYPART_ORGANIC)
+ to_chat(user, "Medicine won't work on a robotic limb! ")
+ return
+
+ if(L == user)
+ L.visible_message("[user] attempts to [apply_method] [src] on [user.p_them()]self. ")
if(self_delay)
- if(!do_mob(user, M, self_delay))
+ if(!do_mob(user, L, self_delay))
return
if(!reagents || !reagents.total_volume)
return
- to_chat(M, "You [apply_method] yourself with [src]. ")
+ to_chat(L, "You [apply_method] yourself with [src]. ")
else
- log_combat(user, M, "attempted to apply", src, reagents.log_list())
- M.visible_message("[user] attempts to [apply_method] [src] on [M]. ", \
- "[user] attempts to [apply_method] [src] on [M]. ")
- if(!do_mob(user, M))
+ log_combat(user, L, "attempted to apply", src, reagents.log_list())
+ L.visible_message("[user] attempts to [apply_method] [src] on [L]. ", \
+ "[user] attempts to [apply_method] [src] on [L]. ")
+ if(!do_mob(user, L))
return
if(!reagents || !reagents.total_volume)
return
- M.visible_message("[user] [apply_method]s [M] down with [src]. ", \
- "[user] [apply_method]s [M] down with [src]. ")
+ L.visible_message("[user] [apply_method]s [L] down with [src]. ", \
+ "[user] [apply_method]s [L] down with [src]. ")
if(!reagents || !reagents.total_volume)
return
else
- log_combat(user, M, "applied", src, reagents.log_list())
+ log_combat(user, L, "applied", src, reagents.log_list())
playsound(src, 'sound/effects/spray2.ogg', 50, 1, -6)
var/fraction = min(amount_per_transfer_from_this/reagents.total_volume, 1)
- reagents.reaction(M, apply_type, fraction)
- reagents.trans_to(M, amount_per_transfer_from_this)
+ reagents.reaction(L, apply_type, fraction)
+ reagents.trans_to(L, amount_per_transfer_from_this)
return
/obj/item/reagent_containers/medspray/styptic
diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm
index 38880f669f..d4880aa085 100644
--- a/code/modules/reagents/reagent_containers/pill.dm
+++ b/code/modules/reagents/reagent_containers/pill.dm
@@ -186,7 +186,6 @@
/obj/item/reagent_containers/pill/antirad_plus
name = "prussian blue pill"
desc = "Used to treat heavy radition poisoning."
- icon = 'modular_citadel/icons/obj/modularpills.dmi'
icon_state = "prussian_blue"
list_reagents = list("prussian_blue" = 25, "water" = 10)
roundstart = 1
@@ -194,7 +193,6 @@
/obj/item/reagent_containers/pill/mutarad
name = "radiation treatment deluxe pill"
desc = "Used to treat heavy radition poisoning and genetic defects."
- icon = 'modular_citadel/icons/obj/modularpills.dmi'
icon_state = "anit_rad_fixgene"
list_reagents = list("prussian_blue" = 15, "potass_iodide" = 15, "mutadone" = 15, "water" = 5)
roundstart = 1
diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm
index d2e3f95bdc..424d7b9ed0 100644
--- a/code/modules/reagents/reagent_containers/spray.dm
+++ b/code/modules/reagents/reagent_containers/spray.dm
@@ -125,7 +125,7 @@
to_chat(user, "You switch the nozzle setting to [stream_mode ? "\"stream\"":"\"spray\""]. You'll now use [amount_per_transfer_from_this] units per use. ")
/obj/item/reagent_containers/spray/attackby(obj/item/I, mob/user, params)
- var/hotness = I.is_hot()
+ var/hotness = I.get_temperature()
if(hotness && reagents)
reagents.expose_temperature(hotness)
to_chat(user, "You heat [name] with [I]! ")
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index cc83eb28f6..6bdae6225a 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -104,7 +104,7 @@
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this) // transfer from, transfer to - who cares?
to_chat(user, "You fill [src] with [trans] units of the solution. It now contains [reagents.total_volume] units. ")
- if (reagents.total_volume >= reagents.maximum_volume)
+ if (round(reagents.total_volume, 0.1) >= reagents.maximum_volume)
mode=!mode
update_icon()
@@ -307,7 +307,7 @@
var/trans = target.reagents.trans_to(src, amount_per_transfer_from_this)
to_chat(user, "You soak the [src] with [trans] units of the solution. It now contains [reagents.total_volume] units. ")
- if (reagents.total_volume >= reagents.maximum_volume)
+ if (round(reagents.total_volume,1) >= reagents.maximum_volume)
mode=!mode
update_icon()
@@ -323,8 +323,9 @@
rounded_vol = "empty"
if(reagents && reagents.total_volume)
- if(volume/reagents.total_volume == 1)
+ if(volume/round(reagents.total_volume, 1) == 1)
rounded_vol="full"
+ mode = SYRINGE_INJECT
icon_state = "[rounded_vol]"
item_state = "syringe_[rounded_vol]"
diff --git a/code/modules/reagents/reagent_dispenser.dm b/code/modules/reagents/reagent_dispenser.dm
index 19afab2e6e..216ecd9654 100644
--- a/code/modules/reagents/reagent_dispenser.dm
+++ b/code/modules/reagents/reagent_dispenser.dm
@@ -39,6 +39,10 @@
else
qdel(src)
+///////////////
+//Water Tanks//
+///////////////
+
/obj/structure/reagent_dispensers/watertank
name = "water tank"
desc = "A water tank."
@@ -57,12 +61,52 @@
reagent_id = "firefighting_foam"
tank_volume = 500
+/obj/structure/reagent_dispensers/water_cooler
+ name = "liquid cooler"
+ desc = "A machine that dispenses liquid to drink."
+ icon = 'icons/obj/vending.dmi'
+ icon_state = "water_cooler"
+ anchored = TRUE
+ tank_volume = 500
+ var/paper_cups = 25 //Paper cups left from the cooler
+
+/obj/structure/reagent_dispensers/water_cooler/examine(mob/user)
+ ..()
+ if (paper_cups > 1)
+ to_chat(user, "There are [paper_cups] paper cups left.")
+ else if (paper_cups == 1)
+ to_chat(user, "There is one paper cup left.")
+ else
+ to_chat(user, "There are no paper cups left.")
+
+/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user)
+ . = ..()
+ if(.)
+ return
+ if(!paper_cups)
+ to_chat(user, "There aren't any cups left! ")
+ return
+ user.visible_message("[user] takes a cup from [src]. ", "You take a paper cup from [src]. ")
+ var/obj/item/reagent_containers/food/drinks/sillycup/S = new(get_turf(src))
+ user.put_in_hands(S)
+ paper_cups--
+
+//////////////
+//Fuel Tanks//
+//////////////
+
/obj/structure/reagent_dispensers/fueltank
name = "fuel tank"
desc = "A tank full of industrial welding fuel. Do not consume."
icon_state = "fuel"
reagent_id = "welding_fuel"
+/obj/structure/reagent_dispensers/fueltank/high //Unused - Good for ghost roles
+ name = "high-capacity fuel tank"
+ desc = "A now illegal tank, full of highly pressurized industrial welding fuel. Do not consume or have a open flame close to this tank."
+ icon_state = "fuel_high"
+ tank_volume = 3000
+
/obj/structure/reagent_dispensers/fueltank/boom()
explosion(get_turf(src), 0, 1, 5, flame_range = 5)
qdel(src)
@@ -117,6 +161,9 @@
return
return ..()
+///////////////////
+//Misc Dispenders//
+///////////////////
/obj/structure/reagent_dispensers/peppertank
name = "pepper spray refiller"
@@ -131,36 +178,24 @@
if(prob(1))
desc = "IT'S PEPPER TIME, BITCH!"
-
-/obj/structure/reagent_dispensers/water_cooler
- name = "liquid cooler"
- desc = "A machine that dispenses liquid to drink."
- icon = 'icons/obj/vending.dmi'
- icon_state = "water_cooler"
+/obj/structure/reagent_dispensers/virusfood
+ name = "virus food dispenser"
+ desc = "A dispenser of low-potency virus mutagenic."
+ icon_state = "virus_food"
anchored = TRUE
- tank_volume = 500
- var/paper_cups = 25 //Paper cups left from the cooler
+ density = FALSE
+ reagent_id = "virusfood"
-/obj/structure/reagent_dispensers/water_cooler/examine(mob/user)
- ..()
- if (paper_cups > 1)
- to_chat(user, "There are [paper_cups] paper cups left.")
- else if (paper_cups == 1)
- to_chat(user, "There is one paper cup left.")
- else
- to_chat(user, "There are no paper cups left.")
+/obj/structure/reagent_dispensers/cooking_oil
+ name = "vat of cooking oil"
+ desc = "A huge metal vat with a tap on the front. Filled with cooking oil for use in frying food."
+ icon_state = "vat"
+ anchored = TRUE
+ reagent_id = "cooking_oil"
-/obj/structure/reagent_dispensers/water_cooler/attack_hand(mob/living/user)
- . = ..()
- if(.)
- return
- if(!paper_cups)
- to_chat(user, "There aren't any cups left! ")
- return
- user.visible_message("[user] takes a cup from [src]. ", "You take a paper cup from [src]. ")
- var/obj/item/reagent_containers/food/drinks/sillycup/S = new(get_turf(src))
- user.put_in_hands(S)
- paper_cups--
+////////
+//Kegs//
+////////
/obj/structure/reagent_dispensers/beerkeg
name = "beer keg"
@@ -173,19 +208,44 @@
if(!QDELETED(src))
qdel(src)
+/obj/structure/reagent_dispensers/keg
+ name = "keg"
+ desc = "A keg."
+ icon = 'modular_citadel/icons/obj/objects.dmi'
+ icon_state = "keg"
+ reagent_id = "water"
-/obj/structure/reagent_dispensers/virusfood
- name = "virus food dispenser"
- desc = "A dispenser of low-potency virus mutagenic."
- icon_state = "virus_food"
- anchored = TRUE
- density = FALSE
- reagent_id = "virusfood"
+/obj/structure/reagent_dispensers/keg/mead
+ name = "keg of mead"
+ desc = "A keg of mead."
+ icon_state = "orangekeg"
+ reagent_id = "mead"
+/obj/structure/reagent_dispensers/keg/aphro
+ name = "keg of aphrodisiac"
+ desc = "A keg of aphrodisiac."
+ icon_state = "pinkkeg"
+ reagent_id = "aphro"
-/obj/structure/reagent_dispensers/cooking_oil
- name = "vat of cooking oil"
- desc = "A huge metal vat with a tap on the front. Filled with cooking oil for use in frying food."
- icon_state = "vat"
- anchored = TRUE
- reagent_id = "cooking_oil"
+/obj/structure/reagent_dispensers/keg/aphro/strong
+ name = "keg of strong aphrodisiac"
+ desc = "A keg of strong and addictive aphrodisiac."
+ reagent_id = "aphro+"
+
+/obj/structure/reagent_dispensers/keg/milk
+ name = "keg of milk"
+ desc = "It's not quite what you were hoping for."
+ icon_state = "whitekeg"
+ reagent_id = "milk"
+
+/obj/structure/reagent_dispensers/keg/semen
+ name = "keg of semen"
+ desc = "Dear lord, where did this even come from?"
+ icon_state = "whitekeg"
+ reagent_id = "semen"
+
+/obj/structure/reagent_dispensers/keg/gargle
+ name = "keg of pan galactic gargleblaster"
+ desc = "A keg of... wow that's a long name."
+ icon_state = "bluekeg"
+ reagent_id = "gargleblaster"
\ No newline at end of file
diff --git a/code/modules/recycling/disposal/bin.dm b/code/modules/recycling/disposal/bin.dm
index 082b1a7d11..5edddd64c2 100644
--- a/code/modules/recycling/disposal/bin.dm
+++ b/code/modules/recycling/disposal/bin.dm
@@ -111,14 +111,7 @@
stuff_mob_in(target, user)
/obj/machinery/disposal/proc/stuff_mob_in(mob/living/target, mob/living/user)
- if(!iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
- return
- if(!isturf(user.loc)) //No magically doing it from inside closets
- return
- if(target.buckled || target.has_buckled_mobs())
- return
- if(target.mob_size > MOB_SIZE_HUMAN)
- to_chat(user, "[target] doesn't fit inside [src]! ")
+ if(!can_stuff_mob_in(target, user))
return
add_fingerprint(user)
if(user == target)
@@ -137,6 +130,19 @@
target.LAssailant = user
update_icon()
+/obj/machinery/disposal/proc/can_stuff_mob_in(mob/living/target, mob/living/user, pushing = FALSE)
+ if(!pushing && !iscarbon(user) && !user.ventcrawler) //only carbon and ventcrawlers can climb into disposal by themselves.
+ return FALSE
+ if(!isturf(user.loc)) //No magically doing it from inside closets
+ return FALSE
+ if(target.buckled || target.has_buckled_mobs())
+ return FALSE
+ if(target.mob_size > MOB_SIZE_HUMAN)
+ if(!pushing)
+ to_chat(user, "[target] doesn't fit inside [src]! ")
+ return FALSE
+ return TRUE
+
/obj/machinery/disposal/relaymove(mob/user)
attempt_escape(user)
@@ -265,6 +271,7 @@
desc = "A pneumatic waste disposal unit."
icon_state = "disposal"
var/datum/oracle_ui/themed/nano/ui
+ obj_flags = CAN_BE_HIT | USES_TGUI | SHOVABLE_ONTO
/obj/machinery/disposal/bin/Initialize(mapload, obj/structure/disposalconstruct/make_from)
. = ..()
@@ -276,7 +283,7 @@
/obj/machinery/disposal/bin/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/storage/bag/trash)) //Not doing component overrides because this is a specific type.
var/obj/item/storage/bag/trash/T = I
- GET_COMPONENT_FROM(STR, /datum/component/storage, T)
+ var/datum/component/storage/STR = T.GetComponent(/datum/component/storage)
to_chat(user, "You empty the bag. ")
for(var/obj/item/O in T.contents)
STR.remove_from_storage(O,src)
@@ -305,7 +312,7 @@
if(Adjacent(user))
return TRUE
return ..()
-
+
/obj/machinery/disposal/bin/oui_data(mob/user)
var/list/data = list()
@@ -360,6 +367,17 @@
else
return ..()
+/obj/machinery/disposal/bin/shove_act(mob/living/target, mob/living/user)
+ if(!can_stuff_mob_in(target, user, TRUE))
+ return FALSE
+ target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
+ target.forceMove(src)
+ user.visible_message("[user.name] shoves [target.name] into \the [src]! ",
+ "You shove [target.name] into \the [src]! ", null, COMBAT_MESSAGE_RANGE)
+ log_combat(user, target, "shoved", "into [src] (disposal bin)")
+ return TRUE
+
+
/obj/machinery/disposal/bin/flush()
..()
full_pressure = FALSE
diff --git a/code/modules/recycling/disposal/construction.dm b/code/modules/recycling/disposal/construction.dm
index 624d5e0e05..348e687e03 100644
--- a/code/modules/recycling/disposal/construction.dm
+++ b/code/modules/recycling/disposal/construction.dm
@@ -29,7 +29,7 @@
pipename = initial(pipe_type.name)
if(flip)
- GET_COMPONENT(rotcomp,/datum/component/simple_rotation)
+ var/datum/component/simple_rotation/rotcomp = GetComponent(/datum/component/simple_rotation)
rotcomp.BaseRot(null,ROTATION_FLIP)
update_icon()
diff --git a/code/modules/research/designs/electronics_designs.dm b/code/modules/research/designs/electronics_designs.dm
index 552976824d..818e80beea 100644
--- a/code/modules/research/designs/electronics_designs.dm
+++ b/code/modules/research/designs/electronics_designs.dm
@@ -131,3 +131,30 @@
category = list("Misc")
departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
+/datum/design/xenobio_upgrade
+ name = "owo"
+ desc = "someone's bussin"
+ build_type = PROTOLATHE
+ materials = list(MAT_METAL = 300, MAT_GLASS = 100)
+ category = list("Electronics")
+ departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
+
+/datum/design/xenobio_upgrade/xenobiomonkeys
+ name = "Xenobiology console monkey upgrade disk"
+ desc = "This disk will add the ability to remotely recycle monkeys via the Xenobiology console."
+ id = "xenobio_monkeys"
+ build_path = /obj/item/disk/xenobio_console_upgrade/monkey
+
+/datum/design/xenobio_upgrade/xenobioslimebasic
+ name = "Xenobiology console basic slime upgrade disk"
+ desc = "This disk will add the ability to remotely manipulate slimes via the Xenobiology console."
+ id = "xenobio_slimebasic"
+ build_path = /obj/item/disk/xenobio_console_upgrade/slimebasic
+
+/datum/design/xenobio_upgrade/xenobioslimeadv
+ name = "Xenobiology console advanced slime upgrade disk"
+ desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
+ id = "xenobio_slimeadv"
+ build_path = /obj/item/disk/xenobio_console_upgrade/slimeadv
+
+
diff --git a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
index 31723cde07..b4d67315ba 100644
--- a/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
+++ b/code/modules/research/designs/machine_desings/machine_designs_all_misc.dm
@@ -98,3 +98,11 @@
build_path = /obj/item/circuitboard/machine/vr_sleeper
departmental_flags = DEPARTMENTAL_FLAG_ALL
category = list ("Medical Machinery")
+
+/datum/design/board/autoylathe
+ name = "Machine Design (Autoylathe)"
+ desc = "The circuit board for an autoylathe."
+ id = "autoylathe"
+ build_path = /obj/item/circuitboard/machine/autoylathe
+ departmental_flags = DEPARTMENTAL_FLAG_ALL
+ category = list("Misc. Machinery")
diff --git a/code/modules/research/designs/machine_desings/machine_designs_medical.dm b/code/modules/research/designs/machine_desings/machine_designs_medical.dm
index 65b3d74f71..2f95954e01 100644
--- a/code/modules/research/designs/machine_desings/machine_designs_medical.dm
+++ b/code/modules/research/designs/machine_desings/machine_designs_medical.dm
@@ -89,3 +89,11 @@
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_ENGINEERING
build_path = /obj/item/circuitboard/machine/clonescanner
category = list("Medical Machinery")
+
+/datum/design/board/bloodbankgen
+ name = "Machine Design (Blood Bank Generator Board)"
+ desc = "The circuit board for a blood bank generator."
+ id = "bloodbankgen"
+ build_path = /obj/item/circuitboard/machine/bloodbankgen
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+ category = list ("Medical Machinery")
diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm
index 301d2de279..e70362553c 100644
--- a/code/modules/research/designs/medical_designs.dm
+++ b/code/modules/research/designs/medical_designs.dm
@@ -534,6 +534,17 @@
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+/datum/design/cybernetic_heart_u
+ name = "Upgraded Cybernetic Heart"
+ desc = "An upgraded cybernetic heart"
+ id = "cybernetic_heart_u"
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 50
+ materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500)
+ build_path = /obj/item/organ/heart/cybernetic/upgraded
+ category = list("Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+
/datum/design/cybernetic_liver_u
name = "Upgraded Cybernetic Liver"
desc = "An upgraded cybernetic liver"
@@ -590,63 +601,34 @@
/datum/design/retractor_adv
name = "Advanced Retractor"
- desc = "A high-class, premium retractor, featuring precision crafted, silver-plated hook-ends and an electrum handle."
+ desc = "An almagation of rods and gears, able to function as both a surgical clamp and retractor. "
id = "retractor_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 1500, MAT_GOLD = 1000)
- build_path = /obj/item/retractor/adv
- category = list("Medical Designs")
- departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
-
-/datum/design/hemostat_adv
- name = "Advanced Hemostat"
- desc = "An exceptionally fine pair of arterial forceps. These appear to be plated in electrum and feel soft to the touch."
- id = "hemostat_adv"
- build_type = PROTOLATHE
- materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 1000, MAT_GOLD = 1500)
- build_path = /obj/item/hemostat/adv
- category = list("Medical Designs")
- departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
-
-/datum/design/cautery_adv
- name = "Electrocautery" //This is based on real-life science.
- desc = "A high-tech unipolar Electrocauter. This tiny device contains an extremely powerful microbattery that uses arcs of electricity to painlessly sear wounds shut. It seems to recharge with the user's body-heat. Wow!"
- id = "cautery_adv"
- build_type = PROTOLATHE
- materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 1000, MAT_GOLD = 1500)
- build_path = /obj/item/cautery/adv
+ build_path = /obj/item/retractor/advanced
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/surgicaldrill_adv
- name = "Surgical Autodrill"
- desc = "With a diamond tip and built-in depth and safety sensors, this drill alerts the user before overpenetrating a patient's skull or tooth. There also appears to be a disable switch."
+ name = "Surgical Laser Drill"
+ desc = "It projects a high power laser used for medical applications."
id = "surgicaldrill_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 2500, MAT_GLASS = 2500, MAT_SILVER = 6000, MAT_GOLD = 5500, MAT_DIAMOND = 3500)
- build_path = /obj/item/surgicaldrill/adv
+ build_path = /obj/item/surgicaldrill/advanced
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/scalpel_adv
- name = "Precision Scalpel"
- desc = "A perfectly balanced electrum scalpel with a silicon-coated edge to eliminate wear and tear."
+ name = "Laser Scalpel"
+ desc = "An advanced scalpel which uses laser technology to cut."
id = "scalpel_adv"
build_type = PROTOLATHE
materials = list(MAT_METAL = 1500, MAT_GLASS = 1500, MAT_SILVER = 4000, MAT_GOLD = 2500)
- build_path = /obj/item/scalpel/adv
+ build_path = /obj/item/scalpel/advanced
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
-/datum/design/circular_saw_adv
- name = "Diamond-Grit Circular Saw"
- desc = "For those Assistants with REALLY thick skulls."
- id = "circular_saw_adv"
- build_type = PROTOLATHE
- materials = list(MAT_METAL = 7500, MAT_GLASS = 6000, MAT_SILVER = 6500, MAT_GOLD = 7500, MAT_DIAMOND = 4500)
- build_path = /obj/item/circular_saw/adv
- category = list("Medical Designs")
- departmental_flags = DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/////////////////////////////////////////
//////////Alien Surgery Tools////////////
@@ -712,6 +694,28 @@
category = list("Medical Designs")
departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+/datum/design/cybernetic_ears
+ name = "Cybernetic Ears"
+ desc = "A pair of cybernetic ears."
+ id = "cybernetic_ears"
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 30
+ materials = list(MAT_METAL = 250, MAT_GLASS = 400)
+ build_path = /obj/item/organ/ears/cybernetic
+ category = list("Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+
+/datum/design/cybernetic_ears_u
+ name = "Upgraded Cybernetic Ears"
+ desc = "A pair of upgraded cybernetic ears."
+ id = "cybernetic_ears_u"
+ build_type = PROTOLATHE | MECHFAB
+ construction_time = 40
+ materials = list(MAT_METAL = 500, MAT_GLASS = 500, MAT_SILVER = 500)
+ build_path = /obj/item/organ/ears/cybernetic/upgraded
+ category = list("Misc", "Medical Designs")
+ departmental_flags = DEPARTMENTAL_FLAG_MEDICAL
+
/////////////////////
///Surgery Designs///
/////////////////////
@@ -723,14 +727,24 @@
research_icon = 'icons/obj/surgery.dmi'
research_icon_state = "surgery_any"
var/surgery
-
+
/datum/design/surgery/experimental_dissection
- name = "Experimental Dissection"
- desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database."
- id = "surgery_exp_dissection"
- surgery = /datum/surgery/advanced/bioware/experimental_dissection
+ name = "Advanced Dissection"
+ desc = "A surgical procedure which analyzes the biology of a corpse, and automatically adds new findings to the research database."
+ id = "surgery_adv_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/adv
research_icon_state = "surgery_chest"
+/datum/design/surgery/experimental_dissection/exp
+ name = "Experimental Dissection"
+ id = "surgery_exp_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/exp
+
+/datum/design/surgery/experimental_dissection/ext
+ name = "Extraterrestrial Dissection"
+ id = "surgery_ext_dissection"
+ surgery = /datum/surgery/advanced/experimental_dissection/alien
+
/datum/design/surgery/lobotomy
name = "Lobotomy"
desc = "An invasive surgical procedure which guarantees removal of almost all brain traumas, but might cause another permanent trauma in return."
@@ -752,13 +766,49 @@
surgery = /datum/surgery/advanced/viral_bonding
research_icon_state = "surgery_chest"
-/datum/design/surgery/reconstruction
- name = "Reconstruction"
- desc = "A surgical procedure that gradually repairs damage done to a body without the assistance of chemicals. Unlike classic medicine, it is effective on corpses."
- id = "surgery_reconstruction"
- surgery = /datum/surgery/advanced/reconstruction
+/datum/design/surgery/healing
+ name = "Tend Wounds"
+ desc = "An upgraded version of the original surgery."
+ id = "surgery_healing_base" //holder because travis cries otherwise. Not used in techweb unlocks.
research_icon_state = "surgery_chest"
+/datum/design/surgery/healing/brute_upgrade
+ name = "Tend Wounds (Brute) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded
+ id = "surgery_heal_brute_upgrade"
+
+/datum/design/surgery/healing/brute_upgrade_2
+ name = "Tend Wounds (Brute) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded/femto
+ id = "surgery_heal_brute_upgrade_femto"
+
+/datum/design/surgery/healing/burn_upgrade
+ name = "Tend Wounds (Burn) Upgrade"
+ surgery = /datum/surgery/healing/burn/upgraded
+ id = "surgery_heal_burn_upgrade"
+
+/datum/design/surgery/healing/burn_upgrade_2
+ name = "Tend Wounds (Burn) Upgrade"
+ surgery = /datum/surgery/healing/brute/upgraded/femto
+ id = "surgery_heal_burn_upgrade_femto"
+
+/datum/design/surgery/healing/combo
+ name = "Tend Wounds (Mixture)"
+ desc = "A surgical procedure that repairs both bruises and burns. Repair efficiency is not as high as the individual surgeries but it is faster."
+ surgery = /datum/surgery/healing/combo
+ id = "surgery_heal_combo"
+
+/datum/design/surgery/healing/combo_upgrade
+ name = "Tend Wounds (Mixture) Upgrade"
+ surgery = /datum/surgery/healing/combo/upgraded
+ id = "surgery_heal_combo_upgrade"
+
+/datum/design/surgery/healing/combo_upgrade_2
+ name = "Tend Wounds (Mixture) Upgrade"
+ desc = "A surgical procedure that repairs both bruises and burns faster than their individual counterparts. It is more effective than both the individual surgeries."
+ surgery = /datum/surgery/healing/combo/upgraded/femto
+ id = "surgery_heal_combo_upgrade_femto"
+
/datum/design/surgery/surgery_toxinhealing
name = "Body Rejuvenation"
desc = "A surgical procedure that helps deal with oxygen deprecation, and treat toxic damaged. Works on corpses and alive alike without chemicals."
@@ -801,6 +851,13 @@
surgery = /datum/surgery/advanced/bioware/vein_threading
research_icon_state = "surgery_chest"
+/datum/design/surgery/muscled_veins
+ name = "Vein Muscle Membrane"
+ desc = "A surgical procedure which adds a muscled membrane to blood vessels, allowing them to pump blood without a heart."
+ id = "surgery_muscled_veins"
+ surgery = /datum/surgery/advanced/bioware/muscled_veins
+ research_icon_state = "surgery_chest"
+
/datum/design/surgery/ligament_hook
name = "Ligament Hook"
desc = "A surgical procedure which reshapes the connections between torso and limbs, making it so limbs can be attached manually if severed. \
diff --git a/code/modules/research/designs/stock_parts_designs.dm b/code/modules/research/designs/stock_parts_designs.dm
index ea67fad434..6526599179 100644
--- a/code/modules/research/designs/stock_parts_designs.dm
+++ b/code/modules/research/designs/stock_parts_designs.dm
@@ -288,7 +288,7 @@
departmental_flags = DEPARTMENTAL_FLAG_ENGINEERING | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/subspace_analyzer
- name = "Subspace Analyzer"
+ name = "Subspace Wavelength Analyzer"
desc = "A sophisticated analyzer capable of analyzing cryptic subspace wavelengths."
id = "s-analyzer"
build_type = PROTOLATHE
diff --git a/code/modules/research/designs/weapon_designs.dm b/code/modules/research/designs/weapon_designs.dm
index 214ef36afe..d69dda37ca 100644
--- a/code/modules/research/designs/weapon_designs.dm
+++ b/code/modules/research/designs/weapon_designs.dm
@@ -47,10 +47,32 @@
build_path = /obj/item/ammo_box/magazine/wt550m9/wtic
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+/datum/design/mag_oldsmg/tx_mag
+ name = "WT-550 Semi-Auto SMG Uranium Magazine (4.6x30mm TX)"
+ desc = "A 20 round uranium tipped magazine for the out of date security WT-550 Semi-Auto SMG."
+ id = "mag_oldsmg_tx"
+ materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_URANIUM = 2000)
+ build_path = /obj/item/ammo_box/magazine/wt550m9/wttx
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
+/datum/design/mag_oldsmg/rubber_mag
+ name = "WT-550 Semi-Auto SMG rubberbullets Magazine (4.6x30mm rubber)"
+ desc = "A 20 round rubber shots magazine for the out of date security WT-550 Semi-Auto SMG"
+ id = "mag_oldsmg_rubber"
+ materials = list(MAT_METAL = 6000)
+ build_path = /obj/item/ammo_box/magazine/wt550m9/wtrubber
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
//////////////
//Ammo Shells/
//////////////
+/datum/design/beanbag_slug/sec
+ id = "sec_beanbag"
+ build_type = PROTOLATHE
+ category = list("Ammo")
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+
/datum/design/rubbershot/sec
id = "sec_rshot"
build_type = PROTOLATHE
@@ -89,7 +111,7 @@
materials = list(MAT_METAL = 200)
build_path = /obj/item/ammo_casing/shotgun/stunslug
category = list("Ammo")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/techshell
name = "Unloaded Technological Shotshell"
@@ -123,7 +145,7 @@
materials = list(MAT_METAL = 500, MAT_GLASS = 300)
build_path = /obj/item/firing_pin/test_range
category = list("Firing Pins")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/pin_mindshield
name = "Mindshield Firing Pin"
@@ -219,7 +241,7 @@
reagents_list = list("radium" = 20)
build_path = /obj/item/gun/energy/floragun
category = list("Weapons")
- departmental_flags = DEPARTMENTAL_FLAG_SERVICE
+ departmental_flags = DEPARTMENTAL_FLAG_SERVICE | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/xray
name = "X-ray Laser Gun"
@@ -293,7 +315,7 @@
materials = list(MAT_METAL = 2000, MAT_PLASMA = 500)
build_path = /obj/item/grenade/chem_grenade/pyro
category = list("Weapons")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/cryo_grenade
name = "Cryo Grenade"
@@ -303,7 +325,7 @@
materials = list(MAT_METAL = 2000, MAT_SILVER = 500)
build_path = /obj/item/grenade/chem_grenade/cryo
category = list("Weapons")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
/datum/design/adv_grenade
name = "Advanced Release Grenade"
@@ -313,7 +335,7 @@
materials = list(MAT_METAL = 3000, MAT_GLASS = 500)
build_path = /obj/item/grenade/chem_grenade/adv_release
category = list("Weapons")
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL
+ departmental_flags = DEPARTMENTAL_FLAG_SECURITY | DEPARTMENTAL_FLAG_MEDICAL | DEPARTMENTAL_FLAG_SCIENCE
//////////
//MISC////
diff --git a/code/modules/research/experimentor.dm b/code/modules/research/experimentor.dm
index e56350a280..0bcd0c5984 100644
--- a/code/modules/research/experimentor.dm
+++ b/code/modules/research/experimentor.dm
@@ -422,7 +422,7 @@
if(exp == SCANTYPE_OBLITERATE)
visible_message("[exp_on] activates the crushing mechanism, [exp_on] is destroyed! ")
if(linked_console.linked_lathe)
- GET_COMPONENT_FROM(linked_materials, /datum/component/material_container, linked_console.linked_lathe)
+ var/datum/component/material_container/linked_materials = linked_console.linked_lathe.GetComponent(/datum/component/material_container)
for(var/material in exp_on.materials)
linked_materials.insert_amount( min((linked_materials.max_amount - linked_materials.total_amount), (exp_on.materials[material])), material)
if(prob(EFFECT_PROB_LOW) && criticalReaction)
diff --git a/code/modules/research/nanites/nanite_programs/healing.dm b/code/modules/research/nanites/nanite_programs/healing.dm
index 8aab7f1e2b..1113f11e87 100644
--- a/code/modules/research/nanites/nanite_programs/healing.dm
+++ b/code/modules/research/nanites/nanite_programs/healing.dm
@@ -72,14 +72,16 @@
/datum/nanite_program/brain_heal/check_conditions()
if(iscarbon(host_mob))
var/mob/living/carbon/C = host_mob
- if(length(C.get_traumas()))
- return ..()
- if(host_mob.getBrainLoss())
+ for(var/X in C.get_traumas())
+ var/datum/brain_trauma/BT = X
+ if(BT.resilience <= TRAUMA_RESILIENCE_BASIC)
+ return ..()
+ if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN))
return ..()
return FALSE
/datum/nanite_program/brain_heal/active_effect()
- host_mob.adjustBrainLoss(-1, TRUE)
+ host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1, TRUE)
if(iscarbon(host_mob) && prob(10))
var/mob/living/carbon/C = host_mob
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_BASIC)
@@ -193,14 +195,16 @@
/datum/nanite_program/brain_heal_advanced/check_conditions()
if(iscarbon(host_mob))
var/mob/living/carbon/C = host_mob
- if(length(C.get_traumas()))
- return ..()
- if(host_mob.getBrainLoss())
+ for(var/X in C.get_traumas())
+ var/datum/brain_trauma/BT = X
+ if(BT.resilience <= TRAUMA_RESILIENCE_LOBOTOMY)
+ return ..()
+ if(host_mob.getOrganLoss(ORGAN_SLOT_BRAIN))
return ..()
return FALSE
-
+
/datum/nanite_program/brain_heal_advanced/active_effect()
- host_mob.adjustBrainLoss(-2, TRUE)
+ host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, -2, TRUE)
if(iscarbon(host_mob) && prob(10))
var/mob/living/carbon/C = host_mob
C.cure_trauma_type(resilience = TRAUMA_RESILIENCE_LOBOTOMY)
@@ -232,7 +236,7 @@
if(!C.getorgan(/obj/item/organ/heart)) //what are we even shocking
return FALSE
var/obj/item/organ/brain/BR = C.getorgan(/obj/item/organ/brain)
- if(QDELETED(BR) || BR.damaged_brain)
+ if(QDELETED(BR) || BR.brain_death || (BR.organ_flags & ORGAN_FAILING) || C.suiciding)
return FALSE
if(C.get_ghost())
return FALSE
@@ -252,7 +256,7 @@
SEND_SIGNAL(C, COMSIG_LIVING_MINOR_SHOCK)
var/tplus = world.time - C.timeofdeath
if(tplus > 600)
- C.adjustBrainLoss( max(0, ((1800 - tplus) / 1800 * 150)), 150)
+ C.adjustOrganLoss(ORGAN_SLOT_BRAIN, max(0, ((1800 - tplus) / 1800 * 150)), 150)
log_game("[C] has been successfully defibrillated by nanites.")
else
playsound(C, 'sound/machines/defib_failed.ogg', 50, 0)
diff --git a/code/modules/research/nanites/nanite_programs/rogue.dm b/code/modules/research/nanites/nanite_programs/rogue.dm
index f64c7e8781..287aed36fe 100644
--- a/code/modules/research/nanites/nanite_programs/rogue.dm
+++ b/code/modules/research/nanites/nanite_programs/rogue.dm
@@ -59,7 +59,7 @@
/datum/nanite_program/brain_decay/active_effect()
if(prob(4))
host_mob.hallucination = min(15, host_mob.hallucination)
- host_mob.adjustBrainLoss(1)
+ host_mob.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
//Generic brain-affecting programs can also decay into this
/datum/nanite_program/brain_misfire
diff --git a/code/modules/research/research_disk.dm b/code/modules/research/research_disk.dm
index 2ec2398d88..02865dc5bb 100644
--- a/code/modules/research/research_disk.dm
+++ b/code/modules/research/research_disk.dm
@@ -29,3 +29,12 @@
/obj/item/disk/tech_disk/illegal/Initialize()
. = ..()
stored_research = new /datum/techweb/syndicate
+
+/obj/item/disk/tech_disk/abductor
+ name = "Gray technology disk"
+ desc = "You feel like it's not Gray because of its color."
+ materials = list()
+
+/obj/item/disk/tech_disk/abductor/Initialize()
+ . = ..()
+ stored_research = new /datum/techweb/abductor
diff --git a/code/modules/research/stock_parts.dm b/code/modules/research/stock_parts.dm
index af004c4701..12fe64463d 100644
--- a/code/modules/research/stock_parts.dm
+++ b/code/modules/research/stock_parts.dm
@@ -13,6 +13,7 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
var/works_from_distance = FALSE
var/pshoom_or_beepboopblorpzingshadashwoosh = 'sound/items/rped.ogg'
var/alt_sound = null
+ rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE //cutting down on exploits
/obj/item/storage/part_replacer/pre_attack(obj/machinery/T, mob/living/user, params)
if(!istype(T) || !T.component_parts)
@@ -42,7 +43,7 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
/obj/item/storage/part_replacer/bluespace
name = "bluespace rapid part exchange device"
- desc = "A version of the RPED that allows for replacement of parts and scanning from a distance, along with higher capacity for parts."
+ desc = "A version of the RPED that allows for replacement of parts and scanning from a distance, along with higher capacity for parts. Definitely not just a BSRPED painted orange."
icon_state = "BS_RPED"
w_class = WEIGHT_CLASS_NORMAL
works_from_distance = TRUE
@@ -51,12 +52,10 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
component_type = /datum/component/storage/concrete/bluespace/rped
/obj/item/storage/part_replacer/cyborg
- name = "rapid part exchange device"
- desc = "Special mechanical module made to store, sort, and apply standard machine parts."
icon_state = "borgrped"
- item_state = "RPED"
- lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
+
+/obj/item/storage/part_replacer/bluespace/cyborg
+ icon_state = "borg_BS_RPED"
/proc/cmp_rped_sort(obj/item/A, obj/item/B)
return B.get_part_rating() - A.get_part_rating()
@@ -67,6 +66,7 @@ If you create T5+ please take a pass at gene_modder.dm [L40]. Max_values MUST fi
icon = 'icons/obj/stock_parts.dmi'
w_class = WEIGHT_CLASS_SMALL
var/rating = 1
+ rad_flags = RAD_NO_CONTAMINATE
/obj/item/stock_parts/Initialize()
. = ..()
diff --git a/code/modules/research/techweb/_techweb.dm b/code/modules/research/techweb/_techweb.dm
index cd5a190fd6..1e554f112f 100644
--- a/code/modules/research/techweb/_techweb.dm
+++ b/code/modules/research/techweb/_techweb.dm
@@ -49,6 +49,14 @@
var/datum/techweb_node/syndicate_basic/Node = new()
research_node(Node, TRUE)
+/datum/techweb/abductor
+ id = "ABDUCTOR"
+ organization = "Aliens"
+
+/datum/techweb/abductor/New()
+ var/datum/techweb_node/alientech/Node = new()
+ research_node(Node, TRUE)
+
/datum/techweb/science //Global science techweb for RND consoles.
id = "SCIENCE"
organization = "Nanotrasen"
@@ -364,3 +372,7 @@
/datum/techweb/specialized/autounlocking/exofab
allowed_buildtypes = MECHFAB
+
+/datum/techweb/specialized/autounlocking/autoylathe
+ design_autounlock_buildtypes = AUTOYLATHE
+ allowed_buildtypes = AUTOYLATHE
diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm
index 038a41b3cd..fdf887d259 100644
--- a/code/modules/research/techweb/all_nodes.dm
+++ b/code/modules/research/techweb/all_nodes.dm
@@ -10,7 +10,7 @@
// Default research tech, prevents bricking
design_ids = list("basic_matter_bin", "basic_cell", "basic_scanning", "basic_capacitor", "basic_micro_laser", "micro_mani",
"destructive_analyzer", "circuit_imprinter", "experimentor", "rdconsole", "design_disk", "tech_disk", "rdserver", "rdservercontrol", "mechfab",
- "space_heater", "xlarge_beaker", "sec_rshot", "sec_bshot", "sec_slug", "sec_Islug", "sec_dart", "sec_38", "sec_38lethal",
+ "space_heater", "xlarge_beaker", "sec_beanbag", "sec_rshot", "sec_bshot", "sec_slug", "sec_Islug", "sec_dart", "sec_38", "sec_38lethal",
"rglass","plasteel","plastitanium","plasmaglass","plasmareinforcedglass","titaniumglass","plastitaniumglass")
/datum/techweb_node/mmi
@@ -60,7 +60,7 @@
display_name = "Biological Technology"
description = "What makes us tick." //the MC, silly!
prereq_ids = list("base")
- design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag")
+ design_ids = list("medicalkit", "chem_heater", "chem_master", "chem_dispenser", "sleeper", "vr_sleeper", "pandemic", "defibmount", "operating", "soda_dispenser", "beer_dispenser", "healthanalyzer", "blood_bag", "bloodbankgen")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -96,7 +96,7 @@
display_name = "Advanced Surgery Tools"
description = "Refined and improved redesigns for the run-of-the-mill medical utensils."
prereq_ids = list("adv_biotech", "adv_surgery")
- design_ids = list("drapes", "retractor_adv", "hemostat_adv", "cautery_adv", "surgicaldrill_adv", "scalpel_adv", "circular_saw_adv")
+ design_ids = list("drapes", "retractor_adv", "surgicaldrill_adv", "scalpel_adv")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -110,12 +110,21 @@
export_price = 5000
/////////////////////////Advanced Surgery/////////////////////////
+/datum/techweb_node/imp_wt_surgery
+ id = "imp_wt_surgery"
+ display_name = "Improved Wound-Tending Surgery"
+ description = "Who would have known being more gentle with a hemostat decreases patient pain?"
+ prereq_ids = list("biotech")
+ design_ids = list("surgery_heal_brute_upgrade","surgery_heal_burn_upgrade")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
+ export_price = 1000
+
/datum/techweb_node/adv_surgery
id = "adv_surgery"
display_name = "Advanced Surgery"
description = "When simple medicine doesn't cut it."
- prereq_ids = list("adv_biotech")
- design_ids = list("surgery_lobotomy", "surgery_reconstruction", "surgery_toxinhealing", "organbox", "surgery_exp_dissection")
+ prereq_ids = list("imp_wt_surgery")
+ design_ids = list("surgery_revival", "surgery_lobotomy", "surgery_heal_brute_upgrade_femto","surgery_heal_burn_upgrade_femto", "surgery_heal_combo", "surgery_toxinhealing", "organbox", "surgery_adv_dissection")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
@@ -124,7 +133,7 @@
display_name = "Experimental Surgery"
description = "When evolution isn't fast enough."
prereq_ids = list("adv_surgery")
- design_ids = list("surgery_revival","surgery_pacify","surgery_vein_thread","surgery_nerve_splice","surgery_nerve_ground","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_viral_bond")
+ design_ids = list("surgery_pacify","surgery_vein_thread","surgery_muscled_veins","surgery_nerve_splice","surgery_nerve_ground","surgery_ligament_hook","surgery_ligament_reinforcement","surgery_viral_bond", "surgery_exp_dissection", "surgery_heal_combo_upgrade")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
export_price = 5000
@@ -133,7 +142,7 @@
display_name = "Alien Surgery"
description = "Abductors did nothing wrong."
prereq_ids = list("exp_surgery", "alientech")
- design_ids = list("surgery_brainwashing","surgery_zombie")
+ design_ids = list("surgery_brainwashing","surgery_zombie", "surgery_ext_dissection", "surgery_heal_combo_upgrade_femto")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000)
export_price = 5000
@@ -517,8 +526,17 @@
display_name = "Cybernetic Organs"
description = "We have the technology to rebuild him."
prereq_ids = list("adv_biotech")
- design_ids = list("cybernetic_heart", "cybernetic_liver", "cybernetic_liver_u", "cybernetic_lungs", "cybernetic_lungs_u", "cybernetic_tongue")
- research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
+ design_ids = list("cybernetic_ears", "cybernetic_heart", "cybernetic_liver", "cybernetic_lungs", "cybernetic_tongue")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1000)
+ export_price = 5000
+
+/datum/techweb_node/cyber_organs_upgraded
+ id = "cyber_organs_upgraded"
+ display_name = "Upgraded Cybernetic Organs"
+ description = "We have the technology to upgrade him."
+ prereq_ids = list("cyber_organs")
+ design_ids = list("cybernetic_ears_u", "cybernetic_heart_u", "cybernetic_liver_u", "cybernetic_lungs_u")
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 1500)
export_price = 5000
/datum/techweb_node/cyber_implants
@@ -1009,26 +1027,19 @@
id = "alien_bio"
display_name = "Alien Biological Tools"
description = "Advanced biological tools."
- prereq_ids = list("alientech", "adv_biotech")
+ prereq_ids = list("alientech", "advance_surgerytools")
design_ids = list("alien_scalpel", "alien_hemostat", "alien_retractor", "alien_saw", "alien_drill", "alien_cautery")
- boost_item_paths = list(/obj/item/gun/energy/alien, /obj/item/scalpel/alien, /obj/item/hemostat/alien, /obj/item/retractor/alien, /obj/item/circular_saw/alien,
- /obj/item/cautery/alien, /obj/item/surgicaldrill/alien, /obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, /obj/item/stock_parts/cell/infinite/abductor,
- /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor)
- research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
- export_price = 20000
- hidden = TRUE
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
+ export_price = 10000
/datum/techweb_node/alien_engi
id = "alien_engi"
display_name = "Alien Engineering"
description = "Alien engineering tools"
- prereq_ids = list("alientech", "adv_engi")
+ prereq_ids = list("alientech", "exp_tools")
design_ids = list("alien_wrench", "alien_wirecutters", "alien_screwdriver", "alien_crowbar", "alien_welder", "alien_multitool")
- boost_item_paths = list(/obj/item/screwdriver/abductor, /obj/item/wrench/abductor, /obj/item/crowbar/abductor, /obj/item/multitool/abductor, /obj/item/stock_parts/cell/infinite/abductor,
- /obj/item/weldingtool/abductor, /obj/item/wirecutters/abductor, /obj/item/circuitboard/machine/abductor, /obj/item/abductor_baton, /obj/item/abductor)
- research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
- export_price = 20000
- hidden = TRUE
+ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000)
+ export_price = 10000
/datum/techweb_node/syndicate_basic
id = "syndicate_basic"
@@ -1045,7 +1056,7 @@
boost_item_paths = list()
for(var/path in GLOB.uplink_items)
var/datum/uplink_item/UI = new path
- if(!UI.item)
+ if(!UI.item || !UI.illegal_tech)
continue
boost_item_paths |= UI.item //allows deconning to unlock.
@@ -1088,4 +1099,4 @@
for(var/i in processing)
var/datum/techweb_node/TN = i
TW.add_point_list(TN.research_costs)
- return TW.printout_points()
\ No newline at end of file
+ return TW.printout_points()
diff --git a/code/modules/research/xenobiology/crossbreeding/_misc.dm b/code/modules/research/xenobiology/crossbreeding/_misc.dm
index b28f1676a1..0099fe143d 100644
--- a/code/modules/research/xenobiology/crossbreeding/_misc.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_misc.dm
@@ -58,9 +58,7 @@
var/mob/living/carbon/human/H = M
if(H.mind && !HAS_TRAIT(H, TRAIT_AGEUSIA))
to_chat(H,"That didn't taste very good... ") //No disgust, though. It's just not good tasting.
- GET_COMPONENT_FROM(mood, /datum/component/mood, H)
- if(mood)
- mood.add_event(null,"gross_food", /datum/mood_event/gross_food)
+ SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "gross_food", /datum/mood_event/gross_food)
last_check_time = world.time
return
..()
diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
index b9e7122d07..9c9542ed17 100644
--- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm
@@ -64,10 +64,9 @@
var/interrupted = FALSE
var/mob/target
var/icon/bluespace
- var/datum/weakref/redirect_component
/datum/status_effect/slimerecall/on_apply()
- redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/resistField))))
+ RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/resistField)
to_chat(owner, "You feel a sudden tug from an unknown force, and feel a pull to bluespace! ")
to_chat(owner, "Resist if you wish avoid the force! ")
bluespace = icon('icons/effects/effects.dmi',"chronofield")
@@ -77,9 +76,9 @@
/datum/status_effect/slimerecall/proc/resistField()
interrupted = TRUE
owner.remove_status_effect(src)
+
/datum/status_effect/slimerecall/on_remove()
- qdel(redirect_component.resolve())
- redirect_component = null
+ UnregisterSignal(owner, COMSIG_LIVING_RESIST)
owner.cut_overlay(bluespace)
if(interrupted || !ismob(target))
to_chat(owner, "The bluespace tug fades away, and you feel that the force has passed you by. ")
@@ -98,10 +97,9 @@
duration = -1 //Will remove self when block breaks.
alert_type = /obj/screen/alert/status_effect/freon/stasis
var/obj/structure/ice_stasis/cube
- var/datum/weakref/redirect_component
/datum/status_effect/frozenstasis/on_apply()
- redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/breakCube))))
+ RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/breakCube)
cube = new /obj/structure/ice_stasis(get_turf(owner))
owner.forceMove(cube)
owner.status_flags |= GODMODE
@@ -118,8 +116,7 @@
if(cube)
qdel(cube)
owner.status_flags &= ~GODMODE
- qdel(redirect_component.resolve())
- redirect_component = null
+ UnregisterSignal(owner, COMSIG_LIVING_RESIST)
/datum/status_effect/slime_clone
id = "slime_cloned"
@@ -375,15 +372,11 @@ datum/status_effect/rebreathing/tick()
duration = 30
/datum/status_effect/tarfoot/on_apply()
- var/mob/living/carbon/human/H = owner
- if(istype(H))
- H.physiology.speed_mod += 0.5
+ owner.add_movespeed_modifier(MOVESPEED_ID_TARFOOT, update=TRUE, priority=100, multiplicative_slowdown=0.5, blacklisted_movetypes=(FLYING|FLOATING))
return ..()
/datum/status_effect/tarfoot/on_remove()
- var/mob/living/carbon/human/H = owner
- if(istype(H))
- H.physiology.speed_mod -= 0.5
+ owner.remove_movespeed_modifier(MOVESPEED_ID_TARFOOT)
/datum/status_effect/spookcookie
id = "spookcookie"
@@ -570,7 +563,7 @@ datum/status_effect/stabilized/blue/on_remove()
name = "burning fingertips"
desc = "You shouldn't see this."
-/obj/item/hothands/is_hot()
+/obj/item/hothands/get_temperature()
return 290 //Below what's required to ignite plasma.
/datum/status_effect/stabilized/darkpurple
@@ -695,20 +688,15 @@ datum/status_effect/stabilized/blue/on_remove()
/datum/status_effect/stabilized/sepia/tick()
if(prob(50) && mod > -1)
mod--
- var/mob/living/carbon/human/H = owner
- if(istype(H))
- H.physiology.speed_mod--
+ owner.add_movespeed_modifier(MOVESPEED_ID_SEPIA, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
else if(mod < 1)
mod++
- var/mob/living/carbon/human/H = owner
- if(istype(H))
- H.physiology.speed_mod++
+ // yeah a value of 0 does nothing but replacing the trait in place is cheaper than removing and adding repeatedly
+ owner.add_movespeed_modifier(MOVESPEED_ID_SEPIA, update=TRUE, priority=100, multiplicative_slowdown=0, blacklisted_movetypes=(FLYING|FLOATING))
return ..()
/datum/status_effect/stabilized/sepia/on_remove()
- var/mob/living/carbon/human/H = owner
- if(istype(H))
- H.physiology.speed_mod += -mod //Reset the changes.
+ owner.remove_movespeed_modifier(MOVESPEED_ID_SEPIA)
/datum/status_effect/stabilized/cerulean
id = "stabilizedcerulean"
@@ -916,7 +904,7 @@ datum/status_effect/stabilized/blue/on_remove()
colour = "light pink"
/datum/status_effect/stabilized/lightpink/on_apply()
- ADD_TRAIT(owner, TRAIT_GOTTAGOFAST,"slimestatus")
+ owner.add_movespeed_modifier(MOVESPEED_ID_SLIME_STATUS, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
return ..()
/datum/status_effect/stabilized/lightpink/tick()
@@ -927,7 +915,7 @@ datum/status_effect/stabilized/blue/on_remove()
return ..()
/datum/status_effect/stabilized/lightpink/on_remove()
- REMOVE_TRAIT(owner, TRAIT_GOTTAGOFAST,"slimestatus")
+ owner.remove_movespeed_modifier(MOVESPEED_ID_SLIME_STATUS)
/datum/status_effect/stabilized/adamantine
id = "stabilizedadamantine"
diff --git a/code/modules/research/xenobiology/crossbreeding/_weapons.dm b/code/modules/research/xenobiology/crossbreeding/_weapons.dm
index 4753abff97..1b2f43c518 100644
--- a/code/modules/research/xenobiology/crossbreeding/_weapons.dm
+++ b/code/modules/research/xenobiology/crossbreeding/_weapons.dm
@@ -27,9 +27,9 @@
return 0
charge_tick = 0
var/mob/living/M = loc
- if(istype(M) && M.blood_volume >= 20)
+ if(istype(M) && M.blood_volume >= 5)
charges++
- M.blood_volume -= 20
+ M.blood_volume -= 5
if(charges == 1)
recharge_newshot()
return 1
diff --git a/code/modules/research/xenobiology/crossbreeding/consuming.dm b/code/modules/research/xenobiology/crossbreeding/consuming.dm
index 0b2d60da8c..d6536f4fdd 100644
--- a/code/modules/research/xenobiology/crossbreeding/consuming.dm
+++ b/code/modules/research/xenobiology/crossbreeding/consuming.dm
@@ -119,7 +119,7 @@ Consuming extracts:
M.adjustToxLoss(-5, forced=1) //To heal slimepeople.
M.adjustOxyLoss(-5)
M.adjustCloneLoss(-5)
- M.adjustBrainLoss(-5)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, -5)
/obj/item/slimecross/consuming/blue
colour = "blue"
diff --git a/code/modules/research/xenobiology/xenobio_camera.dm b/code/modules/research/xenobiology/xenobio_camera.dm
index 35d2a3577a..f696e771f4 100644
--- a/code/modules/research/xenobiology/xenobio_camera.dm
+++ b/code/modules/research/xenobiology/xenobio_camera.dm
@@ -30,12 +30,11 @@
var/datum/action/innate/feed_potion/potion_action
var/datum/action/innate/hotkey_help/hotkey_help
- var/datum/component/redirect/listener
-
var/list/stored_slimes
var/obj/item/slimepotion/slime/current_potion
- var/max_slimes = 5
+ var/max_slimes = 1
var/monkeys = 0
+ var/upgradetier = 0
icon_screen = "slime_comp"
icon_keyboard = "rd_key"
@@ -52,7 +51,7 @@
potion_action = new
hotkey_help = new
stored_slimes = list()
- listener = AddComponent(/datum/component/redirect, list(COMSIG_ATOM_CONTENTS_DEL = CALLBACK(src, .proc/on_contents_del)))
+ RegisterSignal(src, COMSIG_ATOM_CONTENTS_DEL, .proc/on_contents_del)
/obj/machinery/computer/camera_advanced/xenobio/Destroy()
stored_slimes = null
@@ -131,6 +130,22 @@
stored_slimes -= deleted
/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params)
+ if(istype(O, /obj/item/disk/xenobio_console_upgrade))
+ var/obj/item/disk/xenobio_console_upgrade/diskthing = O
+ var/successfulupgrade = FALSE
+ for(var/I in diskthing.upgradetypes)
+ if(upgradetier & I)
+ continue
+ else
+ upgradetier |= I
+ successfulupgrade = TRUE
+ if(I == XENOBIO_UPGRADE_SLIMEADV)
+ max_slimes = 10
+ if(successfulupgrade)
+ to_chat(user, "You have successfully upgraded [src] with [O]. ")
+ else
+ to_chat(user, "[src] already has the contents of [O] installed! ")
+ return
if(istype(O, /obj/item/reagent_containers/food/snacks/monkeycube) && (upgradetier & XENOBIO_UPGRADE_MONKEYS)) //CIT CHANGE - makes monkey-related actions require XENOBIO_UPGRADE_MONKEYS
monkeys++
to_chat(user, "You feed [O] to [src]. It now has [monkeys] monkey cubes stored. ")
@@ -248,8 +263,6 @@
M.visible_message("[M] vanishes as [M.p_theyre()] reclaimed for recycling!")
X.monkeys = round(X.monkeys + 0.2,0.1)
qdel(M)
- if (X.monkeys == (round(X.monkeys,1)))
- to_chat(C, "[X] now has [X.monkeys] monkey(s) available. ")
else
to_chat(owner, "Target is not near a camera. Cannot proceed. ")
@@ -284,7 +297,7 @@
var/obj/machinery/computer/camera_advanced/xenobio/X = target
if(QDELETED(X.current_potion))
- to_chat(owner, "No potion loaded. ")
+ to_chat(owner, "No potion loaded. ")
return
if(GLOB.cameranet.checkTurfVis(remote_eye.loc))
@@ -294,6 +307,38 @@
else
to_chat(owner, "Target is not near a camera. Cannot proceed. ")
+
+//Demodularized Code
+
+/obj/item/disk/xenobio_console_upgrade
+ name = "Xenobiology console upgrade disk"
+ desc = "Allan please add detail."
+ icon_state = "datadisk5"
+ var/list/upgradetypes = list()
+
+/obj/item/disk/xenobio_console_upgrade/admin
+ name = "Xenobio all access thing"
+ desc = "'the consoles are literally useless!!!!!!!!!!!!!!!'"
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV, XENOBIO_UPGRADE_MONKEYS)
+
+/obj/item/disk/xenobio_console_upgrade/monkey
+ name = "Xenobiology console monkey upgrade disk"
+ desc = "This disk will add the ability to remotely recycle monkeys via the Xenobiology console."
+ upgradetypes = list(XENOBIO_UPGRADE_MONKEYS)
+
+/obj/item/disk/xenobio_console_upgrade/slimebasic
+ name = "Xenobiology console basic slime upgrade disk"
+ desc = "This disk will add the ability to remotely manipulate slimes via the Xenobiology console."
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC)
+
+/obj/item/disk/xenobio_console_upgrade/slimeadv
+ name = "Xenobiology console advanced slime upgrade disk"
+ desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
+ upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV)
+
+
+//Xenobio Hotkeys Port
+
/datum/action/innate/hotkey_help
name = "Hotkey Help"
icon_icon = 'icons/mob/actions/actions_silicon.dmi'
diff --git a/code/modules/research/xenobiology/xenobiology.dm b/code/modules/research/xenobiology/xenobiology.dm
index 7acbaaac1c..2894ce2108 100644
--- a/code/modules/research/xenobiology/xenobiology.dm
+++ b/code/modules/research/xenobiology/xenobiology.dm
@@ -325,7 +325,7 @@
if(SLIME_ACTIVATE_MAJOR)
var/turf/open/T = get_turf(user)
if(istype(T))
- T.atmos_spawn_air("nitrogen=40;TEMP=2.7")
+ T.atmos_spawn_air("n2=40;TEMP=2.7")
to_chat(user, "You activate [src], and icy air bursts out of your skin! ")
return 900
@@ -523,7 +523,8 @@
/obj/item/slime_extract/pyrite/activate(mob/living/carbon/human/user, datum/species/jelly/luminescent/species, activation_type)
switch(activation_type)
if(SLIME_ACTIVATE_MINOR)
- var/chosen = pick(difflist(subtypesof(/obj/item/toy/crayon),typesof(/obj/item/toy/crayon/spraycan)))
+ var/blacklisted_cans = list(/obj/item/toy/crayon/spraycan/borg, /obj/item/toy/crayon/spraycan/infinite)
+ var/chosen = pick(subtypesof(/obj/item/toy/crayon/spraycan) - blacklisted_cans)
var/obj/item/O = new chosen(null)
if(!user.put_in_active_hand(O))
O.forceMove(user.drop_location())
@@ -680,7 +681,7 @@
var/list/candidates = pollCandidatesForMob("Do you want to play as [SM.name]?", ROLE_SENTIENCE, null, ROLE_SENTIENCE, 50, SM, POLL_IGNORE_SENTIENCE_POTION) // see poll_ignore.dm
if(LAZYLEN(candidates))
var/mob/dead/observer/C = pick(candidates)
- SM.key = C.key
+ C.transfer_ckey(SM, FALSE)
SM.mind.enslave_mind_to_creator(user)
SM.sentience_act()
to_chat(SM, "All at once it makes sense: you know what you are and who you are! Self awareness is yours! ")
@@ -704,7 +705,7 @@
desc = "A miraculous chemical mix that grants human like intelligence to living beings. It has been modified with Syndicate technology to also grant an internal radio implant to the target and authenticate with identification systems."
/obj/item/slimepotion/slime/sentience/nuclear/after_success(mob/living/user, mob/living/simple_animal/SM)
- var/obj/item/implant/radio/syndicate/imp = new(src)
+ var/obj/item/implant/radio/syndicate/imp = new
imp.implant(SM, user)
SM.access_card = new /obj/item/card/id/syndicate(SM)
@@ -968,7 +969,7 @@
to_chat(user, "You feed the potion to [M]. ")
to_chat(M, "Your mind tingles as you are fed the potion. You can hear radio waves now! ")
- var/obj/item/implant/radio/slime/imp = new(src)
+ var/obj/item/implant/radio/slime/imp = new
imp.implant(M, user)
qdel(src)
diff --git a/code/modules/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/ruins/spaceruin_code/hilbertshotel.dm
new file mode 100644
index 0000000000..0d4d2b6ad6
--- /dev/null
+++ b/code/modules/ruins/spaceruin_code/hilbertshotel.dm
@@ -0,0 +1,529 @@
+GLOBAL_VAR_INIT(hhStorageTurf, null)
+GLOBAL_VAR_INIT(hhmysteryRoomNumber, 1337)
+
+/obj/item/hilbertshotel
+ name = "Hilbert's Hotel"
+ desc = "A sphere of what appears to be an intricate network of bluespace. Observing it in detail seems to give you a headache as you try to comprehend the infinite amount of infinitesimally distinct points on its surface."
+ icon_state = "hilbertshotel"
+ w_class = WEIGHT_CLASS_SMALL
+ resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
+ var/datum/map_template/hilbertshotel/hotelRoomTemp
+ var/datum/map_template/hilbertshotel/empty/hotelRoomTempEmpty
+ var/datum/map_template/hilbertshotel/lore/hotelRoomTempLore
+ var/list/activeRooms = list()
+ var/list/storedRooms = list()
+ var/storageTurf
+ //Lore Stuff
+ var/ruinSpawned = FALSE
+ var/mysteryRoom
+
+/obj/item/hilbertshotel/Initialize()
+ . = ..()
+ //Load templates
+ hotelRoomTemp = new()
+ hotelRoomTempEmpty = new()
+ hotelRoomTempLore = new()
+ var/area/currentArea = get_area(src)
+ if(currentArea.type == /area/ruin/space/has_grav/hilbertresearchfacility)
+ ruinSpawned = TRUE
+
+/obj/item/hilbertshotel/Destroy()
+ ejectRooms()
+ return ..()
+
+/obj/item/hilbertshotel/attack(mob/living/M, mob/living/user)
+ if(M.mind)
+ to_chat(user, "You invite [M] to the hotel. ")
+ promptAndCheckIn(M)
+ else
+ to_chat(user, "[M] is not intelligent enough to understand how to use this device! ")
+
+/obj/item/hilbertshotel/attack_self(mob/user)
+ . = ..()
+ promptAndCheckIn(user)
+
+/obj/item/hilbertshotel/proc/promptAndCheckIn(mob/user)
+ var/chosenRoomNumber = input(user, "What number room will you be checking into?", "Room Number") as null|num
+ if(!chosenRoomNumber)
+ return
+ if(chosenRoomNumber > SHORT_REAL_LIMIT)
+ to_chat(user, "You have to check out the first [SHORT_REAL_LIMIT] rooms before you can go to a higher numbered one! ")
+ return
+ if((chosenRoomNumber < 1) || (chosenRoomNumber != round(chosenRoomNumber)))
+ to_chat(user, "That is not a valid room number! ")
+ return
+ if(ismob(loc))
+ if(user == loc) //Not always the same as user
+ forceMove(get_turf(user))
+ if(!storageTurf) //Blame subsystems for not allowing this to be in Initialize
+ if(!GLOB.hhStorageTurf)
+ var/datum/map_template/hilbertshotelstorage/storageTemp = new()
+ var/datum/turf_reservation/storageReservation = SSmapping.RequestBlockReservation(3, 3)
+ storageTemp.load(locate(storageReservation.bottom_left_coords[1], storageReservation.bottom_left_coords[2], storageReservation.bottom_left_coords[3]))
+ GLOB.hhStorageTurf = locate(storageReservation.bottom_left_coords[1]+1, storageReservation.bottom_left_coords[2]+1, storageReservation.bottom_left_coords[3])
+ else
+ storageTurf = GLOB.hhStorageTurf
+ if(tryActiveRoom(chosenRoomNumber, user))
+ return
+ if(tryStoredRoom(chosenRoomNumber, user))
+ return
+ sendToNewRoom(chosenRoomNumber, user)
+
+
+/obj/item/hilbertshotel/proc/tryActiveRoom(var/roomNumber, var/mob/user)
+ if(activeRooms["[roomNumber]"])
+ var/datum/turf_reservation/roomReservation = activeRooms["[roomNumber]"]
+ do_sparks(3, FALSE, get_turf(user))
+ user.forceMove(locate(roomReservation.bottom_left_coords[1] + hotelRoomTemp.landingZoneRelativeX, roomReservation.bottom_left_coords[2] + hotelRoomTemp.landingZoneRelativeY, roomReservation.bottom_left_coords[3]))
+ return TRUE
+ else
+ return FALSE
+
+/obj/item/hilbertshotel/proc/tryStoredRoom(var/roomNumber, var/mob/user)
+ if(storedRooms["[roomNumber]"])
+ var/datum/turf_reservation/roomReservation = SSmapping.RequestBlockReservation(hotelRoomTemp.width, hotelRoomTemp.height)
+ hotelRoomTempEmpty.load(locate(roomReservation.bottom_left_coords[1], roomReservation.bottom_left_coords[2], roomReservation.bottom_left_coords[3]))
+ var/turfNumber = 1
+ for(var/i=0, iAs the sphere breaks apart, you're suddenly ejected into the depths of space! ")
+ var/max = world.maxx-TRANSITIONEDGE
+ var/min = 1+TRANSITIONEDGE
+ var/list/possible_transtitons = list()
+ for(var/AZ in SSmapping.z_list)
+ var/datum/space_level/D = AZ
+ if (D.linkage == CROSSLINKED)
+ possible_transtitons += D.z_value
+ var/_z = pick(possible_transtitons)
+ var/_x = rand(min,max)
+ var/_y = rand(min,max)
+ var/turf/T = locate(_x, _y, _z)
+ A.forceMove(T)
+ qdel(room)
+
+ if(storedRooms.len)
+ for(var/x in storedRooms)
+ var/list/atomList = storedRooms[x]
+ for(var/atom/movable/A in atomList)
+ var/max = world.maxx-TRANSITIONEDGE
+ var/min = 1+TRANSITIONEDGE
+ var/list/possible_transtitons = list()
+ for(var/AZ in SSmapping.z_list)
+ var/datum/space_level/D = AZ
+ if (D.linkage == CROSSLINKED)
+ possible_transtitons += D.z_value
+ var/_z = pick(possible_transtitons)
+ var/_x = rand(min,max)
+ var/_y = rand(min,max)
+ var/turf/T = locate(_x, _y, _z)
+ A.forceMove(T)
+
+//Template Stuff
+/datum/map_template/hilbertshotel
+ name = "Hilbert's Hotel Room"
+ mappath = '_maps/templates/hilbertshotel.dmm'
+ var/landingZoneRelativeX = 2
+ var/landingZoneRelativeY = 8
+
+/datum/map_template/hilbertshotel/empty
+ name = "Empty Hilbert's Hotel Room"
+ mappath = '_maps/templates/hilbertshotelempty.dmm'
+
+/datum/map_template/hilbertshotel/lore
+ name = "Doctor Hilbert's Deathbed"
+ mappath = '_maps/templates/hilbertshotellore.dmm'
+
+/datum/map_template/hilbertshotelstorage
+ name = "Hilbert's Hotel Storage"
+ mappath = '_maps/templates/hilbertshotelstorage.dmm'
+
+
+//Turfs and Areas
+/turf/closed/indestructible/hotelwall
+ name = "hotel wall"
+ desc = "A wall designed to protect the security of the hotel's guests."
+ icon_state = "hotelwall"
+ canSmoothWith = list(/turf/closed/indestructible/hotelwall)
+ explosion_block = INFINITY
+
+/turf/open/indestructible/hotelwood
+ desc = "Stylish dark wood with extra reinforcement. Secured firmly to the floor to prevent tampering."
+ icon_state = "wood"
+ footstep = FOOTSTEP_WOOD
+ tiled_dirt = FALSE
+
+/turf/open/indestructible/hoteltile
+ desc = "Smooth tile with extra reinforcement. Secured firmly to the floor to prevent tampering."
+ icon_state = "showroomfloor"
+ footstep = FOOTSTEP_FLOOR
+ tiled_dirt = FALSE
+
+/turf/open/space/bluespace
+ name = "\proper bluespace hyperzone"
+ icon_state = "bluespace"
+ baseturfs = /turf/open/space/bluespace
+ flags_1 = NOJAUNT_1
+ explosion_block = INFINITY
+ var/obj/item/hilbertshotel/parentSphere
+
+/turf/open/space/bluespace/Entered(atom/movable/A)
+ . = ..()
+ A.forceMove(get_turf(parentSphere))
+
+/turf/closed/indestructible/hoteldoor
+ name = "Hotel Door"
+ icon_state = "hoteldoor"
+ explosion_block = INFINITY
+ var/obj/item/hilbertshotel/parentSphere
+
+/turf/closed/indestructible/hoteldoor/proc/promptExit(mob/living/user)
+ if(!isliving(user))
+ return
+ if(!user.mind)
+ return
+ if(!parentSphere)
+ to_chat(user, "The door seems to be malfunctioning and refuses to operate! ")
+ return
+ if(alert(user, "Hilbert's Hotel would like to remind you that while we will do everything we can to protect the belongings you leave behind, we make no guarantees of their safety while you're gone, especially that of the health of any living creatures. With that in mind, are you ready to leave?", "Exit", "Leave", "Stay") == "Leave")
+ if(!user.canmove || (get_dist(get_turf(src), get_turf(user)) > 1)) //no teleporting around if they're dead or moved away during the prompt.
+ return
+ user.forceMove(get_turf(parentSphere))
+ do_sparks(3, FALSE, get_turf(user))
+
+/turf/closed/indestructible/hoteldoor/attack_ghost(mob/dead/observer/user)
+ if(!isobserver(user) || !parentSphere)
+ return ..()
+ user.forceMove(get_turf(parentSphere))
+
+//If only this could be simplified...
+/turf/closed/indestructible/hoteldoor/attack_tk(mob/user)
+ return //need to be close.
+
+/turf/closed/indestructible/hoteldoor/attack_hand(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_animal(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_paw(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_hulk(mob/living/carbon/human/user, does_attack_animation)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_larva(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_slime(mob/user)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/attack_robot(mob/user)
+ if(get_dist(get_turf(src), get_turf(user)) <= 1)
+ promptExit(user)
+
+/turf/closed/indestructible/hoteldoor/AltClick(mob/user)
+ . = ..()
+ if(get_dist(get_turf(src), get_turf(user)) <= 1)
+ to_chat(user, "You peak through the door's bluespace peephole... ")
+ user.reset_perspective(parentSphere)
+ user.set_machine(src)
+ var/datum/action/peepholeCancel/PHC = new
+ user.overlay_fullscreen("remote_view", /obj/screen/fullscreen/impaired, 1)
+ PHC.Grant(user)
+
+/turf/closed/indestructible/hoteldoor/check_eye(mob/user)
+ if(get_dist(get_turf(src), get_turf(user)) >= 2)
+ user.unset_machine()
+ for(var/datum/action/peepholeCancel/PHC in user.actions)
+ PHC.Trigger()
+
+/datum/action/peepholeCancel
+ name = "Cancel View"
+ desc = "Stop looking through the bluespace peephole."
+ button_icon_state = "cancel_peephole"
+
+/datum/action/peepholeCancel/Trigger()
+ . = ..()
+ to_chat(owner, "You move away from the peephole. ")
+ owner.reset_perspective()
+ owner.clear_fullscreen("remote_view", 0)
+ qdel(src)
+
+/area/hilbertshotel
+ name = "Hilbert's Hotel Room"
+ icon_state = "hilbertshotel"
+ requires_power = FALSE
+ has_gravity = TRUE
+ noteleport = TRUE
+ hidden = TRUE
+ unique = FALSE
+ dynamic_lighting = DYNAMIC_LIGHTING_FORCED
+ ambientsounds = list('sound/ambience/servicebell.ogg')
+ var/roomnumber = 0
+ var/obj/item/hilbertshotel/parentSphere
+ var/datum/turf_reservation/reservation
+ var/turf/storageTurf
+
+/area/hilbertshotel/Entered(atom/movable/AM)
+ . = ..()
+ if(istype(AM, /obj/item/hilbertshotel))
+ relocate(AM)
+ var/list/obj/item/hilbertshotel/hotels = AM.GetAllContents(/obj/item/hilbertshotel)
+ for(var/obj/item/hilbertshotel/H in hotels)
+ if(parentSphere == H)
+ relocate(H)
+
+/area/hilbertshotel/proc/relocate(obj/item/hilbertshotel/H)
+ if(prob(0.135685)) //Because screw you
+ qdel(H)
+ return
+ var/turf/targetturf = find_safe_turf()
+ if(!targetturf)
+ if(GLOB.blobstart.len > 0)
+ targetturf = get_turf(pick(GLOB.blobstart))
+ else
+ CRASH("Unable to find a blobstart landmark")
+ var/turf/T = get_turf(H)
+ var/area/A = T.loc
+ log_game("[H] entered itself. Moving it to [loc_name(targetturf)].")
+ message_admins("[H] entered itself. Moving it to [ADMIN_VERBOSEJMP(targetturf)].")
+ for(var/mob/M in A)
+ to_chat(M, "[H] almost implodes in upon itself, but quickly rebounds, shooting off into a random point in space! ")
+ H.forceMove(targetturf)
+
+/area/hilbertshotel/Exited(atom/movable/AM)
+ . = ..()
+ if(ismob(AM))
+ var/mob/M = AM
+ if(M.mind)
+ var/stillPopulated = FALSE
+ var/list/currentLivingMobs = GetAllContents(/mob/living) //Got to catch anyone hiding in anything
+ for(var/mob/living/L in currentLivingMobs) //Check to see if theres any sentient mobs left.
+ if(L.mind)
+ stillPopulated = TRUE
+ break
+ if(!stillPopulated)
+ storeRoom()
+
+/area/hilbertshotel/proc/storeRoom()
+ var/roomSize = (reservation.top_right_coords[1]-reservation.bottom_left_coords[1]+1)*(reservation.top_right_coords[2]-reservation.bottom_left_coords[2]+1)
+ var/storage[roomSize]
+ var/turfNumber = 1
+ var/obj/item/abstracthotelstorage/storageObj = new(storageTurf)
+ storageObj.roomNumber = roomnumber
+ storageObj.parentSphere = parentSphere
+ storageObj.name = "Room [roomnumber] Storage"
+ for(var/i=0, iIt's to far away to scan! ")
+ return
+ var/obj/item/hilbertshotel/sphere = target
+ if(sphere.activeRooms.len)
+ to_chat(user, "Currently Occupied Rooms:")
+ for(var/roomnumber in sphere.activeRooms)
+ to_chat(user, roomnumber)
+ else
+ to_chat(user, "No currenty occupied rooms.")
+ if(sphere.storedRooms.len)
+ to_chat(user, "Vacated Rooms:")
+ for(var/roomnumber in sphere.storedRooms)
+ to_chat(user, roomnumber)
+ else
+ to_chat(user, "No vacated rooms.")
+
+/obj/effect/mob_spawn/human/doctorhilbert
+ name = "Doctor Hilbert"
+ mob_name = "Doctor Hilbert"
+ mob_gender = "male"
+ assignedrole = null
+ ghost_usable = FALSE
+ oxy_damage = 500
+ mob_species = /datum/species/skeleton
+ id_job = "Head Researcher"
+ id_access = ACCESS_RESEARCH
+ id_access_list = list(ACCESS_AWAY_GENERIC3, ACCESS_RESEARCH)
+ instant = TRUE
+ id = /obj/item/card/id/silver
+ uniform = /obj/item/clothing/under/rank/research_director
+ shoes = /obj/item/clothing/shoes/sneakers/brown
+ back = /obj/item/storage/backpack/satchel/leather
+ suit = /obj/item/clothing/suit/toggle/labcoat
+
+/obj/item/paper/crumpled/docslogs
+ name = "Research Logs"
+
+/obj/item/paper/crumpled/docslogs/Initialize()
+ . = ..()
+ GLOB.hhmysteryRoomNumber = rand(1, SHORT_REAL_LIMIT)
+ info = {"Research Logs
+ I might just be onto something here!
+ The strange space-warping properties of bluespace have been known about for awhile now, but I might be on the verge of discovering a new way of harnessing it.
+ It's too soon to say for sure, but this might be the start of something quite important!
+ I'll be sure to log any major future breakthroughs. This might be a lot more than I can manage on my own, perhaps I should hire that secretary after all...
+ Breakthrough!
+ I can't believe it, but I did it! Just when I was certain it couldn't be done, I made the final necessary breakthrough.
+ Exploiting the effects of space dilation caused by specific bluespace structures combined with a precise use of geometric calculus, I've discovered a way to correlate an infinite amount of space within a finite area!
+ While the potential applications are endless, I utilized it in quite a nifty way so far by designing a system that recursively constructs subspace rooms and spatially links them to any of the infinite infinitesimally distinct points on the spheres surface.
+ I call it: Hilbert's Hotel!
+ Goodbye
+ I can't take this anymore. I know what happens next, and the fear of what is coming leaves me unable to continue working.
+ Any fool in my field has heard the stories. It's not that I didn't believe them, it's just... I guess I underestimated the importance of my own research...
+ Robert has reported a further increase in frequency of the strange, prying visitors who ask questions they have no business asking. I've requested him to keep everything on strict lockdown and have permanently dismissed all other assistants.
+ I've also instructed him to use the encryption method we discussed for any important quantitative data. The poor lad... I don't think he truly understands what he's gotten himself into...
+ It's clear what happens now. One day they'll show up uninvited, and claim my research as their own, leaving me as nothing more than a bullet ridden corpse floating in space.
+ I can't stick around to the let that happen.
+ I'm escaping into the very thing that brought all this trouble to my doorstep in the first place - my hotel.
+ I'll be in [uppertext(num2hex(GLOB.hhmysteryRoomNumber, 0))] (That will make sense to anyone who should know)
+ I'm sorry that I must go like this. Maybe one day things will be different and it will be safe to return... maybe...
+ Goodbye
+
+ Doctor Hilbert "}
+
+/obj/item/paper/crumpled/robertsworkjournal
+ name = "Work Journal"
+ info = {"First Week!
+ First week on the new job. It's a secretarial position, but hey, whatever pays the bills. Plus it seems like some interesting stuff goes on here.
+ Doc says its best that I don't openly talk about his research with others, I guess he doesn't want it getting out or something. I've caught myself slipping a few times when talking to others, it's hard not to brag about something this cool!
+ I'm not really sure why I'm choosing to journal this. Doc seems to log everything. He says it's incase he discovers anything important.
+ I guess that's why I'm doing it too, I've always wanted to be a part of something important.
+ Here's to a new job and to becoming a part of something important!
+ Weird times...
+ Things are starting to get a little strange around here. Just weeks after Doc's amazing breakthrough, weird visitors have began showing up unannounced, asking strange things about Doc's work.
+ I knew Doc wasn't a big fan of company, but even he seemed strangely unnerved when I told him about the visitors.
+ He said it's important that from here on out we keep tight security on everything, even other staff members.
+ He also said something about securing data, something about hexes. What's that mean? Some sort of curse? Doc never struck me as the magic type...
+ He often uses a lot of big sciencey words that I don't really understand, but I kinda dig it, it makes me feel like I'm witnessing something big.
+ I hope things go back to normal soon, but I guess that's the price you pay for being a part of something important.
+ Last day I guess?
+ Things are officially starting to get too strange for me.
+ The visitors have been coming a lot more often, and they all seem increasingly aggressive and nosey. I'm starting to see why they made Doc so nervous, they're certainly starting to creep me out too.
+ Awhile ago Doc started having me keep the place on strict lockdown and requested I refuse entry to anyone else, including previous staff.
+ But the weirdest part?
+ I haven't seen Doc in days. It's not unusual for him to work continuously for long periods of time in the lab, but when I took a peak in their yesterday - he was nowhere to be seen! I didn't risk prying much further, Doc had a habit of leaving the defense systems on these last few weeks.
+ I'm thinking it might be time to call it quits. Can't work much without a boss, plus things are starting to get kind of shady. I wanted to be a part of something important, but you gotta know when to play it safe.
+ As my dad always said, "The smart get famous, but the wise survive..."
+
+ Robert P. "}
+
+/obj/item/paper/crumpled/bloody/docsdeathnote
+ name = "note"
+ info = {"This is it isn't it?
+ No one's coming to help, that much has become clear.
+ Sure, it's lonely, but do I have much choice? At least I brought the analyzer with me, they shouldn't be able to find me without it.
+ Who knows who's waiting for me out there. Its either die out there in their hands, or die a slower, slightly more comfortable death in here.
+ Everyday I can feel myself slipping away more and more, both physically and mentally. Who knows what happens now...
+ Heh, so it's true then, this must be the inescapable path of all great minds... so be it then.
+
+
+
+ Choose a room, and enter the sphere
+ Lay your head to rest, it soon becomes clear
+ There's always more room around every bend
+ Not all that's countable has an end..."}
diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm
index 119023d465..b581a54095 100644
--- a/code/modules/shuttle/emergency.dm
+++ b/code/modules/shuttle/emergency.dm
@@ -232,7 +232,7 @@
SSshuttle.emergencyLastCallLoc = null
if(!silent)
- priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlecalled.ogg', "Priority")
+ priority_announce("The emergency shuttle has been called. [redAlert ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [timeLeft(600)] minutes.[reason][SSshuttle.emergencyLastCallLoc ? "\n\nCall signal traced. Results can be viewed on any communications console." : "" ]", null, "shuttlecalled", "Priority")
/obj/docking_port/mobile/emergency/cancel(area/signalOrigin)
if(mode != SHUTTLE_CALL)
@@ -247,7 +247,7 @@
SSshuttle.emergencyLastCallLoc = signalOrigin
else
SSshuttle.emergencyLastCallLoc = null
- priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, 'sound/ai/shuttlerecalled.ogg', "Priority")
+ priority_announce("The emergency shuttle has been recalled.[SSshuttle.emergencyLastCallLoc ? " Recall signal traced. Results can be viewed on any communications console." : "" ]", null, "shuttlerecalled", "Priority")
/obj/docking_port/mobile/emergency/proc/is_hijacked()
var/has_people = FALSE
@@ -319,7 +319,7 @@
mode = SHUTTLE_DOCKED
setTimer(SSshuttle.emergencyDockTime)
send2irc("Server", "The Emergency Shuttle has docked with the station.")
- priority_announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, 'sound/ai/shuttledock.ogg', "Priority")
+ priority_announce("The Emergency Shuttle has docked with the station. You have [timeLeft(600)] minutes to board the Emergency Shuttle.", null, "shuttledock", "Priority")
ShuttleDBStuff()
diff --git a/code/modules/shuttle/on_move.dm b/code/modules/shuttle/on_move.dm
index dd2d7483e3..121ee2e07f 100644
--- a/code/modules/shuttle/on_move.dm
+++ b/code/modules/shuttle/on_move.dm
@@ -290,7 +290,7 @@ All ShuttleMove procs go here
// ignores the movement of the shuttle from the staging area on CentCom to
// the station as it is loaded in.
if (oldT && !is_centcom_level(oldT.z))
- GET_COMPONENT(STR, /datum/component/storage/concrete/emergency)
+ var/datum/component/storage/concrete/emergency/STR = GetComponent(/datum/component/storage/concrete/emergency)
STR?.unlock_me()
/************************************Mob move procs************************************/
diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm
index 9bea790957..ab08c162a1 100644
--- a/code/modules/shuttle/special.dm
+++ b/code/modules/shuttle/special.dm
@@ -187,7 +187,7 @@
var/mob/living/M = AM
var/throwtarget = get_edge_target_turf(src, boot_dir)
M.Knockdown(40)
- M.throw_at(throwtarget, 5, 1,src)
+ M.throw_at(throwtarget, 5, 1)
to_chat(M, "No climbing on the bar please. ")
else
. = ..()
diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm
index 2249f5f10e..32c38451c5 100644
--- a/code/modules/shuttle/supply.dm
+++ b/code/modules/shuttle/supply.dm
@@ -24,7 +24,8 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
/obj/effect/portal,
/obj/item/shared_storage,
/obj/structure/extraction_point,
- /obj/machinery/syndicatebomb
+ /obj/machinery/syndicatebomb,
+ /obj/item/hilbertshotel
)))
/obj/docking_port/mobile/supply
diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm
index 98eb6f56bf..22dee60eb4 100644
--- a/code/modules/spells/spell.dm
+++ b/code/modules/spells/spell.dm
@@ -115,6 +115,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
var/nonabstract_req = 0 //spell can only be cast by mobs that are physical entities
var/stat_allowed = 0 //see if it requires being conscious/alive, need to set to 1 for ghostpells
var/phase_allowed = 0 // If true, the spell can be cast while phased, eg. blood crawling, ethereal jaunting
+ var/antimagic_allowed = TRUE // If false, the spell cannot be cast while under the effect of antimagic
var/invocation = "HURP DURP" //what is uttered when the wizard casts the spell
var/invocation_emote_self = null
var/invocation_type = "none" //can be none, whisper, emote and shout
@@ -147,27 +148,36 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(player_lock)
if(!user.mind || !(src in user.mind.spell_list) && !(src in user.mob_spell_list))
to_chat(user, "You shouldn't have this spell! Something's wrong. ")
- return 0
+ return FALSE
else
if(!(src in user.mob_spell_list))
- return 0
+ return FALSE
var/turf/T = get_turf(user)
if(is_centcom_level(T.z) && !centcom_cancast) //Certain spells are not allowed on the centcom zlevel
to_chat(user, "You can't cast this spell here. ")
- return 0
+ return FALSE
if(!skipcharge)
if(!charge_check(user))
- return 0
+ return FALSE
if(user.stat && !stat_allowed)
to_chat(user, "Not when you're incapacitated. ")
- return 0
+ return FALSE
+
+ if(!antimagic_allowed)
+ var/antimagic = user.anti_magic_check(TRUE, FALSE, chargecost = 0, self = TRUE)
+ if(antimagic)
+ if(isitem(antimagic))
+ to_chat(user, "[antimagic] is interfering with your magic. ")
+ else
+ to_chat(user, "Magic seems to flee from you, you can't gather enough power to cast this spell. ")
+ return FALSE
if(!phase_allowed && istype(user.loc, /obj/effect/dummy))
to_chat(user, "[name] cannot be cast unless you are completely manifested in the material plane. ")
- return 0
+ return FALSE
if(ishuman(user))
@@ -175,7 +185,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if((invocation_type == "whisper" || invocation_type == "shout") && !H.can_speak_vocal())
to_chat(user, "You can't get the words out! ")
- return 0
+ return FALSE
var/list/casting_clothes = typecacheof(list(/obj/item/clothing/suit/wizrobe,
/obj/item/clothing/suit/space/hardsuit/wizard,
@@ -187,24 +197,24 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(clothes_req) //clothes check
if(!is_type_in_typecache(H.wear_suit, casting_clothes))
to_chat(H, "I don't feel strong enough without my robe. ")
- return 0
+ return FALSE
if(!is_type_in_typecache(H.head, casting_clothes))
to_chat(H, "I don't feel strong enough without my hat. ")
- return 0
+ return FALSE
if(cult_req) //CULT_REQ CLOTHES CHECK
if(!istype(H.wear_suit, /obj/item/clothing/suit/magusred) && !istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit/cult))
to_chat(H, "I don't feel strong enough without my armor. ")
- return 0
+ return FALSE
if(!istype(H.head, /obj/item/clothing/head/magus) && !istype(H.head, /obj/item/clothing/head/helmet/space/hardsuit/cult))
to_chat(H, "I don't feel strong enough without my helmet. ")
- return 0
+ return FALSE
else
if(clothes_req || human_req)
to_chat(user, "This spell can only be cast by humans! ")
- return 0
+ return FALSE
if(nonabstract_req && (isbrain(user) || ispAI(user)))
to_chat(user, "This spell can only be cast by physical beings! ")
- return 0
+ return FALSE
if(!skipcharge)
@@ -499,6 +509,9 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for th
if(user.stat && !stat_allowed)
return FALSE
+ if(!antimagic_allowed && user.anti_magic_check(TRUE, FALSE, chargecost = 0, self = TRUE))
+ return FALSE
+
if(!ishuman(user))
if(clothes_req || human_req)
return FALSE
diff --git a/code/modules/spells/spell_types/construct_spells.dm b/code/modules/spells/spell_types/construct_spells.dm
index bb3cc1f7e3..0c0b20f0fc 100644
--- a/code/modules/spells/spell_types/construct_spells.dm
+++ b/code/modules/spells/spell_types/construct_spells.dm
@@ -146,7 +146,7 @@
clothes_req = 0
invocation = "none"
invocation_type = "none"
- proj_type = /obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile/lesser
+ proj_type = "/obj/effect/proc_holder/spell/targeted/inflict_handler/magic_missile/lesser"
proj_lifespan = 10
max_targets = 6
action_icon_state = "magicm"
diff --git a/code/modules/spells/spell_types/forcewall.dm b/code/modules/spells/spell_types/forcewall.dm
index 47d6f71f9b..ed78e3315a 100644
--- a/code/modules/spells/spell_types/forcewall.dm
+++ b/code/modules/spells/spell_types/forcewall.dm
@@ -35,6 +35,6 @@
return TRUE
if(ismob(mover))
var/mob/M = mover
- if(M.anti_magic_check())
+ if(M.anti_magic_check(chargecost = 0))
return TRUE
return FALSE
diff --git a/code/modules/spells/spell_types/lichdom.dm b/code/modules/spells/spell_types/lichdom.dm
index efc80101f6..0cbb3a8272 100644
--- a/code/modules/spells/spell_types/lichdom.dm
+++ b/code/modules/spells/spell_types/lichdom.dm
@@ -57,7 +57,7 @@
new /obj/item/phylactery(marked_item, M.mind)
to_chat(M, "With a hideous feeling of emptiness you watch in horrified fascination as skin sloughs off bone! Blood boils, nerves disintegrate, eyes boil in their sockets! As your organs crumble to dust in your fleshless chest you come to terms with your choice. You're a lich! ")
- M.set_species(/datum/species/skeleton)
+ M.set_species(/datum/species/skeleton/space)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.dropItemToGround(H.w_uniform)
@@ -132,7 +132,7 @@
lich.real_name = mind.name
mind.transfer_to(lich)
mind.grab_ghost(force=TRUE)
- lich.hardset_dna(null,null,lich.real_name,null, new /datum/species/skeleton)
+ lich.hardset_dna(null,null,lich.real_name,null, new /datum/species/skeleton/space)
to_chat(lich, "Your bones clatter and shudder as you are pulled back into this world! ")
var/turf/body_turf = get_turf(old_body)
lich.Knockdown(200 + 200*resurrections)
diff --git a/code/modules/spells/spell_types/mind_transfer.dm b/code/modules/spells/spell_types/mind_transfer.dm
index ffdd270994..d78b32c643 100644
--- a/code/modules/spells/spell_types/mind_transfer.dm
+++ b/code/modules/spells/spell_types/mind_transfer.dm
@@ -61,7 +61,7 @@ Also, you never added distance checking after target is selected. I've went ahea
return
var/datum/mind/TM = target.mind
- if((target.anti_magic_check() || TM.has_antag_datum(/datum/antagonist/wizard) || TM.has_antag_datum(/datum/antagonist/cult) || TM.has_antag_datum(/datum/antagonist/clockcult) || TM.has_antag_datum(/datum/antagonist/changeling) || TM.has_antag_datum(/datum/antagonist/rev)) || cmptext(copytext(target.key,1,2),"@"))
+ if((target.anti_magic_check(TRUE, FALSE) || TM.has_antag_datum(/datum/antagonist/wizard) || TM.has_antag_datum(/datum/antagonist/cult) || TM.has_antag_datum(/datum/antagonist/clockcult) || TM.has_antag_datum(/datum/antagonist/changeling) || TM.has_antag_datum(/datum/antagonist/rev)) || cmptext(copytext(target.key,1,2),"@"))
if(!silent)
to_chat(user, "[target.p_their(TRUE)] mind is resisting your spell! ")
return
@@ -70,12 +70,12 @@ Also, you never added distance checking after target is selected. I've went ahea
var/mob/living/caster = user//The wizard/whomever doing the body transferring.
//MIND TRANSFER BEGIN
- var/mob/dead/observer/ghost = victim.ghostize(0)
+ var/mob/dead/observer/ghost = victim.ghostize(FALSE, TRUE)
caster.mind.transfer_to(victim)
ghost.mind.transfer_to(caster)
if(ghost.key)
- caster.key = ghost.key //have to transfer the key since the mind was not active
+ ghost.transfer_ckey(caster) //have to transfer the key since the mind was not active
qdel(ghost)
//MIND TRANSFER END
diff --git a/code/modules/spells/spell_types/shapeshift.dm b/code/modules/spells/spell_types/shapeshift.dm
index 1576c55326..46eb14013f 100644
--- a/code/modules/spells/spell_types/shapeshift.dm
+++ b/code/modules/spells/spell_types/shapeshift.dm
@@ -13,7 +13,7 @@
var/revert_on_death = TRUE
var/die_with_shapeshifted_form = TRUE
- var/convert_damage = FALSE //If you want to convert the caster's health to the shift, and vice versa.
+ var/convert_damage = TRUE //If you want to convert the caster's health to the shift, and vice versa.
var/convert_damage_type = BRUTE //Since simplemobs don't have advanced damagetypes, what to convert damage back into.
var/shapeshift_type
var/list/possible_shapes = list(/mob/living/simple_animal/mouse,\
@@ -101,8 +101,10 @@
stored.forceMove(src)
stored.notransform = TRUE
if(source.convert_damage)
- var/damapply = (stored.maxHealth - (stored.health + stored.maxHealth)/2) //Carbons go from -100 to 100 naturally, while simplemobs only go from 0 to 100. Can't do a direct conversion.
- shape.apply_damage(damapply, source.convert_damage_type)
+ var/damage_percent = (stored.maxHealth - stored.health)/stored.maxHealth;
+ var/damapply = damage_percent * shape.maxHealth;
+
+ shape.apply_damage(damapply, source.convert_damage_type, forced = TRUE);
slink = soullink(/datum/soullink/shapeshift, stored , shape)
slink.source = src
@@ -152,8 +154,10 @@
stored.death()
else if(source.convert_damage)
stored.revive(full_heal = TRUE)
- var/damapply = (shape.maxHealth - 2*shape.health) //Since we halved incoming damage, double outgoing.
- stored.apply_damage(damapply, source.convert_damage_type)
+ var/damage_percent = (shape.maxHealth - shape.health)/shape.maxHealth;
+ var/damapply = stored.maxHealth * damage_percent
+
+ stored.apply_damage(damapply, source.convert_damage_type, forced = TRUE)
qdel(shape)
qdel(src)
diff --git a/code/modules/spells/spell_types/spacetime_distortion.dm b/code/modules/spells/spell_types/spacetime_distortion.dm
index 7fd857dc51..7a19787675 100644
--- a/code/modules/spells/spell_types/spacetime_distortion.dm
+++ b/code/modules/spells/spell_types/spacetime_distortion.dm
@@ -86,7 +86,7 @@
/obj/effect/cross_action/spacetime_dist/proc/walk_link(atom/movable/AM)
if(ismob(AM))
var/mob/M = AM
- if(M.anti_magic_check())
+ if(M.anti_magic_check(chargecost = 0))
return
if(linked_dist && walks_left > 0)
flick("purplesparkles", src)
diff --git a/code/modules/spells/spell_types/summonitem.dm b/code/modules/spells/spell_types/summonitem.dm
index 6d46c53a9d..7d9823e29b 100644
--- a/code/modules/spells/spell_types/summonitem.dm
+++ b/code/modules/spells/spell_types/summonitem.dm
@@ -61,6 +61,10 @@
organ.Remove(organ.owner)
else
while(!isturf(item_to_retrieve.loc) && infinite_recursion < 10) //if it's in something you get the whole thing.
+ if(isitem(item_to_retrieve.loc))
+ var/obj/item/I = item_to_retrieve.loc
+ if(I.item_flags & ABSTRACT) //Being able to summon abstract things because your item happened to get placed there is a no-no
+ break
if(ismob(item_to_retrieve.loc)) //If its on someone, properly drop it
var/mob/M = item_to_retrieve.loc
diff --git a/code/modules/spells/spell_types/telepathy.dm b/code/modules/spells/spell_types/telepathy.dm
new file mode 100644
index 0000000000..34f100f753
--- /dev/null
+++ b/code/modules/spells/spell_types/telepathy.dm
@@ -0,0 +1,32 @@
+/obj/effect/proc_holder/spell/targeted/telepathy
+ name = "Telepathy"
+ desc = "Telepathically transmits a message to the target."
+ charge_max = 0
+ clothes_req = 0
+ range = 7
+ include_user = 0
+ action_icon = 'icons/mob/actions/actions_revenant.dmi'
+ action_icon_state = "r_transmit"
+ action_background_icon_state = "bg_spell"
+ var/notice = "notice"
+ var/boldnotice = "boldnotice"
+ var/magic_check = FALSE
+ var/holy_check = FALSE
+ var/tinfoil_check = TRUE
+
+/obj/effect/proc_holder/spell/targeted/telepathy/cast(list/targets, mob/living/user = usr)
+ for(var/mob/living/M in targets)
+ var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
+ if(!msg)
+ charge_counter = charge_max
+ return
+ log_directed_talk(user, M, msg, LOG_SAY, "[name]")
+ to_chat(user, "You transmit to [M]: [msg] ")
+ if(!M.anti_magic_check(magic_check, holy_check, tinfoil_check, 0)) //hear no evil
+ to_chat(M, "You hear something behind you talking... [msg] ")
+ for(var/ded in GLOB.dead_mob_list)
+ if(!isobserver(ded))
+ continue
+ var/follow_rev = FOLLOW_LINK(ded, user)
+ var/follow_whispee = FOLLOW_LINK(ded, M)
+ to_chat(ded, "[follow_rev] [user] [name]: \"[msg]\" to [follow_whispee] [M] ")
diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm
index 3073a6fcc3..2aae17b0f3 100644
--- a/code/modules/station_goals/dna_vault.dm
+++ b/code/modules/station_goals/dna_vault.dm
@@ -276,7 +276,7 @@
ADD_TRAIT(H, TRAIT_PIERCEIMMUNE, "dna_vault")
if(VAULT_SPEED)
to_chat(H, "Your legs feel faster. ")
- ADD_TRAIT(H, TRAIT_GOTTAGOFAST, "dna_vault")
+ H.add_movespeed_modifier(MOVESPEED_ID_DNA_VAULT, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING))
if(VAULT_QUICK)
to_chat(H, "Your arms move as fast as lightning. ")
H.next_move_modifier = 0.5
diff --git a/code/modules/station_goals/station_goal.dm b/code/modules/station_goals/station_goal.dm
index 88377455c6..b68fef3e2f 100644
--- a/code/modules/station_goals/station_goal.dm
+++ b/code/modules/station_goals/station_goal.dm
@@ -12,7 +12,7 @@
var/report_message = "Complete this goal."
/datum/station_goal/proc/send_report()
- priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", 'sound/ai/commandreport.ogg')
+ priority_announce("Priority Nanotrasen directive received. Project \"[name]\" details inbound.", "Incoming Priority Message", "commandreport")
print_command_report(get_report(),"Nanotrasen Directive [pick(GLOB.phonetic_alphabet)] \Roman[rand(1,50)]", announce=FALSE)
on_report()
diff --git a/code/modules/surgery/advanced/bioware/bioware_surgery.dm b/code/modules/surgery/advanced/bioware/bioware_surgery.dm
index 86817b9b09..eb8f739193 100644
--- a/code/modules/surgery/advanced/bioware/bioware_surgery.dm
+++ b/code/modules/surgery/advanced/bioware/bioware_surgery.dm
@@ -5,6 +5,8 @@
/datum/surgery/advanced/bioware/can_start(mob/user, mob/living/carbon/human/target)
if(!..())
return FALSE
+ if(!istype(target))
+ return FALSE
for(var/X in target.bioware)
var/datum/bioware/B = X
if(B.mod_type == bioware_target)
diff --git a/code/modules/surgery/advanced/bioware/experimental_dissection.dm b/code/modules/surgery/advanced/bioware/experimental_dissection.dm
deleted file mode 100644
index 6266480baf..0000000000
--- a/code/modules/surgery/advanced/bioware/experimental_dissection.dm
+++ /dev/null
@@ -1,72 +0,0 @@
-/datum/surgery/advanced/bioware/experimental_dissection
- name = "Experimental Dissection"
- desc = "A surgical procedure which deeply analyzes the biology of a corpse, and automatically adds new findings to the research database."
- steps = list(/datum/surgery_step/incise,
- /datum/surgery_step/retract_skin,
- /datum/surgery_step/clamp_bleeders,
- /datum/surgery_step/incise,
- /datum/surgery_step/dissection,
- /datum/surgery_step/close)
- possible_locs = list(BODY_ZONE_CHEST)
- bioware_target = BIOWARE_DISSECTION
-
-/datum/surgery/advanced/bioware/experimental_dissection/can_start(mob/user, mob/living/carbon/target)
- . = ..()
- if(iscyborg(user))
- return FALSE //robots cannot be creative
- //(also this surgery shouldn't be consistently successful, and cyborgs have a 100% success rate on surgery)
- if(target.stat != DEAD)
- return FALSE
-
-/datum/surgery_step/dissection
- name = "dissection"
- implements = list(/obj/item/scalpel = 60, /obj/item/kitchen/knife = 30, /obj/item/shard = 15)
- time = 125
-
-/datum/surgery_step/dissection/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- display_results(user, target, "You start dissecting [target]. ",
- "[user] starts dissecting [target].",
- "[user] starts dissecting [target].")
-
-/datum/surgery_step/dissection/proc/check_value(mob/living/carbon/target)
- if(isalienroyal(target))
- return 10000
- else if(isalienadult(target))
- return 5000
- else if(ismonkey(target))
- return 1000
- else if(ishuman(target))
- var/mob/living/carbon/human/H = target
- if(H.dna && H.dna.species)
- if(isabductor(H))
- return 8000
- if(isgolem(H) || iszombie(H))
- return 4000
- if(isjellyperson(H) || ispodperson(H))
- return 3000
- return 2000
-
-/datum/surgery_step/dissection/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- display_results(user, target, "You dissect [target], and add your discoveries to the research database! ",
- "[user] dissects [target], adding [user.p_their()] discoveries to the research database!",
- "[user] dissects [target]!")
- SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = check_value(target)))
- var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
- target.apply_damage(80, BRUTE, L)
- new /datum/bioware/dissected(target)
- return TRUE
-
-/datum/surgery_step/dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- display_results(user, target, "You dissect [target], but do not find anything particularly interesting. ",
- "[user] dissects [target], however it seems [user.p_they()] didn't find anything useful.",
- "[user] dissects [target], but looks a little dissapointed.")
- SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = (check_value(target) * 0.2)))
- var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
- target.apply_damage(80, BRUTE, L)
- new /datum/bioware/dissected(target)
- return TRUE
-
-/datum/bioware/dissected
- name = "Dissected"
- desc = "This body has been dissected and analyzed. It is no longer worth experimenting on."
- mod_type = BIOWARE_DISSECTION
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/bioware/muscled_veins.dm b/code/modules/surgery/advanced/bioware/muscled_veins.dm
new file mode 100644
index 0000000000..81212019a8
--- /dev/null
+++ b/code/modules/surgery/advanced/bioware/muscled_veins.dm
@@ -0,0 +1,42 @@
+/datum/surgery/advanced/bioware/muscled_veins
+ name = "Vein Muscle Membrane"
+ desc = "A surgical procedure which adds a muscled membrane to blood vessels, allowing them to pump blood without a heart."
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/muscled_veins,
+ /datum/surgery_step/close)
+ possible_locs = list(BODY_ZONE_CHEST)
+ bioware_target = BIOWARE_CIRCULATION
+
+/datum/surgery_step/muscled_veins
+ name = "shape vein muscles"
+ accept_hand = TRUE
+ time = 125
+
+/datum/surgery_step/muscled_veins/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You start wrapping muscles around [target]'s circulatory system. ",
+ "[user] starts wrapping muscles around [target]'s circulatory system.",
+ "[user] starts manipulating [target]'s circulatory system.")
+
+/datum/surgery_step/muscled_veins/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You reshape [target]'s circulatory system, adding a muscled membrane! ",
+ "[user] reshapes [target]'s circulatory system, adding a muscled membrane!",
+ "[user] finishes manipulating [target]'s circulatory system.")
+ new /datum/bioware/muscled_veins(target)
+ return TRUE
+
+/datum/bioware/muscled_veins
+ name = "Threaded Veins"
+ desc = "The circulatory system is woven into a mesh, severely reducing the amount of blood lost from wounds."
+ mod_type = BIOWARE_CIRCULATION
+
+/datum/bioware/muscled_veins/on_gain()
+ ..()
+ ADD_TRAIT(owner, TRAIT_STABLEHEART, "muscled_veins")
+
+/datum/bioware/muscled_veins/on_lose()
+ ..()
+ REMOVE_TRAIT(owner, TRAIT_STABLEHEART, "muscled_veins")
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/brainwashing.dm b/code/modules/surgery/advanced/brainwashing.dm
index 730a912189..b067cce56b 100644
--- a/code/modules/surgery/advanced/brainwashing.dm
+++ b/code/modules/surgery/advanced/brainwashing.dm
@@ -12,9 +12,10 @@
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/brainwash,
/datum/surgery_step/close)
-
- species = list(/mob/living/carbon/human)
+
+ target_mobtypes = list(/mob/living/carbon/human)
possible_locs = list(BODY_ZONE_HEAD)
+
/datum/surgery/advanced/brainwashing/can_start(mob/user, mob/living/carbon/target)
if(!..())
return FALSE
@@ -24,7 +25,7 @@
return TRUE
/datum/surgery_step/brainwash
name = "brainwash"
- implements = list(/obj/item/hemostat = 85, TOOL_WIRECUTTER = 50, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
+ implements = list(TOOL_HEMOSTAT = 85, TOOL_WIRECUTTER = 50, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
time = 200
var/objective
/datum/surgery_step/brainwash/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -56,7 +57,7 @@
display_results(user, target, "You screw up, bruising the brain tissue! ",
"[user] screws up, causing brain damage! ",
"[user] completes the surgery on [target]'s brain.")
- target.adjustBrainLoss(40)
+ target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 40)
else
user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore. ")
return FALSE
diff --git a/code/modules/surgery/advanced/lobotomy.dm b/code/modules/surgery/advanced/lobotomy.dm
index 1c09f5f7da..0149fc6c27 100644
--- a/code/modules/surgery/advanced/lobotomy.dm
+++ b/code/modules/surgery/advanced/lobotomy.dm
@@ -9,7 +9,7 @@
/datum/surgery_step/lobotomize,
/datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_HEAD)
requires_bodypart_type = 0
/datum/surgery/advanced/lobotomy/can_start(mob/user, mob/living/carbon/target)
@@ -21,11 +21,11 @@
return TRUE
/datum/surgery_step/lobotomize
name = "perform lobotomy"
- implements = list(/obj/item/scalpel = 85, /obj/item/melee/transforming/energy/sword = 55, /obj/item/kitchen/knife = 35,
+ implements = list(TOOL_SCALPEL = 85, /obj/item/melee/transforming/energy/sword = 55, /obj/item/kitchen/knife = 35,
/obj/item/shard = 25, /obj/item = 20)
time = 100
/datum/surgery_step/lobotomize/tool_check(mob/user, obj/item/tool)
- if(implement_type == /obj/item && !tool.is_sharp())
+ if(implement_type == /obj/item && !tool.get_sharpness())
return FALSE
return TRUE
@@ -51,11 +51,12 @@
return TRUE
/datum/surgery_step/lobotomize/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- if(target.getorganslot(ORGAN_SLOT_BRAIN))
+ var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
+ if(B)
display_results(user, target, "You remove the wrong part, causing more damage! ",
"[user] successfully lobotomizes [target]!",
"[user] completes the surgery on [target]'s brain.")
- target.adjustBrainLoss(80)
+ B.applyOrganDamage(80)
switch(rand(1,3))
if(1)
target.gain_trauma_type(BRAIN_TRAUMA_MILD, TRAUMA_RESILIENCE_MAGIC)
diff --git a/code/modules/surgery/advanced/necrotic_revival.dm b/code/modules/surgery/advanced/necrotic_revival.dm
index 8c57930252..f8fb160a8a 100644
--- a/code/modules/surgery/advanced/necrotic_revival.dm
+++ b/code/modules/surgery/advanced/necrotic_revival.dm
@@ -16,7 +16,7 @@
/datum/surgery_step/bionecrosis
name = "start bionecrosis"
- implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30)
time = 50
chems_needed = list("zombiepowder", "rezadone")
diff --git a/code/modules/surgery/advanced/pacification.dm b/code/modules/surgery/advanced/pacification.dm
index d5585d71a8..866c85842b 100644
--- a/code/modules/surgery/advanced/pacification.dm
+++ b/code/modules/surgery/advanced/pacification.dm
@@ -7,7 +7,8 @@
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/pacify,
/datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_HEAD)
requires_bodypart_type = 0
/datum/surgery/advanced/pacify/can_start(mob/user, mob/living/carbon/target)
@@ -17,7 +18,7 @@
return FALSE
/datum/surgery_step/pacify
name = "rewire brain"
- implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
time = 40
/datum/surgery_step/pacify/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -37,4 +38,4 @@
"[user] screws up, causing brain damage! ",
"[user] completes the surgery on [target]'s brain.")
target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
- return FALSE
+ return FALSE
diff --git a/code/modules/surgery/advanced/reconstruction.dm b/code/modules/surgery/advanced/reconstruction.dm
deleted file mode 100644
index 84d9f5b9f8..0000000000
--- a/code/modules/surgery/advanced/reconstruction.dm
+++ /dev/null
@@ -1,35 +0,0 @@
-/datum/surgery/advanced/reconstruction
- name = "Reconstruction"
- desc = "A surgical procedure that gradually repairs damage done to a body without the assistance of chemicals. Unlike classic medicine, it is effective on corpses."
- steps = list(/datum/surgery_step/incise,
- /datum/surgery_step/incise,
- /datum/surgery_step/retract_skin,
- /datum/surgery_step/incise,
- /datum/surgery_step/clamp_bleeders,
- /datum/surgery_step/incise,
- /datum/surgery_step/retract_skin,
- /datum/surgery_step/reconstruct,
- /datum/surgery_step/close)
-
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
- possible_locs = list(BODY_ZONE_CHEST)
- requires_bodypart_type = 0
-
-/datum/surgery_step/reconstruct
- name = "repair body"
- implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
- repeatable = TRUE
- time = 25
-
-/datum/surgery_step/reconstruct/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] starts knitting some of [target]'s flesh back together.", "You start knitting some of [target]'s flesh back together. ")
-
-/datum/surgery_step/reconstruct/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] fixes some of [target]'s wounds.", "You succeed in fixing some of [target]'s wounds. ")
- target.heal_bodypart_damage(10,10)
- return TRUE
-
-/datum/surgery_step/reconstruct/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
- user.visible_message("[user] screws up!", "You screwed up! ")
- target.take_bodypart_damage(5,0)
- return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/advanced/revival.dm b/code/modules/surgery/advanced/revival.dm
index 01c30f174a..a2d5345ea4 100644
--- a/code/modules/surgery/advanced/revival.dm
+++ b/code/modules/surgery/advanced/revival.dm
@@ -8,7 +8,8 @@
/datum/surgery_step/incise,
/datum/surgery_step/revive,
/datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_HEAD)
requires_bodypart_type = 0
/datum/surgery/advanced/revival/can_start(mob/user, mob/living/carbon/target)
@@ -63,7 +64,7 @@
user.visible_message("...[target] wakes up, alive and aware!", "IT'S ALIVE! ")
target.visible_message("...[target] wakes up, alive and aware!")
target.emote("gasp")
- target.adjustBrainLoss(50, 199) //MAD SCIENCE
+ target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 50, 199) //MAD SCIENCE
return TRUE
else
user.visible_message("...[target.p_they()] convulses, then lies still.")
@@ -75,5 +76,5 @@
"[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.",
"[user] send a powerful shock to [target]'s brain with [tool], but [target.p_they()] doesn't react.")
playsound(get_turf(target), 'sound/magic/lightningbolt.ogg', 50, 1)
- target.adjustBrainLoss(15, 199)
+ target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 15, 199)
return FALSE
diff --git a/code/modules/surgery/advanced/toxichealing.dm b/code/modules/surgery/advanced/toxichealing.dm
index a82287831c..bb28a0fb05 100644
--- a/code/modules/surgery/advanced/toxichealing.dm
+++ b/code/modules/surgery/advanced/toxichealing.dm
@@ -1,6 +1,6 @@
/datum/surgery/advanced/toxichealing
name = "Body Rejuvenation"
- desc = "A surgical procedure that helps deal with oxygen deprecation, and treat toxic damaged. Works on corpses and alive alike without chemicals."
+ desc = "A surgical procedure that helps deal with oxygen deprivation, and treats parts damaged due to toxic compounds. Works on corpses and alive alike without chemicals."
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/incise,
/datum/surgery_step/retract_skin,
@@ -11,13 +11,13 @@
/datum/surgery_step/toxichealing,
/datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_CHEST)
requires_bodypart_type = 0
/datum/surgery_step/toxichealing
name = "rejuvenate body"
- implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
repeatable = TRUE
time = 25
diff --git a/code/modules/surgery/advanced/viral_bonding.dm b/code/modules/surgery/advanced/viral_bonding.dm
index b87d5e001c..87e6a8a99f 100644
--- a/code/modules/surgery/advanced/viral_bonding.dm
+++ b/code/modules/surgery/advanced/viral_bonding.dm
@@ -7,7 +7,8 @@
/datum/surgery_step/incise,
/datum/surgery_step/viral_bond,
/datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_CHEST)
/datum/surgery/advanced/viral_bonding/can_start(mob/user, mob/living/carbon/target)
if(!..())
@@ -17,13 +18,13 @@
return TRUE
/datum/surgery_step/viral_bond
name = "viral bond"
- implements = list(/obj/item/cautery = 100, TOOL_WELDER = 50, /obj/item = 30) // 30% success with any hot item.
+ implements = list(TOOL_CAUTERY = 100, TOOL_WELDER = 50, /obj/item = 30) // 30% success with any hot item.
time = 100
chems_needed = list("spaceacillin","virusfood","formaldehyde")
/datum/surgery_step/viral_bond/tool_check(mob/user, obj/item/tool)
if(implement_type == TOOL_WELDER || implement_type == /obj/item)
- return tool.is_hot()
+ return tool.get_temperature()
return TRUE
/datum/surgery_step/viral_bond/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm
index 01cf6ae112..5c77532188 100644
--- a/code/modules/surgery/amputation.dm
+++ b/code/modules/surgery/amputation.dm
@@ -1,12 +1,12 @@
/datum/surgery/amputation
name = "Amputation"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/sever_limb)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD)
requires_bodypart_type = 0
/datum/surgery_step/sever_limb
name = "sever limb"
- implements = list(/obj/item/scalpel = 100, /obj/item/circular_saw = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/melee/arm_blade = 80, /obj/item/twohanded/required/chainsaw = 80, /obj/item/mounted_chainsaw = 80, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25)
+ implements = list(TOOL_SCALPEL = 100, TOOL_SAW = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/melee/arm_blade = 80, /obj/item/twohanded/required/chainsaw = 80, /obj/item/mounted_chainsaw = 80, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 40, /obj/item/kitchen/knife/butcher = 25)
time = 64
/datum/surgery_step/sever_limb/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/bodyparts/bodyparts.dm b/code/modules/surgery/bodyparts/bodyparts.dm
index dffb7bf355..9aa89dcaf5 100644
--- a/code/modules/surgery/bodyparts/bodyparts.dm
+++ b/code/modules/surgery/bodyparts/bodyparts.dm
@@ -13,8 +13,7 @@
var/needs_processing = FALSE
var/body_zone //BODY_ZONE_CHEST, BODY_ZONE_L_ARM, etc , used for def_zone
- var/aux_zone // used for hands
- var/aux_layer
+ var/list/aux_icons // associative list, currently used for hands
var/body_part = null //bitflag used to check which clothes cover this bodypart
var/use_digitigrade = NOT_DIGITIGRADE //Used for alternate legs, useless elsewhere
var/list/embedded_objects = list()
@@ -434,9 +433,9 @@
. += image(body_markings_icon, "[body_markings]_[digitigrade_type]_[use_digitigrade]_[body_zone]", -MARKING_LAYER, image_dir)
var/image/limb = image(layer = -BODYPARTS_LAYER, dir = image_dir)
- var/image/aux
+ var/list/aux = list()
var/image/marking
- var/image/auxmarking
+ var/list/auxmarking = list()
. += limb
@@ -502,13 +501,15 @@
// Citadel End
- if(aux_zone)
- aux = image(limb.icon, "[species_id]_[aux_zone]", -aux_layer, image_dir)
- if(!isnull(aux_marking))
- if(species_id == "husk")
- auxmarking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[aux_zone]", -aux_layer, image_dir)
- else
- auxmarking = image(body_markings_icon, "[body_markings]_[aux_zone]", -aux_layer, image_dir)
+ if(aux_icons)
+ for(var/I in aux_icons)
+ var/aux_layer = aux_icons[I]
+ aux += image(limb.icon, "[species_id]_[I]", -aux_layer, image_dir)
+ if(!isnull(aux_marking))
+ if(species_id == "husk")
+ auxmarking += image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[I]", -aux_layer, image_dir)
+ else
+ auxmarking += image(body_markings_icon, "[body_markings]_[I]", -aux_layer, image_dir)
. += aux
. += auxmarking
@@ -519,15 +520,17 @@
else
limb.icon_state = "[body_zone]"
- if(aux_zone)
- aux = image(limb.icon, "[aux_zone]", -aux_layer, image_dir)
+ if(aux_icons)
+ for(var/I in aux_icons)
+ var/aux_layer = aux_icons[I]
+ aux += image(limb.icon, "[I]", -aux_layer, image_dir)
+ if(!isnull(aux_marking))
+ if(species_id == "husk")
+ auxmarking += image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[I]", -aux_layer, image_dir)
+ else
+ auxmarking += image(body_markings_icon, "[body_markings]_[I]", -aux_layer, image_dir)
+ . += auxmarking
. += aux
- if(!isnull(aux_marking))
- if(species_id == "husk")
- auxmarking = image('modular_citadel/icons/mob/markings_notmammals.dmi', "husk_[aux_zone]", -aux_layer, image_dir)
- else
- auxmarking = image(body_markings_icon, "[body_markings]_[aux_zone]", -aux_layer, image_dir)
- . += auxmarking
if(!isnull(body_markings))
if(species_id == "husk")
@@ -549,13 +552,17 @@
var/draw_color = mutation_color || species_color || (skin_tone && skintone2hex(skin_tone))
if(draw_color)
limb.color = "#[draw_color]"
- if(aux_zone)
- aux.color = "#[draw_color]"
+ if(aux_icons)
+ for(var/a in aux)
+ var/image/I = a
+ I.color = "#[draw_color]"
if(!isnull(aux_marking))
- if(species_id == "husk")
- auxmarking.color = "#141414"
- else
- auxmarking.color = list(markings_color)
+ for(var/a in auxmarking)
+ var/image/I = a
+ if(species_id == "husk")
+ I.color = "#141414"
+ else
+ I.color = list(markings_color)
if(!isnull(body_markings))
if(species_id == "husk")
@@ -633,8 +640,7 @@
max_stamina_damage = 50
body_zone = BODY_ZONE_L_ARM
body_part = ARM_LEFT
- aux_zone = BODY_ZONE_PRECISE_L_HAND
- aux_layer = HANDS_PART_LAYER
+ aux_icons = list(BODY_ZONE_PRECISE_L_HAND = HANDS_PART_LAYER, "l_hand_behind" = BODY_BEHIND_LAYER)
body_damage_coeff = 0.75
held_index = 1
px_x = -6
@@ -697,8 +703,7 @@
max_damage = 50
body_zone = BODY_ZONE_R_ARM
body_part = ARM_RIGHT
- aux_zone = BODY_ZONE_PRECISE_R_HAND
- aux_layer = HANDS_PART_LAYER
+ aux_icons = list(BODY_ZONE_PRECISE_R_HAND = HANDS_PART_LAYER, "r_hand_behind" = BODY_BEHIND_LAYER)
body_damage_coeff = 0.75
held_index = 2
px_x = 6
@@ -768,6 +773,8 @@
px_y = 12
stam_heal_tick = 2
max_stamina_damage = 50
+ var/blood_state = BLOOD_STATE_NOT_BLOODY
+ var/list/bloody_legs = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
/obj/item/bodypart/l_leg/is_disabled()
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_L_LEG))
@@ -828,6 +835,8 @@
px_y = 12
max_stamina_damage = 50
stam_heal_tick = 2
+ var/blood_state = BLOOD_STATE_NOT_BLOODY
+ var/list/bloody_legs = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
/obj/item/bodypart/r_leg/is_disabled()
if(HAS_TRAIT(owner, TRAIT_PARALYSIS_R_LEG))
diff --git a/code/modules/surgery/bodyparts/head.dm b/code/modules/surgery/bodyparts/head.dm
index 46ee10a3fd..23d49e98bb 100644
--- a/code/modules/surgery/bodyparts/head.dm
+++ b/code/modules/surgery/bodyparts/head.dm
@@ -32,6 +32,8 @@
var/lip_style = null
var/lip_color = "white"
+ //If the head is a special sprite
+ var/custom_head
/obj/item/bodypart/head/can_dismember(obj/item/I)
if(!((owner.stat == DEAD) || owner.InFullCritical()))
@@ -128,6 +130,8 @@
add_overlay(standing)
/obj/item/bodypart/head/get_limb_icon(dropped)
+ if(custom_head)
+ return
cut_overlays()
. = ..()
if(dropped) //certain overlays only appear when the limb is being detached from its owner.
diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm
index a2e8017956..704a377fa8 100644
--- a/code/modules/surgery/bodyparts/helpers.dm
+++ b/code/modules/surgery/bodyparts/helpers.dm
@@ -49,6 +49,27 @@
+/mob/proc/has_left_leg()
+ return TRUE
+
+/mob/living/carbon/has_left_leg()
+ var/obj/item/bodypart/l_leg = get_bodypart(BODY_ZONE_L_LEG)
+ if(l_leg)
+ return TRUE
+ else
+ return FALSE
+
+/mob/proc/has_right_leg()
+ return TRUE
+
+/mob/living/carbon/has_right_leg()
+ var/obj/item/bodypart/r_leg = get_bodypart(BODY_ZONE_R_LEG)
+ if(r_leg)
+ return TRUE
+ else
+ return FALSE
+
+
//Limb numbers
/mob/proc/get_num_arms(check_disabled = TRUE)
return 2
@@ -91,14 +112,14 @@
/mob/proc/get_leg_ignore()
return FALSE
-/mob/living/carbon/alien/larva/get_leg_ignore()
- return TRUE
-
-/mob/living/carbon/human/get_leg_ignore()
- if((movement_type & FLYING) || floating)
+/mob/living/carbon/get_leg_ignore()
+ if(movement_type & (FLYING|FLOATING))
return TRUE
return FALSE
+/mob/living/carbon/alien/larva/get_leg_ignore()
+ return TRUE
+
/mob/living/proc/get_missing_limbs()
return list()
diff --git a/code/modules/surgery/brain_surgery.dm b/code/modules/surgery/brain_surgery.dm
index e65271576d..d86f5731c7 100644
--- a/code/modules/surgery/brain_surgery.dm
+++ b/code/modules/surgery/brain_surgery.dm
@@ -7,12 +7,13 @@
/datum/surgery_step/clamp_bleeders,
/datum/surgery_step/fix_brain,
/datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_HEAD)
requires_bodypart_type = 0
/datum/surgery_step/fix_brain
name = "fix brain"
- implements = list(/obj/item/hemostat = 85, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100
+ implements = list(TOOL_HEMOSTAT = 85, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15) //don't worry, pouring some alcohol on their open brain will get that chance to 100
time = 120 //long and complicated
/datum/surgery/brain_surgery/can_start(mob/user, mob/living/carbon/target)
var/obj/item/organ/brain/B = target.getorganslot(ORGAN_SLOT_BRAIN)
@@ -31,7 +32,7 @@
"[user] completes the surgery on [target]'s brain.")
if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed))
target.mind.remove_antag_datum(/datum/antagonist/brainwashed)
- target.adjustBrainLoss(-60)
+ target.setOrganLoss(ORGAN_SLOT_BRAIN, target.getOrganLoss(ORGAN_SLOT_BRAIN) - 60) //we set damage in this case in order to clear the "failing" flag
target.cure_all_traumas(TRAUMA_RESILIENCE_SURGERY)
return TRUE
@@ -40,7 +41,7 @@
display_results(user, target, "You screw up, causing more damage! ",
"[user] screws up, causing brain damage! ",
"[user] completes the surgery on [target]'s brain.")
- target.adjustBrainLoss(60)
+ target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 60)
target.gain_trauma_type(BRAIN_TRAUMA_SEVERE, TRAUMA_RESILIENCE_LOBOTOMY)
else
user.visible_message("[user] suddenly notices that the brain [user.p_they()] [user.p_were()] working on is not there anymore.", "You suddenly notice that the brain you were working on is not there anymore. ")
diff --git a/code/modules/surgery/cavity_implant.dm b/code/modules/surgery/cavity_implant.dm
index 4c65b56962..200e33b5f8 100644
--- a/code/modules/surgery/cavity_implant.dm
+++ b/code/modules/surgery/cavity_implant.dm
@@ -1,7 +1,7 @@
/datum/surgery/cavity_implant
name = "Cavity implant"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/incise, /datum/surgery_step/handle_cavity, /datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_CHEST)
//handle cavity
/datum/surgery_step/handle_cavity
@@ -15,7 +15,7 @@
/datum/surgery_step/handle_cavity/tool_check(mob/user, obj/item/tool)
if(istype(tool, /obj/item/cautery) || istype(tool, /obj/item/gun/energy/laser))
return FALSE
- return !tool.is_hot()
+ return !tool.get_temperature()
/datum/surgery_step/handle_cavity/preop(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
var/obj/item/bodypart/chest/CH = target.get_bodypart(BODY_ZONE_CHEST)
IC = CH.cavity_item
diff --git a/code/modules/surgery/core_removal.dm b/code/modules/surgery/core_removal.dm
index 6243405f8d..3f36a8bb8c 100644
--- a/code/modules/surgery/core_removal.dm
+++ b/code/modules/surgery/core_removal.dm
@@ -1,8 +1,10 @@
/datum/surgery/core_removal
name = "Core removal"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/extract_core)
- species = list(/mob/living/simple_animal/slime)
+ target_mobtypes = list(/mob/living/simple_animal/slime)
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
+ lying_required = FALSE
+ ignore_clothes = TRUE
/datum/surgery/core_removal/can_start(mob/user, mob/living/target)
if(target.stat == DEAD)
@@ -11,7 +13,7 @@
//extract brain
/datum/surgery_step/extract_core
name = "extract core"
- implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 100)
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 100)
time = 16
/datum/surgery_step/extract_core/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm
new file mode 100644
index 0000000000..71a48ae68c
--- /dev/null
+++ b/code/modules/surgery/coronary_bypass.dm
@@ -0,0 +1,77 @@
+/datum/surgery/coronary_bypass
+ name = "Coronary Bypass"
+ steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise_heart, /datum/surgery_step/coronary_bypass, /datum/surgery_step/close)
+ possible_locs = list(BODY_ZONE_CHEST)
+
+/datum/surgery/coronary_bypass/can_start(mob/user, mob/living/carbon/target)
+ var/obj/item/organ/heart/H = target.getorganslot(ORGAN_SLOT_HEART)
+ if(H)
+ if(H.damage > 60 && !H.operated)
+ return TRUE
+ return FALSE
+
+
+//an incision but with greater bleed, and a 90% base success chance
+/datum/surgery_step/incise_heart
+ name = "incise heart"
+ implements = list(TOOL_SCALPEL = 90, /obj/item/melee/transforming/energy/sword = 45, /obj/item/kitchen/knife = 45,
+ /obj/item/shard = 25)
+ time = 16
+
+/datum/surgery_step/incise_heart/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to make an incision in [target]'s heart... ",
+ "[user] begins to make an incision in [target]'s heart.",
+ "[user] begins to make an incision in [target]'s heart.")
+
+/datum/surgery_step/incise_heart/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if (!(NOBLOOD in H.dna.species.species_traits))
+ display_results(user, target, "Blood pools around the incision in [H]'s heart. ",
+ "Blood pools around the incision in [H]'s heart.",
+ "")
+ H.bleed_rate += 10
+ H.adjustBruteLoss(10)
+ return TRUE
+
+/datum/surgery_step/incise_heart/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ display_results(user, target, "You screw up, cutting too deeply into the heart! ",
+ "[user] screws up, causing blood to spurt out of [H]'s chest! ",
+ "[user] screws up, causing blood to spurt out of [H]'s chest! ")
+ H.bleed_rate += 20
+ H.adjustOrganLoss(ORGAN_SLOT_HEART, 10)
+ H.adjustBruteLoss(10)
+
+//grafts a coronary bypass onto the individual's heart, success chance is 90% base again
+/datum/surgery_step/coronary_bypass
+ name = "graft coronary bypass"
+ implements = list(TOOL_HEMOSTAT = 90, TOOL_WIRECUTTER = 35, /obj/item/stack/packageWrap = 15, /obj/item/stack/cable_coil = 5)
+ time = 90
+
+/datum/surgery_step/coronary_bypass/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to graft a bypass onto [target]'s heart... ",
+ "[user] begins to graft something onto [target]'s heart!",
+ "[user] begins to graft something onto [target]'s heart!")
+
+/datum/surgery_step/coronary_bypass/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ target.setOrganLoss(ORGAN_SLOT_HEART, 60)
+ var/obj/item/organ/heart/heart = target.getorganslot(ORGAN_SLOT_HEART)
+ if(heart) //slightly worrying if we lost our heart mid-operation, but that's life
+ heart.operated = TRUE
+ display_results(user, target, "You successfully graft a bypass onto [target]'s heart. ",
+ "[user] finishes grafting something onto [target]'s heart.",
+ "[user] finishes grafting something onto [target]'s heart.")
+ return TRUE
+
+/datum/surgery_step/coronary_bypass/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ display_results(user, target, "You screw up in attaching the graft, and it tears off, tearing part of the heart! ",
+ "[user] screws up, causing blood to spurt out of [H]'s chest profusely! ",
+ "[user] screws up, causing blood to spurt out of [H]'s chest profusely! ")
+ H.adjustOrganLoss(ORGAN_SLOT_HEART, 20)
+ H.bleed_rate += 30
+ return FALSE
diff --git a/code/modules/surgery/embalming.dm b/code/modules/surgery/embalming.dm
index f74d864245..b07c2b3179 100644
--- a/code/modules/surgery/embalming.dm
+++ b/code/modules/surgery/embalming.dm
@@ -1,18 +1,17 @@
/datum/surgery/embalming //Fast and easy way to husk bodys
name = "Embalming"
- desc = "A surgical procedure that prevents a corps from producing."
+ desc = "A surgical procedure that prevents a corpse from producing miasma."
steps = list(/datum/surgery_step/incise,
/datum/surgery_step/embalming,
/datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_CHEST)
requires_bodypart_type = 0
/datum/surgery_step/embalming
name = "embalming body"
- implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
- implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30)
+ implements = list(/obj/item/reagent_containers/syringe = 100, /obj/item/pen = 30)
time = 10
chems_needed = list("drying_agent", "sterilizine")
require_all_chems = FALSE
@@ -28,4 +27,4 @@
/datum/surgery_step/embalming/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] screws up!", "You screwed up! ")
ADD_TRAIT(target, TRAIT_NOCLONE, MAGIC_TRAIT) //That body is ruined, but still gives miasma
- return FALSE
\ No newline at end of file
+ return FALSE
diff --git a/code/modules/surgery/experimental_dissection.dm b/code/modules/surgery/experimental_dissection.dm
new file mode 100644
index 0000000000..3172496146
--- /dev/null
+++ b/code/modules/surgery/experimental_dissection.dm
@@ -0,0 +1,113 @@
+#define BASE_HUMAN_REWARD 500
+
+/datum/surgery/advanced/experimental_dissection
+ name = "Dissection"
+ desc = "A surgical procedure which analyzes the biology of a corpse, and automatically adds new findings to the research database."
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/dissection,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/close)
+ possible_locs = list(BODY_ZONE_CHEST)
+ target_mobtypes = list(/mob/living) //Feel free to dissect devils but they're magic.
+ replaced_by = /datum/surgery/advanced/experimental_dissection/adv
+ requires_tech = FALSE
+ var/value_multiplier = 1
+
+/datum/surgery/advanced/experimental_dissection/can_start(mob/user, mob/living/target)
+ . = ..()
+ if(HAS_TRAIT_FROM(target, TRAIT_DISSECTED,"[name]"))
+ return FALSE
+ if(target.stat != DEAD)
+ return FALSE
+
+/datum/surgery_step/dissection
+ name = "dissection"
+ implements = list(/obj/item/scalpel/augment = 75, /obj/item/scalpel/advanced = 60, /obj/item/scalpel = 45, /obj/item/kitchen/knife = 20, /obj/item/shard = 10)// special tools not only cut down time but also improve probability, doesn't use TOOL_SCALPEL because different scalpels have different probs
+ time = 125
+ silicons_obey_prob = TRUE
+ repeatable = TRUE
+
+/datum/surgery_step/dissection/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You start dissecting [target]. ",
+ "[user] starts dissecting [target].",
+ "[user] starts dissecting [target].")
+
+/datum/surgery_step/dissection/proc/check_value(mob/living/target, datum/surgery/advanced/experimental_dissection/ED)
+ var/cost = BASE_HUMAN_REWARD
+ var/multi_surgery_adjust = 0
+
+ //determine bonus applied
+ if(isalienroyal(target))
+ cost = (BASE_HUMAN_REWARD*10)
+ else if(isalienadult(target))
+ cost = (BASE_HUMAN_REWARD*5)
+ else if(ismonkey(target))
+ cost = (BASE_HUMAN_REWARD*0.5)
+ else if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ if(H?.dna?.species)
+ if(isabductor(H))
+ cost = (BASE_HUMAN_REWARD*4)
+ else if(isgolem(H) || iszombie(H))
+ cost = (BASE_HUMAN_REWARD*3)
+ /*else if(isjellyperson(H) || ispodperson(H)) CITADEL CHANGE: jelly and pod being available roundstart shouldn't give additional points
+ cost = (BASE_HUMAN_REWARD*2)*/
+ else
+ cost = (BASE_HUMAN_REWARD * 0.6)
+
+
+
+ //now we do math for surgeries already done (no double dipping!).
+ for(var/i in typesof(/datum/surgery/advanced/experimental_dissection))
+ var/datum/surgery/advanced/experimental_dissection/cringe = i
+ if(HAS_TRAIT_FROM(target,TRAIT_DISSECTED,"[initial(cringe.name)]"))
+ multi_surgery_adjust = max(multi_surgery_adjust,initial(cringe.value_multiplier)) - 1
+
+ multi_surgery_adjust *= cost
+
+ //multiply by multiplier in surgery
+ cost *= ED.value_multiplier
+ return (cost-multi_surgery_adjust)
+
+/datum/surgery_step/dissection/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/points_earned = check_value(target, surgery)
+ display_results(user, target, "You dissect [target], and add your [points_earned] point\s worth of discoveries to the research database! ",
+ "[user] dissects [target], discovering [points_earned] point\s of data!",
+ "[user] dissects [target]!")
+ SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = points_earned))
+ var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
+ target.apply_damage(80, BRUTE, L)
+ ADD_TRAIT(target, TRAIT_DISSECTED, "[surgery.name]")
+ repeatable = FALSE
+ return TRUE
+
+/datum/surgery_step/dissection/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You dissect [target], but do not find anything particularly interesting. ",
+ "[user] dissects [target], however it seems [user.p_they()] didn't find anything useful.",
+ "[user] dissects [target], but looks a little dissapointed.")
+ SSresearch.science_tech.add_point_list(list(TECHWEB_POINT_TYPE_GENERIC = (round(check_value(target, surgery) * 0.01))))
+ var/obj/item/bodypart/L = target.get_bodypart(BODY_ZONE_CHEST)
+ target.apply_damage(80, BRUTE, L)
+ return TRUE
+
+/datum/surgery/advanced/experimental_dissection/adv
+ name = "Thorough Dissection"
+ value_multiplier = 2
+ replaced_by = /datum/surgery/advanced/experimental_dissection/exp
+ requires_tech = TRUE
+
+/datum/surgery/advanced/experimental_dissection/exp
+ name = "Experimental Dissection"
+ value_multiplier = 5
+ replaced_by = /datum/surgery/advanced/experimental_dissection/alien
+ requires_tech = TRUE
+
+/datum/surgery/advanced/experimental_dissection/alien
+ name = "Extraterrestrial Dissection"
+ value_multiplier = 10
+ requires_tech = TRUE
+ replaced_by = null
+
+#undef EXPDIS_FAIL_MSG
\ No newline at end of file
diff --git a/code/modules/surgery/eye_surgery.dm b/code/modules/surgery/eye_surgery.dm
index 85142e7bb1..f7a06af388 100644
--- a/code/modules/surgery/eye_surgery.dm
+++ b/code/modules/surgery/eye_surgery.dm
@@ -1,13 +1,13 @@
/datum/surgery/eye_surgery
name = "Eye surgery"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/fix_eyes, /datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_PRECISE_EYES)
requires_bodypart_type = 0
//fix eyes
/datum/surgery_step/fix_eyes
name = "fix eyes"
- implements = list(/obj/item/hemostat = 100, TOOL_SCREWDRIVER = 45, /obj/item/pen = 25)
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 45, /obj/item/pen = 25)
time = 64
/datum/surgery/eye_surgery/can_start(mob/user, mob/living/carbon/target)
var/obj/item/organ/eyes/E = target.getorganslot(ORGAN_SLOT_EYES)
@@ -37,7 +37,7 @@
display_results(user, target, "You accidentally stab [target] right in the brain! ",
"[user] accidentally stabs [target] right in the brain! ",
"[user] accidentally stabs [target] right in the brain! ")
- target.adjustBrainLoss(70)
+ target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 70)
else
display_results(user, target, "You accidentally stab [target] right in the brain! Or would have, if [target] had a brain. ",
"[user] accidentally stabs [target] right in the brain! Or would have, if [target] had a brain. ",
diff --git a/code/modules/surgery/graft_synthtissue.dm b/code/modules/surgery/graft_synthtissue.dm
new file mode 100644
index 0000000000..7540b2cd94
--- /dev/null
+++ b/code/modules/surgery/graft_synthtissue.dm
@@ -0,0 +1,71 @@
+//Organ reconstruction, limited to the chest region as most organs in the head have their own repair method (eyes/brain). We require synthflesh for these
+//steps since fixing internal organs aren't as simple as mending exterior flesh, though in the future it would be neat to add more chems to the viable list.
+//TBD: Add heart damage, have heart reconstruction seperate from organ reconstruction, and find a better name for this. I can imagine people getting it confused with manipulation.
+
+/datum/surgery/graft_synthtissue
+ name = "Graft synthtissue"
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES)
+ steps = list(
+ /datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/saw,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/graft_synthtissue,
+ /datum/surgery_step/close
+ )
+
+//repair organs
+/datum/surgery_step/graft_synthtissue
+ name = "graft synthtissue"
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 35, /obj/item/pen = 15)
+ repeatable = TRUE
+ time = 75
+ chems_needed = list("synthtissue")
+ var/obj/item/organ/chosen_organ
+ var/health_restored = 10
+
+/datum/surgery_step/graft_synthtissue/preop(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(implement_type in implements)
+ var/list/organs = target.getorganszone(target_zone)
+ if(!organs.len)
+ to_chat(user, "There are no targetable organs in [target]'s [parse_zone(target_zone)]! ")
+ return -1
+ else
+ for(var/obj/item/organ/O in organs)
+ O.on_find(user)
+ organs -= O
+ organs[O.name] = O
+ chosen_organ = input("Target which organ?", "Surgery", null, null) as null|anything in organs
+ chosen_organ = organs[chosen_organ]
+ if(!chosen_organ)
+ return -1
+ if(!target.reagents.has_reagent("synthtissue"))
+ to_chat(user, "There's no synthtissue available for use on [chosen_organ] ")
+ return -1
+ var/datum/reagent/synthtissue/Sf = locate(/datum/reagent/synthtissue) in target.reagents.reagent_list
+ if(Sf.volume < 10)
+ to_chat(user, "There's not enough synthtissue to perform the operation! There needs to be at least 10u. ")
+ return -1
+
+ if((chosen_organ.organ_flags & ORGAN_FAILING) && !(Sf.data["grown_volume"] >= 115))
+ to_chat(user, "[chosen_organ] is too damaged to graft onto! ")
+ return -1
+
+ if(health_restored != 10)
+ health_restored = 10
+ health_restored += (Sf.data["grown_volume"]/10)
+
+ user.visible_message("[user] begins to graft synthtissue onto [chosen_organ]. ")
+ target.reagents.remove_reagent("synthtissue", 10)
+
+/datum/surgery_step/graft_synthtissue/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] successfully grafts synthtissue to [chosen_organ].", "You succeed in grafting 10u of the synthflesh to the [chosen_organ]. ")
+ chosen_organ.applyOrganDamage(-health_restored)
+ return TRUE
+
+/datum/surgery_step/graft_synthtissue/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ user.visible_message("[user] accidentally damages part of [chosen_organ]! ", "You damage [chosen_organ]! Apply more synthtissue if it's run out. ")
+ chosen_organ.applyOrganDamage(10)
+ return FALSE
diff --git a/code/modules/surgery/healing.dm b/code/modules/surgery/healing.dm
new file mode 100644
index 0000000000..d20d1d822a
--- /dev/null
+++ b/code/modules/surgery/healing.dm
@@ -0,0 +1,215 @@
+/datum/surgery/healing
+ steps = list(/datum/surgery_step/incise,
+ /datum/surgery_step/retract_skin,
+ /datum/surgery_step/incise,
+ /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/heal,
+ /datum/surgery_step/close)
+
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ possible_locs = list(BODY_ZONE_CHEST)
+ requires_bodypart_type = FALSE
+ replaced_by = /datum/surgery
+ ignore_clothes = TRUE
+ var/healing_step_type
+ var/antispam = FALSE
+
+/datum/surgery/healing/New(surgery_target, surgery_location, surgery_bodypart)
+ ..()
+ if(healing_step_type)
+ steps = list(/datum/surgery_step/incise/nobleed,
+ healing_step_type, //hehe cheeky
+ /datum/surgery_step/close)
+
+/datum/surgery_step/heal
+ name = "repair body"
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_SCREWDRIVER = 65, /obj/item/pen = 55)
+ repeatable = TRUE
+ time = 25
+ var/brutehealing = 0
+ var/burnhealing = 0
+ var/missinghpbonus = 0 //heals an extra point of damager per X missing damage of type (burn damage for burn healing, brute for brute). Smaller Number = More Healing!
+
+/datum/surgery_step/heal/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/woundtype
+ if(brutehealing && burnhealing)
+ woundtype = "wounds"
+ else if(brutehealing)
+ woundtype = "bruises"
+ else //why are you trying to 0,0...?
+ woundtype = "burns"
+ if(istype(surgery,/datum/surgery/healing))
+ var/datum/surgery/healing/the_surgery = surgery
+ if(!the_surgery.antispam)
+ display_results(user, target, "You attempt to patch some of [target]'s [woundtype]. ",
+ "[user] attempts to patch some of [target]'s [woundtype]. ",
+ "[user] attempts to patch some of [target]'s [woundtype]. ")
+
+/datum/surgery_step/heal/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
+ if(..())
+ while((brutehealing && target.getBruteLoss()) || (burnhealing && target.getFireLoss()))
+ if(!..())
+ break
+
+/datum/surgery_step/heal/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ var/umsg = "You succeed in fixing some of [target]'s wounds" //no period, add initial space to "addons"
+ var/tmsg = "[user] fixes some of [target]'s wounds" //see above
+ var/urhealedamt_brute = brutehealing
+ var/urhealedamt_burn = burnhealing
+ if(missinghpbonus)
+ if(target.stat != DEAD)
+ urhealedamt_brute += round((target.getBruteLoss()/ missinghpbonus),0.1)
+ urhealedamt_burn += round((target.getFireLoss()/ missinghpbonus),0.1)
+ else //less healing bonus for the dead since they're expected to have lots of damage to begin with (to make TW into defib not TOO simple)
+ urhealedamt_brute += round((target.getBruteLoss()/ (missinghpbonus*5)),0.1)
+ urhealedamt_burn += round((target.getFireLoss()/ (missinghpbonus*5)),0.1)
+ if(!get_location_accessible(target, target_zone))
+ urhealedamt_brute *= 0.55
+ urhealedamt_burn *= 0.55
+ umsg += " as best as you can while they have clothing on"
+ tmsg += " as best as they can while [target] has clothing on"
+ target.heal_bodypart_damage(urhealedamt_brute,urhealedamt_burn)
+ display_results(user, target, "[umsg]. ",
+ "[tmsg].",
+ "[tmsg].")
+ if(istype(surgery, /datum/surgery/healing))
+ var/datum/surgery/healing/the_surgery = surgery
+ the_surgery.antispam = TRUE
+ return TRUE
+
+/datum/surgery_step/heal/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You screwed up! ",
+ "[user] screws up! ",
+ "[user] fixes some of [target]'s wounds. ", TRUE)
+ var/urdamageamt_burn = brutehealing * 0.8
+ var/urdamageamt_brute = burnhealing * 0.8
+ if(missinghpbonus)
+ urdamageamt_brute += round((target.getBruteLoss()/ (missinghpbonus*2)),0.1)
+ urdamageamt_burn += round((target.getFireLoss()/ (missinghpbonus*2)),0.1)
+
+ target.take_bodypart_damage(urdamageamt_brute, urdamageamt_burn)
+ return FALSE
+
+/***************************BRUTE***************************/
+/datum/surgery/healing/brute
+ name = "Tend Wounds (Bruises)"
+
+/datum/surgery/healing/brute/basic
+ name = "Tend Wounds (Bruises, Basic)"
+ replaced_by = /datum/surgery/healing/brute/upgraded
+ healing_step_type = /datum/surgery_step/heal/brute/basic
+ desc = "A surgical procedure that provides basic treatment for a patient's brute traumas. Heals slightly more when the patient is severely injured."
+
+/datum/surgery/healing/brute/upgraded
+ name = "Tend Wounds (Bruises, Adv.)"
+ replaced_by = /datum/surgery/healing/brute/upgraded/femto
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/brute/upgraded
+ desc = "A surgical procedure that provides advanced treatment for a patient's brute traumas. Heals more when the patient is severely injured."
+
+/datum/surgery/healing/brute/upgraded/femto
+ name = "Tend Wounds (Bruises, Exp.)"
+ replaced_by = /datum/surgery/healing/combo/upgraded/femto
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/brute/upgraded/femto
+ desc = "A surgical procedure that provides experimental treatment for a patient's brute traumas. Heals considerably more when the patient is severely injured."
+
+/********************BRUTE STEPS********************/
+/datum/surgery_step/heal/brute/basic
+ name = "tend bruises"
+ brutehealing = 5
+ missinghpbonus = 15
+
+/datum/surgery_step/heal/brute/upgraded
+ brutehealing = 5
+ missinghpbonus = 10
+
+/datum/surgery_step/heal/brute/upgraded/femto
+ brutehealing = 5
+ missinghpbonus = 5
+
+/***************************BURN***************************/
+/datum/surgery/healing/burn
+ name = "Tend Wounds (Burn)"
+
+/datum/surgery/healing/burn/basic
+ name = "Tend Wounds (Burn, Basic)"
+ replaced_by = /datum/surgery/healing/burn/upgraded
+ healing_step_type = /datum/surgery_step/heal/burn/basic
+ desc = "A surgical procedure that provides basic treatment for a patient's burns. Heals slightly more when the patient is severely injured."
+
+/datum/surgery/healing/burn/upgraded
+ name = "Tend Wounds (Burn, Adv.)"
+ replaced_by = /datum/surgery/healing/burn/upgraded/femto
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/burn/upgraded
+ desc = "A surgical procedure that provides advanced treatment for a patient's burns. Heals more when the patient is severely injured."
+
+/datum/surgery/healing/burn/upgraded/femto
+ name = "Tend Wounds (Burn, Exp.)"
+ replaced_by = /datum/surgery/healing/combo/upgraded/femto
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/burn/upgraded/femto
+ desc = "A surgical procedure that provides experimental treatment for a patient's burns. Heals considerably more when the patient is severely injured."
+
+/********************BURN STEPS********************/
+/datum/surgery_step/heal/burn/basic
+ name = "tend burn wounds"
+ burnhealing = 5
+ missinghpbonus = 15
+
+/datum/surgery_step/heal/burn/upgraded
+ burnhealing = 5
+ missinghpbonus = 10
+
+/datum/surgery_step/heal/burn/upgraded/femto
+ burnhealing = 5
+ missinghpbonus = 5
+
+/***************************COMBO***************************/
+/datum/surgery/healing/combo
+
+
+/datum/surgery/healing/combo
+ name = "Tend Wounds (Mixture, Basic)"
+ replaced_by = /datum/surgery/healing/combo/upgraded
+ requires_tech = TRUE
+ healing_step_type = /datum/surgery_step/heal/combo
+ desc = "A surgical procedure that provides basic treatment for a patient's burns and brute traumas. Heals slightly more when the patient is severely injured."
+
+/datum/surgery/healing/combo/upgraded
+ name = "Tend Wounds (Mixture, Adv.)"
+ replaced_by = /datum/surgery/healing/combo/upgraded/femto
+ healing_step_type = /datum/surgery_step/heal/combo/upgraded
+ desc = "A surgical procedure that provides advanced treatment for a patient's burns and brute traumas. Heals more when the patient is severely injured."
+
+
+/datum/surgery/healing/combo/upgraded/femto //no real reason to type it like this except consistency, don't worry you're not missing anything
+ name = "Tend Wounds (Mixture, Exp.)"
+ replaced_by = null
+ healing_step_type = /datum/surgery_step/heal/combo/upgraded/femto
+ desc = "A surgical procedure that provides experimental treatment for a patient's burns and brute traumas. Heals considerably more when the patient is severely injured."
+
+/********************COMBO STEPS********************/
+/datum/surgery_step/heal/combo
+ name = "tend physical wounds"
+ brutehealing = 3
+ burnhealing = 3
+ missinghpbonus = 15
+ time = 10
+
+/datum/surgery_step/heal/combo/upgraded
+ brutehealing = 3
+ burnhealing = 3
+ missinghpbonus = 10
+
+/datum/surgery_step/heal/combo/upgraded/femto
+ brutehealing = 1
+ burnhealing = 1
+ missinghpbonus = 2.5
+
+/datum/surgery_step/heal/combo/upgraded/femto/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You screwed up! ",
+ "[user] screws up! ",
+ "[user] fixes some of [target]'s wounds. ", TRUE)
+ target.take_bodypart_damage(5,5)
\ No newline at end of file
diff --git a/code/modules/surgery/helpers.dm b/code/modules/surgery/helpers.dm
index 0419a4c73f..f52bf97147 100644
--- a/code/modules/surgery/helpers.dm
+++ b/code/modules/surgery/helpers.dm
@@ -10,9 +10,6 @@
C = M
affecting = C.get_bodypart(check_zone(selected_zone))
- if(!M.lying && !isslime(M)) //if they're prone or a slime
- return
-
var/datum/surgery/current_surgery
for(var/datum/surgery/S in M.surgeries)
@@ -35,13 +32,18 @@
continue
else if(C && S.requires_bodypart) //mob with no limb in surgery zone when we need a limb
continue
+ if(S.lying_required && !(M.lying))
+ continue
if(!S.can_start(user, M))
continue
- for(var/path in S.species)
+ for(var/path in S.target_mobtypes)
if(istype(M, path))
available_surgeries[S.name] = S
break
+ if(!available_surgeries.len)
+ return
+
var/P = input("Begin which procedure?", "Surgery", null, null) as null|anything in available_surgeries
if(P && user && user.Adjacent(M) && (I in user))
var/datum/surgery/S = available_surgeries[P]
@@ -60,6 +62,8 @@
return
else if(C && S.requires_bodypart)
return
+ if(S.lying_required && !(M.lying))
+ return
if(!S.can_start(user, M))
return
diff --git a/code/modules/surgery/implant_removal.dm b/code/modules/surgery/implant_removal.dm
index 05119b365d..3eb05c91c7 100644
--- a/code/modules/surgery/implant_removal.dm
+++ b/code/modules/surgery/implant_removal.dm
@@ -1,12 +1,12 @@
/datum/surgery/implant_removal
name = "implant removal"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/extract_implant, /datum/surgery_step/close)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_CHEST)
//extract implant
/datum/surgery_step/extract_implant
name = "extract implant"
- implements = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 65)
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 65)
time = 64
var/obj/item/implant/I = null
/datum/surgery_step/extract_implant/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/limb_augmentation.dm b/code/modules/surgery/limb_augmentation.dm
index 7ba8dbc49d..b1d8990b48 100644
--- a/code/modules/surgery/limb_augmentation.dm
+++ b/code/modules/surgery/limb_augmentation.dm
@@ -2,7 +2,7 @@
//SURGERY STEPS
/datum/surgery_step/replace
name = "sever muscles"
- implements = list(/obj/item/scalpel = 100, TOOL_WIRECUTTER = 55)
+ implements = list(TOOL_SCALPEL = 100, TOOL_WIRECUTTER = 55)
time = 32
@@ -38,7 +38,7 @@
/datum/surgery/augmentation
name = "Augmentation"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/replace, /datum/surgery_step/saw, /datum/surgery_step/replace_limb)
- species = list(/mob/living/carbon/human)
+ target_mobtypes = list(/mob/living/carbon/human)
possible_locs = list(BODY_ZONE_R_ARM,BODY_ZONE_L_ARM,BODY_ZONE_R_LEG,BODY_ZONE_L_LEG,BODY_ZONE_CHEST,BODY_ZONE_HEAD)
requires_real_bodypart = TRUE
//SURGERY STEP SUCCESSES
diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm
index bb297b4604..b28b439f9f 100644
--- a/code/modules/surgery/lipoplasty.dm
+++ b/code/modules/surgery/lipoplasty.dm
@@ -9,7 +9,7 @@
//cut fat
/datum/surgery_step/cut_fat
name = "cut excess fat"
- implements = list(/obj/item/circular_saw = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25)
+ implements = list(TOOL_SAW = 100, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25) //why we need a saw to cut adipose tissue is beyond me, shit's soft as fuck
time = 64
/datum/surgery_step/cut_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -26,7 +26,7 @@
//remove fat
/datum/surgery_step/remove_fat
name = "remove loose fat"
- implements = list(/obj/item/retractor = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
+ implements = list(TOOL_RETRACTOR = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
time = 32
/datum/surgery_step/remove_fat/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/lobectomy.dm b/code/modules/surgery/lobectomy.dm
new file mode 100644
index 0000000000..297be175a0
--- /dev/null
+++ b/code/modules/surgery/lobectomy.dm
@@ -0,0 +1,46 @@
+/datum/surgery/lobectomy
+ name = "Lobectomy" //not to be confused with lobotomy
+ steps = list(/datum/surgery_step/incise, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/clamp_bleeders,
+ /datum/surgery_step/lobectomy, /datum/surgery_step/close)
+ possible_locs = list(BODY_ZONE_CHEST)
+
+/datum/surgery/lobectomy/can_start(mob/user, mob/living/carbon/target)
+ var/obj/item/organ/lungs/L = target.getorganslot(ORGAN_SLOT_LUNGS)
+ if(L)
+ if(L.damage > 60 && !L.operated)
+ return TRUE
+ return FALSE
+
+
+//lobectomy, removes the most damaged lung lobe with a 95% base success chance
+/datum/surgery_step/lobectomy
+ name = "excise damaged lung node"
+ implements = list(TOOL_SCALPEL = 95, /obj/item/melee/transforming/energy/sword = 65, /obj/item/kitchen/knife = 45,
+ /obj/item/shard = 35)
+ time = 42
+
+/datum/surgery_step/lobectomy/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to make an incision in [target]'s lungs... ",
+ "[user] begins to make an incision in [target].",
+ "[user] begins to make an incision in [target].")
+
+/datum/surgery_step/lobectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ var/obj/item/organ/lungs/L = H.getorganslot(ORGAN_SLOT_LUNGS)
+ L.operated = TRUE
+ H.setOrganLoss(ORGAN_SLOT_LUNGS, 60)
+ display_results(user, target, "You successfully excise [H]'s most damaged lobe. ",
+ "Successfully removes a piece of [H]'s lungs.",
+ "")
+ return TRUE
+
+/datum/surgery_step/lobectomy/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ if(ishuman(target))
+ var/mob/living/carbon/human/H = target
+ display_results(user, target, "You screw up, failing to excise [H]'s damaged lobe! ",
+ "[user] screws up! ",
+ "[user] screws up! ")
+ H.losebreath += 4
+ H.adjustOrganLoss(ORGAN_SLOT_LUNGS, 10)
+ return FALSE
\ No newline at end of file
diff --git a/code/modules/surgery/mechanic_steps.dm b/code/modules/surgery/mechanic_steps.dm
index 7d364d9ecf..9366e585c3 100644
--- a/code/modules/surgery/mechanic_steps.dm
+++ b/code/modules/surgery/mechanic_steps.dm
@@ -3,7 +3,7 @@
name = "unscrew shell"
implements = list(
TOOL_SCREWDRIVER = 100,
- /obj/item/scalpel = 75, // med borgs could try to unskrew shell with scalpel
+ TOOL_SCALPEL = 75, // med borgs could try to unskrew shell with scalpel
/obj/item/kitchen/knife = 50,
/obj/item = 10) // 10% success with any sharp item.
time = 24
@@ -14,7 +14,7 @@
"[user] begins to unscrew the shell of [target]'s [parse_zone(target_zone)].")
/datum/surgery_step/mechanic_incise/tool_check(mob/user, obj/item/tool)
- if(implement_type == /obj/item && !tool.is_sharp())
+ if(implement_type == /obj/item && !tool.get_sharpness())
return FALSE
return TRUE
//close shell
@@ -22,7 +22,7 @@
name = "screw shell"
implements = list(
TOOL_SCREWDRIVER = 100,
- /obj/item/scalpel = 75,
+ TOOL_SCALPELl = 75,
/obj/item/kitchen/knife = 50,
/obj/item = 10) // 10% success with any sharp item.
time = 24
@@ -33,7 +33,7 @@
"[user] begins to screw the shell of [target]'s [parse_zone(target_zone)].")
/datum/surgery_step/mechanic_close/tool_check(mob/user, obj/item/tool)
- if(implement_type == /obj/item && !tool.is_sharp())
+ if(implement_type == /obj/item && !tool.get_sharpness())
return FALSE
return TRUE
//prepare electronics
@@ -41,7 +41,7 @@
name = "prepare electronics"
implements = list(
TOOL_MULTITOOL = 100,
- /obj/item/hemostat = 10) // try to reboot internal controllers via short circuit with some conductor
+ TOOL_HEMOSTAT = 10) // try to reboot internal controllers via short circuit with some conductor
time = 24
/datum/surgery_step/prepare_electronics/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -54,7 +54,7 @@
name = "unwrench bolts"
implements = list(
TOOL_WRENCH = 100,
- /obj/item/retractor = 10)
+ TOOL_RETRACTOR = 10)
time = 24
/datum/surgery_step/mechanic_unwrench/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -67,7 +67,7 @@
name = "wrench bolts"
implements = list(
TOOL_WRENCH = 100,
- /obj/item/retractor = 10)
+ TOOL_RETRACTOR = 10)
time = 24
/datum/surgery_step/mechanic_wrench/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -84,4 +84,4 @@
/datum/surgery_step/open_hatch/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "You begin to open the hatch holders in [target]'s [parse_zone(target_zone)]... ",
"[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].",
- "[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].")
+ "[user] begins to open the hatch holders in [target]'s [parse_zone(target_zone)].")
diff --git a/code/modules/surgery/organ_manipulation.dm b/code/modules/surgery/organ_manipulation.dm
index 6bffed7452..699b3f7f24 100644
--- a/code/modules/surgery/organ_manipulation.dm
+++ b/code/modules/surgery/organ_manipulation.dm
@@ -1,6 +1,6 @@
/datum/surgery/organ_manipulation
- name = "Organ manipulation"
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ name = "organ manipulation"
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD)
requires_real_bodypart = 1
steps = list(
@@ -26,7 +26,7 @@
/datum/surgery/organ_manipulation/alien
name = "Alien organ manipulation"
possible_locs = list(BODY_ZONE_CHEST, BODY_ZONE_HEAD, BODY_ZONE_PRECISE_GROIN, BODY_ZONE_PRECISE_EYES, BODY_ZONE_PRECISE_MOUTH, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM)
- species = list(/mob/living/carbon/alien/humanoid)
+ target_mobtypes = list(/mob/living/carbon/alien/humanoid)
steps = list(
/datum/surgery_step/saw,
/datum/surgery_step/incise,
@@ -62,7 +62,7 @@
name = "manipulate organs"
repeatable = 1
implements = list(/obj/item/organ = 100, /obj/item/reagent_containers/food/snacks/organ = 0, /obj/item/organ_storage = 100)
- var/implements_extract = list(/obj/item/hemostat = 100, TOOL_CROWBAR = 55)
+ var/implements_extract = list(TOOL_HEMOSTAT = 100, TOOL_CROWBAR = 55)
var/current_type
var/obj/item/organ/I = null
/datum/surgery_step/manipulate_organs/New()
diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm
index da03771a27..3b05873a0a 100644
--- a/code/modules/surgery/organic_steps.dm
+++ b/code/modules/surgery/organic_steps.dm
@@ -1,7 +1,7 @@
//make incision
/datum/surgery_step/incise
name = "make incision"
- implements = list(/obj/item/scalpel = 100, /obj/item/melee/transforming/energy/sword = 75, /obj/item/kitchen/knife = 65,
+ implements = list(TOOL_SCALPEL = 100, /obj/item/melee/transforming/energy/sword = 75, /obj/item/kitchen/knife = 65,
/obj/item/shard = 45, /obj/item = 30) // 30% success with any sharp item.
time = 16
@@ -11,7 +11,7 @@
"[user] begins to make an incision in [target]'s [parse_zone(target_zone)].")
/datum/surgery_step/incise/tool_check(mob/user, obj/item/tool)
- if(implement_type == /obj/item && !tool.is_sharp())
+ if(implement_type == /obj/item && !tool.get_sharpness())
return FALSE
return TRUE
/datum/surgery_step/incise/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -24,10 +24,20 @@
H.bleed_rate += 3
return TRUE
+/datum/surgery_step/incise/nobleed //silly friendly!
+
+/datum/surgery_step/incise/nobleed/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ display_results(user, target, "You begin to carefully make an incision in [target]'s [parse_zone(target_zone)]... ",
+ "[user] begins to carefully make an incision in [target]'s [parse_zone(target_zone)].",
+ "[user] begins to carefully make an incision in [target]'s [parse_zone(target_zone)].")
+
+/datum/surgery_step/incise/nobleed/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+ return TRUE
+
//clamp bleeders
/datum/surgery_step/clamp_bleeders
name = "clamp bleeders"
- implements = list(/obj/item/hemostat = 100, TOOL_WIRECUTTER = 60, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
+ implements = list(TOOL_HEMOSTAT = 100, TOOL_WIRECUTTER = 60, /obj/item/stack/packageWrap = 35, /obj/item/stack/cable_coil = 15)
time = 24
/datum/surgery_step/clamp_bleeders/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -45,7 +55,7 @@
//retract skin
/datum/surgery_step/retract_skin
name = "retract skin"
- implements = list(/obj/item/retractor = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
+ implements = list(TOOL_RETRACTOR = 100, TOOL_SCREWDRIVER = 45, TOOL_WIRECUTTER = 35)
time = 24
/datum/surgery_step/retract_skin/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -58,7 +68,7 @@
//close incision
/datum/surgery_step/close
name = "mend incision"
- implements = list(/obj/item/cautery = 100, /obj/item/gun/energy/laser = 90, TOOL_WELDER = 70,
+ implements = list(TOOL_CAUTERY = 100, /obj/item/gun/energy/laser = 90, TOOL_WELDER = 70,
/obj/item = 30) // 30% success with any hot item.
time = 24
@@ -69,7 +79,7 @@
/datum/surgery_step/close/tool_check(mob/user, obj/item/tool)
if(implement_type == TOOL_WELDER || implement_type == /obj/item)
- return tool.is_hot()
+ return tool.get_temperature()
return TRUE
/datum/surgery_step/close/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
if(locate(/datum/surgery_step/saw) in surgery.steps)
@@ -81,9 +91,7 @@
//saw bone
/datum/surgery_step/saw
name = "saw bone"
- implements = list(/obj/item/circular_saw = 100, /obj/item/melee/transforming/energy/sword/cyborg/saw = 100,
- /obj/item/melee/arm_blade = 75, /obj/item/mounted_chainsaw = 65, /obj/item/twohanded/required/chainsaw = 50,
- /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25)
+ implements = list(TOOL_SAW = 100, /obj/item/melee/arm_blade = 75, /obj/item/twohanded/fireaxe = 50, /obj/item/hatchet = 35, /obj/item/kitchen/knife/butcher = 25)
time = 54
/datum/surgery_step/saw/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -101,7 +109,7 @@
//drill bone
/datum/surgery_step/drill
name = "drill bone"
- implements = list(/obj/item/surgicaldrill = 100, /obj/item/screwdriver/power = 80, /obj/item/pickaxe/drill = 60, /obj/item/mecha_parts/mecha_equipment/drill = 60, TOOL_SCREWDRIVER = 20)
+ implements = list(TOOL_DRILL = 100, /obj/item/screwdriver/power = 80, /obj/item/pickaxe/drill = 60, TOOL_SCREWDRIVER = 20)
time = 30
/datum/surgery_step/drill/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
diff --git a/code/modules/surgery/organs/appendix.dm b/code/modules/surgery/organs/appendix.dm
index 34a7e16ebf..1f3f2fff5b 100644
--- a/code/modules/surgery/organs/appendix.dm
+++ b/code/modules/surgery/organs/appendix.dm
@@ -3,7 +3,21 @@
icon_state = "appendix"
zone = BODY_ZONE_PRECISE_GROIN
slot = ORGAN_SLOT_APPENDIX
- var/inflamed = 0
+ healing_factor = STANDARD_ORGAN_HEALING
+ decay_factor = STANDARD_ORGAN_DECAY
+
+ now_failing = "An explosion of pain erupts in your lower right abdomen! "
+ now_fixed = "The pain in your abdomen has subsided. "
+
+ var/inflamed
+
+/obj/item/organ/appendix/on_life()
+ ..()
+ if(!(organ_flags & ORGAN_FAILING))
+ return
+ var/mob/living/carbon/M = owner
+ if(M)
+ M.adjustToxLoss(4, TRUE, TRUE) //forced to ensure people don't use it to gain tox as slime person
/obj/item/organ/appendix/update_icon()
if(inflamed)
@@ -16,7 +30,7 @@
/obj/item/organ/appendix/Remove(mob/living/carbon/M, special = 0)
for(var/datum/disease/appendicitis/A in M.diseases)
A.cure()
- inflamed = 1
+ inflamed = TRUE
update_icon()
..()
diff --git a/code/modules/surgery/organs/augments_arms.dm b/code/modules/surgery/organs/augments_arms.dm
index 2489aa0705..e42fc91d47 100644
--- a/code/modules/surgery/organs/augments_arms.dm
+++ b/code/modules/surgery/organs/augments_arms.dm
@@ -121,7 +121,7 @@
playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1)
/obj/item/organ/cyberimp/arm/ui_action_click()
- if(crit_fail || (!holder && !contents.len))
+ if(crit_fail || (organ_flags & ORGAN_FAILING) || (!holder && !contents.len))
to_chat(owner, "The implant doesn't respond. It seems to be broken... ")
return
@@ -145,7 +145,7 @@
. = ..()
if(. & EMP_PROTECT_SELF)
return
- if(prob(30/severity) && owner && !crit_fail)
+ if(prob(30/severity) && owner && !(organ_flags & ORGAN_FAILING))
Retract()
owner.visible_message("A loud bang comes from [owner]\'s [zone == BODY_ZONE_R_ARM ? "right" : "left"] arm! ")
playsound(get_turf(owner), 'sound/weapons/flashbang.ogg', 100, 1)
@@ -154,6 +154,7 @@
owner.IgniteMob()
owner.adjustFireLoss(25)
crit_fail = 1
+ organ_flags |= ORGAN_FAILING
/obj/item/organ/cyberimp/arm/gun/laser
diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm
index ea336bea19..8af52abc47 100644
--- a/code/modules/surgery/organs/augments_chest.dm
+++ b/code/modules/surgery/organs/augments_chest.dm
@@ -129,7 +129,7 @@
var/datum/effect_system/trail_follow/ion/ion_trail
/obj/item/organ/cyberimp/chest/thrusters/Insert(mob/living/carbon/M, special = 0)
- ..()
+ . = ..()
if(!ion_trail)
ion_trail = new
ion_trail.set_up(M)
@@ -144,17 +144,21 @@
/obj/item/organ/cyberimp/chest/thrusters/proc/toggle(silent = FALSE)
if(!on)
- if(crit_fail)
+ if(crit_fail || (organ_flags & ORGAN_FAILING))
if(!silent)
to_chat(owner, "Your thrusters set seems to be broken! ")
return 0
on = TRUE
if(allow_thrust(0.01))
ion_trail.start()
+ RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/move_react)
+ owner.add_movespeed_modifier(MOVESPEED_ID_CYBER_THRUSTER, priority=100, multiplicative_slowdown=-2, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK)
if(!silent)
to_chat(owner, "You turn your thrusters set on. ")
else
ion_trail.stop()
+ UnregisterSignal(owner, COMSIG_MOVABLE_MOVED)
+ owner.remove_movespeed_modifier(MOVESPEED_ID_CYBER_THRUSTER)
if(!silent)
to_chat(owner, "You turn your thrusters set off. ")
on = FALSE
@@ -169,6 +173,9 @@
var/datum/action/A = X
A.UpdateButtonIcon()
+/obj/item/organ/cyberimp/chest/thrusters/proc/move_react()
+ allow_thrust(0.01)
+
/obj/item/organ/cyberimp/chest/thrusters/proc/allow_thrust(num)
if(!on || !owner)
return 0
diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm
index 06d523721d..f487e61d38 100644
--- a/code/modules/surgery/organs/augments_internal.dm
+++ b/code/modules/surgery/organs/augments_internal.dm
@@ -4,6 +4,7 @@
name = "cybernetic implant"
desc = "A state-of-the-art implant that improves a baseline's functionality."
status = ORGAN_ROBOTIC
+ organ_flags = ORGAN_SYNTHETIC
var/implant_color = "#FFFFFF"
var/implant_overlay
var/syndicate_implant = FALSE //Makes the implant invisible to health analyzers and medical HUDs.
@@ -102,7 +103,7 @@
/obj/item/organ/cyberimp/brain/anti_stun/on_life()
..()
- if(crit_fail)
+ if(crit_fail || !(organ_flags & ORGAN_FAILING))
return
owner.adjustStaminaLoss(-3.5) //Citadel edit, makes it more useful in Stamina based combat
if(owner.AmountStun() > STUN_SET_AMOUNT)
@@ -112,13 +113,15 @@
/obj/item/organ/cyberimp/brain/anti_stun/emp_act(severity)
. = ..()
- if(crit_fail || . & EMP_PROTECT_SELF)
+ if(crit_fail || (organ_flags & ORGAN_FAILING) || . & EMP_PROTECT_SELF)
return
crit_fail = TRUE
+ organ_flags |= ORGAN_FAILING
addtimer(CALLBACK(src, .proc/reboot), 90 / severity)
/obj/item/organ/cyberimp/brain/anti_stun/proc/reboot()
crit_fail = FALSE
+ organ_flags &= ~ORGAN_FAILING
//[[[[MOUTH]]]]
@@ -139,22 +142,3 @@
if(prob(60/severity))
to_chat(owner, "Your breathing tube suddenly closes! ")
owner.losebreath += 2
-
-//BOX O' IMPLANTS
-
-/obj/item/storage/box/cyber_implants
- name = "boxed cybernetic implants"
- desc = "A sleek, sturdy box."
- icon_state = "cyber_implants"
- var/list/boxed = list(
- /obj/item/autosurgeon/thermal_eyes,
- /obj/item/autosurgeon/xray_eyes,
- /obj/item/autosurgeon/anti_stun,
- /obj/item/autosurgeon/reviver)
- var/amount = 5
-
-/obj/item/storage/box/cyber_implants/PopulateContents()
- var/implant
- while(contents.len <= amount)
- implant = pick(boxed)
- new implant(src)
diff --git a/code/modules/surgery/organs/autosurgeon.dm b/code/modules/surgery/organs/autosurgeon.dm
index 2cc5c554c6..70959e6253 100644
--- a/code/modules/surgery/organs/autosurgeon.dm
+++ b/code/modules/surgery/organs/autosurgeon.dm
@@ -17,9 +17,10 @@
if(starting_organ)
insert_organ(new starting_organ(src))
-/obj/item/autosurgeon/proc/insert_organ(var/obj/item/I)
+/obj/item/autosurgeon/proc/insert_organ(var/obj/item/organ/I)
storedorgan = I
I.forceMove(src)
+ I.organ_flags |= ORGAN_FROZEN //Stops decay
name = "[initial(name)] ([storedorgan.name])"
/obj/item/autosurgeon/attack_self(mob/user)//when the object it used...
@@ -102,6 +103,26 @@
/obj/item/autosurgeon/anti_drop
starting_organ = /obj/item/organ/cyberimp/brain/anti_drop
+//BOX O' IMPLANTS
+
+/obj/item/storage/box/cyber_implants
+ name = "boxed cybernetic implants"
+ desc = "A sleek, sturdy box."
+ icon_state = "syndiebox"
+ illustration = "cyber_implants"
+ var/list/boxed = list(
+ /obj/item/autosurgeon/thermal_eyes,
+ /obj/item/autosurgeon/xray_eyes,
+ /obj/item/autosurgeon/anti_stun,
+ /obj/item/autosurgeon/reviver)
+ var/amount = 5
+
+/obj/item/storage/box/cyber_implants/PopulateContents()
+ var/implant
+ while(contents.len <= amount)
+ implant = pick(boxed)
+ new implant(src)
+
/obj/item/autosurgeon/penis
desc = "A single use autosurgeon that contains a penis. A screwdriver can be used to remove it, but implants can't be placed back in."
uses = 1
@@ -125,4 +146,4 @@
/obj/item/autosurgeon/womb
desc = "A single use autosurgeon that contains a womb. A screwdriver can be used to remove it, but implants can't be placed back in."
uses = 1
- starting_organ = /obj/item/organ/genital/womb
\ No newline at end of file
+ starting_organ = /obj/item/organ/genital/womb
diff --git a/code/modules/surgery/organs/ears.dm b/code/modules/surgery/organs/ears.dm
index 8e191a41a9..0d3002915e 100644
--- a/code/modules/surgery/organs/ears.dm
+++ b/code/modules/surgery/organs/ears.dm
@@ -6,6 +6,14 @@
slot = ORGAN_SLOT_EARS
gender = PLURAL
+ healing_factor = STANDARD_ORGAN_HEALING
+ decay_factor = STANDARD_ORGAN_DECAY
+
+ low_threshold_passed = "Your ears begin to resonate with an internal ring sometimes. "
+ now_failing = "You are unable to hear at all! "
+ now_fixed = "Noise slowly begins filling your ears once more. "
+ low_threshold_cleared = "The ringing in your ears has died down. "
+
// `deaf` measures "ticks" of deafness. While > 0, the person is unable
// to hear anything.
var/deaf = 0
@@ -23,17 +31,26 @@
/obj/item/organ/ears/on_life()
if(!iscarbon(owner))
return
+ ..()
var/mob/living/carbon/C = owner
+ if((damage < maxHealth) && (organ_flags & ORGAN_FAILING)) //ear damage can be repaired from the failing condition
+ organ_flags &= ~ORGAN_FAILING
// genetic deafness prevents the body from using the ears, even if healthy
if(HAS_TRAIT(C, TRAIT_DEAF))
deaf = max(deaf, 1)
- else if(ear_damage < UNHEALING_EAR_DAMAGE) // if higher than UNHEALING_EAR_DAMAGE, no natural healing occurs.
- ear_damage = max(ear_damage - 0.05, 0)
+ else if(!(organ_flags & ORGAN_FAILING)) // if this organ is failing, do not clear deaf stacks.
deaf = max(deaf - 1, 0)
+ if(prob(damage / 20) && (damage > low_threshold))
+ adjustEarDamage(0, 4)
+ SEND_SOUND(C, sound('sound/weapons/flash_ring.ogg'))
+ to_chat(C, "The ringing in your ears grows louder, blocking out any external noises for a moment. ")
+ else if((organ_flags & ORGAN_FAILING) && (deaf == 0))
+ deaf = 1 //stop being not deaf you deaf idiot
/obj/item/organ/ears/proc/restoreEars()
deaf = 0
ear_damage = 0
+ organ_flags &= ~ORGAN_FAILING
var/mob/living/carbon/C = owner
@@ -99,4 +116,23 @@
name = "tin ears"
desc = "The robust ears of a bronze golem. "
damage_multiplier = 0.1 //STRONK
- bang_protect = 1 //Fear me weaklings.
+ bang_protect = 1 //Fear me weaklings.
+
+/obj/item/organ/ears/cybernetic
+ name = "cybernetic ears"
+ icon_state = "ears-c"
+ desc = "a basic cybernetic designed to mimic the operation of ears."
+ damage_multiplier = 0.9
+ organ_flags = ORGAN_SYNTHETIC
+
+/obj/item/organ/ears/cybernetic/upgraded
+ name = "upgraded cybernetic ears"
+ icon_state = "ears-c-u"
+ desc = "an advanced cybernetic ear, surpassing the performance of organic ears"
+ damage_multiplier = 0.5
+
+/obj/item/organ/ears/cybernetic/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
+ return
+ damage += 40/severity
diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm
index 40d11ca2a4..d877af7451 100644
--- a/code/modules/surgery/organs/eyes.dm
+++ b/code/modules/surgery/organs/eyes.dm
@@ -6,6 +6,19 @@
slot = ORGAN_SLOT_EYES
gender = PLURAL
+ healing_factor = STANDARD_ORGAN_HEALING
+ decay_factor = STANDARD_ORGAN_DECAY
+ maxHealth = 0.5 * STANDARD_ORGAN_THRESHOLD //half the normal health max since we go blind at 30, a permanent blindness at 50 therefore makes sense unless medicine is administered
+ high_threshold = 0.3 * STANDARD_ORGAN_THRESHOLD //threshold at 30
+ low_threshold = 0.15 * STANDARD_ORGAN_THRESHOLD //threshold at 15
+
+ low_threshold_passed = "Distant objects become somewhat less tangible. "
+ high_threshold_passed = "Everything starts to look a lot less clear. "
+ now_failing = "Darkness envelopes you, as your eyes go blind! "
+ now_fixed = "Color and shapes are once again perceivable. "
+ high_threshold_cleared = "Your vision functions passably once more. "
+ low_threshold_cleared = "Your vision is cleared of any ailment. "
+
var/sight_flags = 0
var/see_in_dark = 2
var/eye_damage = 0
@@ -15,9 +28,12 @@
var/flash_protect = 0
var/see_invisible = SEE_INVISIBLE_LIVING
var/lighting_alpha
+ var/damaged = FALSE //damaged indicates that our eyes are undergoing some level of negative effect
/obj/item/organ/eyes/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = FALSE)
..()
+ if(damage == initial(damage))
+ clear_eye_trauma()
if(ishuman(owner))
var/mob/living/carbon/human/HMN = owner
old_eye_color = HMN.eye_color
@@ -32,7 +48,9 @@
M.update_tint()
owner.update_sight()
+
/obj/item/organ/eyes/Remove(mob/living/carbon/M, special = 0)
+ clear_eye_trauma()
..()
if(ishuman(M) && eye_color)
var/mob/living/carbon/human/HMN = M
@@ -41,6 +59,34 @@
M.update_tint()
M.update_sight()
+/obj/item/organ/eyes/on_life()
+ ..()
+ var/mob/living/carbon/C = owner
+ //since we can repair fully damaged eyes, check if healing has occurred
+ if((organ_flags & ORGAN_FAILING) && (damage < maxHealth))
+ organ_flags &= ~ORGAN_FAILING
+ C.cure_blind(EYE_DAMAGE)
+ //various degrees of "oh fuck my eyes", from "point a laser at your eye" to "staring at the Sun" intensities
+ if(damage > 20)
+ damaged = TRUE
+ if(organ_flags & ORGAN_FAILING)
+ C.become_blind(EYE_DAMAGE)
+ else if(damage > 30)
+ C.overlay_fullscreen("eye_damage", /obj/screen/fullscreen/impaired, 2)
+ else
+ C.overlay_fullscreen("eye_damage", /obj/screen/fullscreen/impaired, 1)
+ //called once since we don't want to keep clearing the screen of eye damage for people who are below 20 damage
+ else if(damaged)
+ damaged = FALSE
+ C.clear_fullscreen("eye_damage")
+ return
+
+/obj/item/organ/eyes/proc/clear_eye_trauma()
+ var/mob/living/carbon/C = owner
+ C.clear_fullscreen("eye_damage")
+ C.cure_blind(EYE_DAMAGE)
+ damaged = FALSE
+
/obj/item/organ/eyes/night_vision
name = "shadow eyes"
desc = "A spooky set of eyes that can see in the dark."
@@ -71,6 +117,7 @@
/obj/item/organ/eyes/night_vision/zombie
name = "undead eyes"
desc = "Somewhat counterintuitively, these half-rotten eyes actually have superior vision to those of a living human."
+ sight_flags = SEE_MOBS
/obj/item/organ/eyes/night_vision/nightmare
name = "burning red eyes"
@@ -88,15 +135,17 @@
icon_state = "cybernetic_eyeballs"
desc = "Your vision is augmented."
status = ORGAN_ROBOTIC
+ organ_flags = ORGAN_SYNTHETIC
/obj/item/organ/eyes/robotic/emp_act(severity)
. = ..()
if(!owner || . & EMP_PROTECT_SELF)
return
- if(prob(10 * severity))
- return
to_chat(owner, "Static obfuscates your vision! ")
owner.flash_act(visual = 1)
+ if(severity == EMP_HEAVY)
+ owner.adjustOrganLoss(ORGAN_SLOT_EYES, 20)
+
/obj/item/organ/eyes/robotic/xray
name = "\improper X-ray eyes"
@@ -137,7 +186,7 @@
M.become_blind("flashlight_eyes")
-/obj/item/organ/eyes/robotic/flashlight/Remove(var/mob/living/carbon/M, var/special = 0)
+/obj/item/organ/eyes/robotic/flashlight/Remove(var/mob/living/carbon/M, special = FALSE)
eye.on = FALSE
eye.update_brightness(M)
eye.forceMove(src)
@@ -178,7 +227,7 @@
terminate_effects()
. = ..()
-/obj/item/organ/eyes/robotic/glow/Remove()
+/obj/item/organ/eyes/robotic/glow/Remove(mob/living/carbon/M, special = FALSE)
terminate_effects()
. = ..()
@@ -289,7 +338,7 @@
/obj/item/organ/eyes/robotic/glow/proc/start_visuals()
if(!islist(eye_lighting))
regenerate_light_effects()
- if((eye_lighting.len < light_beam_distance) || !on_mob)
+ if((LAZYLEN(eye_lighting) < light_beam_distance) || !on_mob)
regenerate_light_effects()
sync_light_effects()
update_visuals()
diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm
index 5852cba0c9..82fbf932e9 100644
--- a/code/modules/surgery/organs/heart.dm
+++ b/code/modules/surgery/organs/heart.dm
@@ -4,12 +4,24 @@
icon_state = "heart-on"
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_HEART
+
+ healing_factor = STANDARD_ORGAN_HEALING
+ decay_factor = 3 * STANDARD_ORGAN_DECAY //designed to fail about 5 minutes after death
+
+ low_threshold_passed = "Prickles of pain appear then die out from within your chest... "
+ high_threshold_passed = "Something inside your chest hurts, and the pain isn't subsiding. You notice yourself breathing far faster than before. "
+ now_fixed = "Your heart begins to beat again. "
+ high_threshold_cleared = "The pain in your chest has died down, and your breathing becomes more relaxed. "
+
// Heart attack code is in code/modules/mob/living/carbon/human/life.dm
var/beating = 1
var/icon_base = "heart"
attack_verb = list("beat", "thumped")
var/beat = BEAT_NONE//is this mob having a heatbeat sound played? if so, which?
+ var/failed = FALSE //to prevent constantly running failing code
+ var/operated = FALSE //whether the heart's been operated on to fix some of its damages
+
/obj/item/organ/heart/update_icon()
if(beating)
icon_state = "[icon_base]-on"
@@ -45,11 +57,13 @@
/obj/item/organ/heart/prepare_eat()
var/obj/S = ..()
- S.icon_state = "heart-off"
+ S.icon_state = "[icon_base]-off"
return S
/obj/item/organ/heart/on_life()
+ ..()
if(owner.client && beating)
+ failed = FALSE
var/sound/slowbeat = sound('sound/health/slowbeat.ogg', repeat = TRUE)
var/sound/fastbeat = sound('sound/health/fastbeat.ogg', repeat = TRUE)
var/mob/living/carbon/H = owner
@@ -70,11 +84,24 @@
H.stop_sound_channel(CHANNEL_HEARTBEAT)
beat = BEAT_NONE
+ if(organ_flags & ORGAN_FAILING) //heart broke, stopped beating, death imminent
+ if(owner.stat == CONSCIOUS)
+ owner.visible_message("[owner] clutches at [owner.p_their()] chest as if [owner.p_their()] heart is stopping! ")
+ owner.set_heartattack(TRUE)
+ failed = TRUE
+
+obj/item/organ/heart/slime
+ name = "slime heart"
+ desc = "It seems we've gotten to the slimy core of the matter."
+ icon_state = "heart-s-on"
+ icon_base = "heart-s"
+
/obj/item/organ/heart/cursed
name = "cursed heart"
desc = "A heart that, when inserted, will force you to pump it manually."
icon_state = "cursedheart-off"
icon_base = "cursedheart"
+ decay_factor = 0
actions_types = list(/datum/action/item_action/organ_action/cursed_heart)
var/last_pump = 0
var/add_colour = TRUE //So we're not constantly recreating colour datums
@@ -153,18 +180,61 @@
name = "cybernetic heart"
desc = "An electronic device designed to mimic the functions of an organic human heart. Offers no benefit over an organic heart other than being easy to make."
icon_state = "heart-c"
- synthetic = TRUE
+ organ_flags = ORGAN_SYNTHETIC
-/obj/item/organ/heart/cybernetic/emp_act()
+/obj/item/organ/heart/cybernetic/emp_act(severity)
. = ..()
if(. & EMP_PROTECT_SELF)
return
Stop()
+ addtimer(CALLBACK(src, .proc/Restart), 20/severity SECONDS)
+ damage += 100/severity
+
+/obj/item/organ/heart/cybernetic/upgraded
+ name = "upgraded cybernetic heart"
+ desc = "An electronic device designed to mimic the functions of an organic human heart. Also holds an emergency dose of epinephrine, used automatically after facing severe trauma. This upgraded model can regenerate its dose after use."
+ icon_state = "heart-c-u"
+ maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
+
+ //I put it on upgraded for now.
+ var/dose_available = TRUE
+ var/rid = /datum/reagent/medicine/epinephrine
+ var/ramount = 10
+
+obj/item/organ/heart/cybernetic/upgraded/on_life()
+ . = ..()
+ if(dose_available && owner.health <= owner.crit_threshold && !owner.reagents.has_reagent(rid))
+ owner.reagents.add_reagent(rid, ramount)
+ used_dose()
+ if(ramount < 10) //eats your nutrition to regen epinephrine
+ var/regen_amount = owner.nutrition/2000
+ owner.nutrition -= regen_amount
+ ramount += regen_amount
+
+/obj/item/organ/heart/cybernetic/upgraded/proc/used_dose()
+ . = ..()
+ addtimer(VARSET_CALLBACK(src, dose_available, TRUE), 5 MINUTES)
+ ramount = 0
+
+
+
+/obj/item/organ/heart/ipc
+ name = "IPC heart"
+ desc = "An electronic pump that regulates hydraulic functions, they have an auto-restart after EMPs."
+ icon_state = "heart-c"
+ organ_flags = ORGAN_SYNTHETIC
+
+/obj/item/organ/heart/ipc/emp_act()
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
+ return
+ Stop()
+ addtimer(CALLBACK(src, .proc/Restart), 10)
/obj/item/organ/heart/freedom
name = "heart of freedom"
desc = "This heart pumps with the passion to give... something freedom."
- synthetic = TRUE //the power of freedom prevents heart attacks
+ organ_flags = ORGAN_SYNTHETIC //the power of freedom prevents heart attacks
var/min_next_adrenaline = 0
/obj/item/organ/heart/freedom/on_life()
diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm
index 94973a8e10..01559c83c3 100755
--- a/code/modules/surgery/organs/liver.dm
+++ b/code/modules/surgery/organs/liver.dm
@@ -10,10 +10,13 @@
zone = BODY_ZONE_CHEST
slot = ORGAN_SLOT_LIVER
desc = "Pairing suggestion: chianti and fava beans."
- var/damage = 0 //liver damage, 0 is no damage, damage=maxHealth causes liver failure
+
+ maxHealth = STANDARD_ORGAN_THRESHOLD
+ healing_factor = STANDARD_ORGAN_HEALING
+ decay_factor = STANDARD_ORGAN_DECAY
+
var/alcohol_tolerance = ALCOHOL_RATE//affects how much damage the liver takes from alcohol
var/failing //is this liver failing?
- var/maxHealth = LIVER_DEFAULT_HEALTH
var/toxTolerance = LIVER_DEFAULT_TOX_TOLERANCE//maximum amount of toxins the liver can just shrug off
var/toxLethality = LIVER_DEFAULT_TOX_LETHALITY//affects how much damage toxins do to the liver
var/filterToxins = TRUE //whether to filter toxins
@@ -24,7 +27,7 @@
var/mob/living/carbon/C = owner
if(istype(C))
- if(!failing)//can't process reagents with a failing liver
+ if(!(organ_flags & ORGAN_FAILING))//can't process reagents with a failing liver
//slowly heal liver damage
damage = max(0, damage - 0.1)
@@ -69,7 +72,7 @@
if(moveCalc == cachedmoveCalc)//reduce calculations
return
if(prob(5))
- to_chat(owner, "You feel a stange ache in your side, almost like a sitch. This pain is affecting your movements and making you feel lightheaded. ")
+ to_chat(owner, "You feel a stange ache in your side, almost like a stitch. This pain is affecting your movements and making you feel lightheaded. ")
var/mob/living/carbon/human/H = owner
H.add_movespeed_modifier(LIVER_SWELLING_MOVE_MODIFY, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
H.AdjustBloodVol(moveCalc/3)
@@ -97,14 +100,15 @@
name = "cybernetic liver"
icon_state = "liver-c"
desc = "An electronic device designed to mimic the functions of a human liver. It has no benefits over an organic liver, but is easy to produce."
- synthetic = TRUE
+ organ_flags = ORGAN_SYNTHETIC
+ maxHealth = 1.1 * STANDARD_ORGAN_THRESHOLD
/obj/item/organ/liver/cybernetic/upgraded
name = "upgraded cybernetic liver"
icon_state = "liver-c-u"
desc = "An upgraded version of the cybernetic liver, designed to improve upon organic livers. It is resistant to alcohol poisoning and is very robust at filtering toxins."
alcohol_tolerance = 0.001
- maxHealth = 200 //double the health of a normal liver
+ maxHealth = 2 * STANDARD_ORGAN_THRESHOLD
toxTolerance = 15 //can shrug off up to 15u of toxins
toxLethality = 0.008 //20% less damage than a normal liver
diff --git a/code/modules/surgery/organs/lungs.dm b/code/modules/surgery/organs/lungs.dm
index cfbb530e69..6b0e4f01ae 100644
--- a/code/modules/surgery/organs/lungs.dm
+++ b/code/modules/surgery/organs/lungs.dm
@@ -8,6 +8,21 @@
gender = PLURAL
w_class = WEIGHT_CLASS_NORMAL
+ var/failed = FALSE
+ var/operated = FALSE //whether we can still have our damages fixed through surgery
+
+ //health
+ maxHealth = 3 * STANDARD_ORGAN_THRESHOLD
+
+ healing_factor = STANDARD_ORGAN_HEALING
+ decay_factor = STANDARD_ORGAN_DECAY
+ high_threshold = 0.6 * LUNGS_MAX_HEALTH //threshold at 180
+ low_threshold = 0.3 * LUNGS_MAX_HEALTH //threshold at 90
+
+ high_threshold_passed = "You feel some sort of constriction around your chest as your breathing becomes shallow and rapid. "
+ now_fixed = "Your lungs seem to once again be able to hold air. "
+ high_threshold_cleared = "The constriction around your chest loosens as your breathing calms down. "
+
//Breath damage
var/safe_oxygen_min = 16 // Minimum safe partial pressure of O2, in kPa
@@ -56,36 +71,35 @@
var/crit_stabilizing_reagent = "epinephrine"
- //health
- var/maxHealth = LUNGS_MAX_HEALTH
- var/damage = 0
+
//TODO: lung health affects lung function
-/obj/item/organ/lungs/proc/adjustLungLoss(damage_mod, mob/living/carbon/M) //damage might be too low atm.
+/obj/item/organ/lungs/onDamage(damage_mod) //damage might be too low atm.
+ var/cached_damage = damage
if (maxHealth == INFINITY)
return
- if(damage+damage_mod < 0)
- damage = 0
+ if(cached_damage+damage_mod < 0)
+ cached_damage = 0
return
- damage += damage_mod
- if ((damage / maxHealth) > 1)
- to_chat(M, "You feel your lungs collapse within your chest as you gasp for air, unable to inflate them anymore! ")
- M.emote("gasp")
+ cached_damage += damage_mod
+ if ((cached_damage/ maxHealth) > 1)
+ to_chat(owner, "You feel your lungs collapse within your chest as you gasp for air, unable to inflate them anymore! ")
+ owner.emote("gasp")
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Lungs lost")
- qdel(src)
- else if ((damage / maxHealth) > 0.75)
- to_chat(M, "It's getting really hard to breathe!! ")
- M.emote("gasp")
- M.Dizzy(3)
- else if ((damage / maxHealth) > 0.5)
- M.Dizzy(2)
- to_chat(M, "Your chest is really starting to hurt. ")
- M.emote("cough")
- else if ((damage / maxHealth) > 0.2)
- to_chat(M, "You feel an ache within your chest. ")
- M.emote("cough")
- M.Dizzy(1)
+ //qdel(src) - Handled elsewhere for now.
+ else if ((cached_damage / maxHealth) > 0.75)
+ to_chat(owner, "It's getting really hard to breathe!! ")
+ owner.emote("gasp")
+ owner.Dizzy(3)
+ else if ((cached_damage / maxHealth) > 0.5)
+ owner.Dizzy(2)
+ to_chat(owner, "Your chest is really starting to hurt. ")
+ owner.emote("cough")
+ else if ((cached_damage / maxHealth) > 0.2)
+ to_chat(owner, "You feel an ache within your chest. ")
+ owner.emote("cough")
+ owner.Dizzy(1)
/obj/item/organ/lungs/proc/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
//TODO: add lung damage = less oxygen gains
@@ -289,7 +303,7 @@
H.hallucination += 10
H.reagents.add_reagent("bz_metabolites",5)
if(prob(33))
- H.adjustBrainLoss(3, 150)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3, 150)
else if(bz_pp > 0.01)
H.hallucination += 5
@@ -405,13 +419,13 @@
var/cold_modifier = H.dna.species.coldmod
if(breath_temperature < cold_level_3_threshold)
H.apply_damage_type(cold_level_3_damage*cold_modifier, cold_damage_type)
- adjustLungLoss((cold_level_3_damage*cold_modifier*2), H)
+ H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (cold_level_3_damage*cold_modifier*2))
if(breath_temperature > cold_level_3_threshold && breath_temperature < cold_level_2_threshold)
H.apply_damage_type(cold_level_2_damage*cold_modifier, cold_damage_type)
- adjustLungLoss((cold_level_2_damage*cold_modifier*2), H)
+ H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (cold_level_2_damage*cold_modifier*2))
if(breath_temperature > cold_level_2_threshold && breath_temperature < cold_level_1_threshold)
H.apply_damage_type(cold_level_1_damage*cold_modifier, cold_damage_type)
- adjustLungLoss((cold_level_1_damage*cold_modifier*2), H)
+ H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (cold_level_1_damage*cold_modifier*2))
if(breath_temperature < cold_level_1_threshold)
if(prob(20))
to_chat(H, "You feel [cold_message] in your [name]! ")
@@ -420,17 +434,29 @@
var/heat_modifier = H.dna.species.heatmod
if(breath_temperature > heat_level_1_threshold && breath_temperature < heat_level_2_threshold)
H.apply_damage_type(heat_level_1_damage*heat_modifier, heat_damage_type)
- adjustLungLoss((heat_level_1_damage*heat_modifier*2), H)
+ H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (heat_level_1_damage*heat_modifier*2))
if(breath_temperature > heat_level_2_threshold && breath_temperature < heat_level_3_threshold)
H.apply_damage_type(heat_level_2_damage*heat_modifier, heat_damage_type)
- adjustLungLoss((heat_level_2_damage*heat_modifier*2), H)
+ H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (heat_level_2_damage*heat_modifier*2))
if(breath_temperature > heat_level_3_threshold)
H.apply_damage_type(heat_level_3_damage*heat_modifier, heat_damage_type)
- adjustLungLoss((heat_level_3_damage*heat_modifier*2), H)
+ H.adjustOrganLoss(ORGAN_SLOT_LUNGS, (heat_level_3_damage*heat_modifier*2))
if(breath_temperature > heat_level_1_threshold)
if(prob(20))
to_chat(H, "You feel [hot_message] in your [name]! ")
+
+/obj/item/organ/lungs/on_life()
+ ..()
+ if((!failed) && ((organ_flags & ORGAN_FAILING)))
+ if(owner.stat == CONSCIOUS)
+ owner.visible_message("[owner] grabs [owner.p_their()] throat, struggling for breath! ", \
+ "You suddenly feel like you can't breathe! ")
+ failed = TRUE
+ else if(!(organ_flags & ORGAN_FAILING))
+ failed = FALSE
+ return
+
/obj/item/organ/lungs/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent("salbutamol", 5)
@@ -451,14 +477,16 @@
name = "cybernetic lungs"
desc = "A cybernetic version of the lungs found in traditional humanoid entities. It functions the same as an organic lung and is merely meant as a replacement."
icon_state = "lungs-c"
- synthetic = TRUE
+ organ_flags = ORGAN_SYNTHETIC
maxHealth = 400
+ safe_oxygen_min = 13
/obj/item/organ/lungs/cybernetic/emp_act()
. = ..()
if(. & EMP_PROTECT_SELF)
return
owner.losebreath = 20
+ owner.adjustOrganLoss(ORGAN_SLOT_LUNGS, 25)
/obj/item/organ/lungs/cybernetic/upgraded
@@ -495,8 +523,24 @@
safe_toxins_max = 0 //We breathe this to gain POWER.
+ cold_level_1_threshold = 285 // Remember when slimes used to be succeptable to cold? Well....
+ cold_level_2_threshold = 260
+ cold_level_3_threshold = 230
+
+ maxHealth = 250
+
/obj/item/organ/lungs/slime/check_breath(datum/gas_mixture/breath, mob/living/carbon/human/H)
. = ..()
if (breath && breath.gases[/datum/gas/plasma])
var/plasma_pp = breath.get_breath_partial_pressure(breath.gases[/datum/gas/plasma])
owner.blood_volume += (0.2 * plasma_pp) // 10/s when breathing literally nothing but plasma, which will suffocate you.
+
+/obj/item/organ/lungs/yamerol
+ name = "Yamerol lungs"
+ desc = "A temporary pair of lungs made from self assembling yamerol molecules."
+ maxHealth = 200
+ color = "#68e83a"
+
+/obj/item/organ/lungs/yamerol/on_life()
+ ..()
+ damage += 2 //Yamerol lungs are temporary
diff --git a/code/modules/surgery/organs/organ_internal.dm b/code/modules/surgery/organs/organ_internal.dm
index 9f910de9a9..194a10f4c4 100644
--- a/code/modules/surgery/organs/organ_internal.dm
+++ b/code/modules/surgery/organs/organ_internal.dm
@@ -1,3 +1,6 @@
+#define STANDARD_ORGAN_THRESHOLD 100
+#define STANDARD_ORGAN_HEALING 0.001
+
/obj/item/organ
name = "organ"
icon = 'icons/obj/surgery.dmi'
@@ -8,15 +11,27 @@
var/zone = BODY_ZONE_CHEST
var/slot
// DO NOT add slots with matching names to different zones - it will break internal_organs_slot list!
- var/vital = 0
- //Was this organ implanted/inserted/etc, if true will not be removed during species change.
- var/external = FALSE
- var/synthetic = FALSE // To distinguish between organic and synthetic organs
+ var/organ_flags = 0
+ var/maxHealth = STANDARD_ORGAN_THRESHOLD
+ var/damage = 0 //total damage this organ has sustained
+ ///Healing factor and decay factor function on % of maxhealth, and do not work by applying a static number per tick
+ var/healing_factor = 0 //fraction of maxhealth healed per on_life(), set to 0 for generic organs
+ var/decay_factor = 0 //same as above but when without a living owner, set to 0 for generic organs
+ var/high_threshold = STANDARD_ORGAN_THRESHOLD * 0.45 //when severe organ damage occurs
+ var/low_threshold = STANDARD_ORGAN_THRESHOLD * 0.1 //when minor organ damage occurs
+ ///Organ variables for determining what we alert the owner with when they pass/clear the damage thresholds
+ var/prev_damage = 0
+ var/low_threshold_passed
+ var/high_threshold_passed
+ var/now_failing
+ var/now_fixed
+ var/high_threshold_cleared
+ var/low_threshold_cleared
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
if(!iscarbon(M) || owner == M)
- return
+ return FALSE
var/obj/item/organ/replaced = M.getorganslot(slot)
if(replaced)
@@ -26,6 +41,9 @@
else
qdel(replaced)
+ //Hopefully this doesn't cause problems
+ organ_flags &= ~ORGAN_FROZEN
+
owner = M
M.internal_organs |= src
M.internal_organs_slot[slot] = src
@@ -33,31 +51,115 @@
for(var/X in actions)
var/datum/action/A = X
A.Grant(M)
+ STOP_PROCESSING(SSobj, src)
+
+ return TRUE
//Special is for instant replacement like autosurgeons
-/obj/item/organ/proc/Remove(mob/living/carbon/M, special = 0)
+/obj/item/organ/proc/Remove(mob/living/carbon/M, special = FALSE)
owner = null
if(M)
M.internal_organs -= src
if(M.internal_organs_slot[slot] == src)
M.internal_organs_slot.Remove(slot)
- if(vital && !special && !(M.status_flags & GODMODE))
+ if((organ_flags & ORGAN_VITAL) && !special && !(M.status_flags & GODMODE))
M.death()
for(var/X in actions)
var/datum/action/A = X
A.Remove(M)
+ START_PROCESSING(SSobj, src)
+ return TRUE
/obj/item/organ/proc/on_find(mob/living/finder)
return
-/obj/item/organ/proc/on_life()
- return
+/obj/item/organ/process() //runs decay when outside of a person AND ONLY WHEN OUTSIDE (i.e. long obj).
+ on_death() //Kinda hate doing it like this, but I really don't want to call process directly.
+
+//Sources; life.dm process_organs
+/obj/item/organ/proc/on_death() //Runs when outside AND inside.
+ decay()
+
+//Applys the slow damage over time decay
+/obj/item/organ/proc/decay()
+ if(!can_decay())
+ STOP_PROCESSING(SSobj, src)
+ return
+ is_cold()
+ if(organ_flags & ORGAN_FROZEN)
+ return
+ applyOrganDamage(maxHealth * decay_factor)
+
+/obj/item/organ/proc/can_decay()
+ if(CHECK_BITFIELD(organ_flags, ORGAN_NO_SPOIL | ORGAN_SYNTHETIC | ORGAN_FAILING))
+ return FALSE
+ return TRUE
+
+//Checks to see if the organ is frozen from temperature
+/obj/item/organ/proc/is_cold()
+ var/freezing_objects = list(/obj/structure/closet/crate/freezer, /obj/structure/closet/secure_closet/freezer, /obj/structure/bodycontainer, /obj/item/autosurgeon)
+ if(istype(loc, /obj/))//Freezer of some kind, I hope.
+ if(is_type_in_list(loc, freezing_objects))
+ if(!(organ_flags & ORGAN_FROZEN))//Incase someone puts them in when cold, but they warm up inside of the thing. (i.e. they have the flag, the thing turns it off, this rights it.)
+ organ_flags |= ORGAN_FROZEN
+ return TRUE
+ return
+
+ var/local_temp
+ if(istype(loc, /turf/))//Only concern is adding an organ to a freezer when the area around it is cold.
+ var/turf/T = loc
+ var/datum/gas_mixture/enviro = T.return_air()
+ local_temp = enviro.temperature
+
+ else if(istype(loc, /mob/) && !owner)
+ var/mob/M = loc
+ if(is_type_in_list(M.loc, freezing_objects))
+ if(!(organ_flags & ORGAN_FROZEN))
+ organ_flags |= ORGAN_FROZEN
+ return TRUE
+ var/turf/T = M.loc
+ var/datum/gas_mixture/enviro = T.return_air()
+ local_temp = enviro.temperature
+
+ if(owner)
+ //Don't interfere with bodies frozen by structures.
+ if(is_type_in_list(owner.loc, freezing_objects))
+ if(!(organ_flags & ORGAN_FROZEN))
+ organ_flags |= ORGAN_FROZEN
+ return TRUE
+ local_temp = owner.bodytemperature
+
+ if(!local_temp)//Shouldn't happen but in case
+ return
+ if(local_temp < 154)//I have a pretty shaky citation that states -120 allows indefinite cyrostorage
+ organ_flags |= ORGAN_FROZEN
+ return TRUE
+ organ_flags &= ~ORGAN_FROZEN
+ return FALSE
+
+/obj/item/organ/proc/on_life() //repair organ damage if the organ is not failing
+ if(organ_flags & ORGAN_FAILING)
+ return
+ if(is_cold())
+ return
+ ///Damage decrements by a percent of its maxhealth
+ var/healing_amount = -(maxHealth * healing_factor)
+ ///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
+ healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0
+ applyOrganDamage(healing_amount) //to FERMI_TWEAK
+ //Make it so each threshold is stuck.
/obj/item/organ/examine(mob/user)
- ..()
- if(status == ORGAN_ROBOTIC && crit_fail)
- to_chat(user, "[src] seems to be broken! ")
+ . = ..()
+ if(organ_flags & ORGAN_FAILING)
+ if(status == ORGAN_ROBOTIC)
+ . += "[src] seems to be broken! "
+ return
+ . += "[src] has decayed for too long, and has turned a sickly color! It doesn't look like it will work anymore! "
+ return
+ if(damage > high_threshold)
+ . += "[src] is starting to look discolored. "
/obj/item/organ/proc/prepare_eat()
@@ -78,11 +180,15 @@
foodtype = RAW | MEAT | GROSS
+/obj/item/organ/Initialize()
+ . = ..()
+ START_PROCESSING(SSobj, src)
+
/obj/item/organ/Destroy()
if(owner)
// The special flag is important, because otherwise mobs can die
// while undergoing transformation into different mobs.
- Remove(owner, special=TRUE)
+ Remove(owner, TRUE)
return ..()
/obj/item/organ/attack(mob/living/carbon/M, mob/user)
@@ -100,13 +206,66 @@
/obj/item/organ/item_action_slot_check(slot,mob/user)
return //so we don't grant the organ's action to mobs who pick up the organ.
+///Adjusts an organ's damage by the amount "d", up to a maximum amount, which is by default max damage
+/obj/item/organ/proc/applyOrganDamage(var/d, var/maximum = maxHealth) //use for damaging effects
+ if(!d) //Micro-optimization.
+ return
+ if(maximum < damage)
+ return
+ damage = CLAMP(damage + d, 0, maximum)
+ var/mess = check_damage_thresholds(owner)
+ prev_damage = damage
+ if(mess && owner)
+ to_chat(owner, mess)
+
+///SETS an organ's damage to the amount "d", and in doing so clears or sets the failing flag, good for when you have an effect that should fix an organ if broken
+/obj/item/organ/proc/setOrganDamage(var/d) //use mostly for admin heals
+ applyOrganDamage(d - damage)
+
+/** check_damage_thresholds
+ * input: M (a mob, the owner of the organ we call the proc on)
+ * output: returns a message should get displayed.
+ * description: By checking our current damage against our previous damage, we can decide whether we've passed an organ threshold.
+ * If we have, send the corresponding threshold message to the owner, if such a message exists.
+ */
+/obj/item/organ/proc/check_damage_thresholds(var/M)
+ if(damage == prev_damage)
+ return
+ var/delta = damage - prev_damage
+ if(delta > 0)
+ if(damage >= maxHealth)
+ organ_flags |= ORGAN_FAILING
+ return now_failing
+ if(damage > high_threshold && prev_damage <= high_threshold)
+ return high_threshold_passed
+ if(damage > low_threshold && prev_damage <= low_threshold)
+ return low_threshold_passed
+ else
+ organ_flags &= ~ORGAN_FAILING
+ if(!owner)//Processing is stopped when the organ is dead and outside of someone. This hopefully should restart it if a removed organ is repaired outside of a body.
+ START_PROCESSING(SSobj, src)
+ if(prev_damage > low_threshold && damage <= low_threshold)
+ return low_threshold_cleared
+ if(prev_damage > high_threshold && damage <= high_threshold)
+ return high_threshold_cleared
+ if(prev_damage == maxHealth)
+ return now_fixed
+
+//Runs some code on the organ when damage is taken/healed
+/obj/item/organ/proc/onDamage(var/d, var/maximum = maxHealth)
+ return
+
+//Runs some code on the organ when damage is taken/healed
+/obj/item/organ/proc/onSetDamage(var/d, var/maximum = maxHealth)
+ return
+
//Looking for brains?
//Try code/modules/mob/living/carbon/brain/brain_item.dm
/mob/living/proc/regenerate_organs()
return 0
-/mob/living/carbon/regenerate_organs()
+/mob/living/carbon/regenerate_organs(only_one = FALSE)
var/breathes = TRUE
var/blooded = TRUE
if(dna && dna.species)
@@ -125,6 +284,8 @@
else
LI = new()
LI.Insert(src)
+ if(only_one)
+ return TRUE
if(has_stomach && !getorganslot(ORGAN_SLOT_STOMACH))
var/obj/item/organ/stomach/S
@@ -134,14 +295,20 @@
else
S = new()
S.Insert(src)
+ if(only_one)
+ return TRUE
if(breathes && !getorganslot(ORGAN_SLOT_LUNGS))
var/obj/item/organ/lungs/L = new()
L.Insert(src)
+ if(only_one)
+ return TRUE
if(blooded && !getorganslot(ORGAN_SLOT_HEART))
var/obj/item/organ/heart/H = new()
H.Insert(src)
+ if(only_one)
+ return TRUE
if(!getorganslot(ORGAN_SLOT_TONGUE))
var/obj/item/organ/tongue/T
@@ -153,7 +320,10 @@
// if they have no mutant tongues, give them a regular one
T.Insert(src)
- else
+ if(only_one)
+ return TRUE
+
+ else if (!only_one)
var/obj/item/organ/tongue/oT = getorganslot(ORGAN_SLOT_TONGUE)
if(oT.name == "fluffy tongue")
var/obj/item/organ/tongue/T
@@ -174,6 +344,8 @@
else
E = new()
E.Insert(src)
+ if(only_one)
+ return TRUE
if(!getorganslot(ORGAN_SLOT_EARS))
var/obj/item/organ/ears/ears
@@ -183,9 +355,13 @@
ears = new
ears.Insert(src)
+ if(only_one)
+ return TRUE
if(!getorganslot(ORGAN_SLOT_TAIL))
var/obj/item/organ/tail/tail
if(dna && dna.species && dna.species.mutanttail)
tail = new dna.species.mutanttail
tail.Insert(src)
+ if(only_one)
+ return TRUE
diff --git a/code/modules/surgery/organs/stomach.dm b/code/modules/surgery/organs/stomach.dm
index 24132bcf04..a1624efd61 100755
--- a/code/modules/surgery/organs/stomach.dm
+++ b/code/modules/surgery/organs/stomach.dm
@@ -8,12 +8,42 @@
desc = "Onaka ga suite imasu."
var/disgust_metabolism = 1
-/obj/item/organ/stomach/on_life()
- var/mob/living/carbon/human/H = owner
+ healing_factor = STANDARD_ORGAN_HEALING
+ decay_factor = STANDARD_ORGAN_DECAY
- if(istype(H))
- H.dna.species.handle_digestion(H)
+ low_threshold_passed = "Your stomach flashes with pain before subsiding. Food doesn't seem like a good idea right now. "
+ high_threshold_passed = "Your stomach flares up with constant pain- you can hardly stomach the idea of food right now! "
+ high_threshold_cleared = "The pain in your stomach dies down for now, but food still seems unappealing. "
+ low_threshold_cleared = "The last bouts of pain in your stomach have died out. "
+
+/obj/item/organ/stomach/on_life()
+ ..()
+ var/datum/reagent/consumable/nutriment/Nutri
+ if(ishuman(owner))
+ var/mob/living/carbon/human/H = owner
+ if(!(organ_flags & ORGAN_FAILING))
+ H.dna.species.handle_digestion(H)
handle_disgust(H)
+ Nutri = locate(/datum/reagent/consumable/nutriment) in H.reagents.reagent_list
+
+ if(Nutri)
+ if(prob((damage/40) * Nutri.volume * Nutri.volume))
+ H.vomit(damage)
+ to_chat(H, "Your stomach reels in pain as you're incapable of holding down all that food! ")
+
+ else if(Nutri && damage > high_threshold)
+ if(prob((damage/10) * Nutri.volume * Nutri.volume))
+ H.vomit(damage)
+ to_chat(H, "Your stomach reels in pain as you're incapable of holding down all that food! ")
+
+
+ else if(iscarbon(owner))
+ var/mob/living/carbon/C = owner
+ Nutri = locate(/datum/reagent/consumable/nutriment) in C.reagents.reagent_list
+
+ if(damage < low_threshold)
+ return
+
/obj/item/organ/stomach/proc/handle_disgust(mob/living/carbon/human/H)
if(H.disgust)
diff --git a/code/modules/surgery/organs/tongue.dm b/code/modules/surgery/organs/tongue.dm
index 3eaaa8de92..a9e2b331bb 100644
--- a/code/modules/surgery/organs/tongue.dm
+++ b/code/modules/surgery/organs/tongue.dm
@@ -10,8 +10,7 @@
var/list/languages_possible
var/say_mod = null
var/taste_sensitivity = 15 // lower is more sensitive.
- var/maxHealth = TONGUE_MAX_HEALTH
- var/damage = 0
+ maxHealth = TONGUE_MAX_HEALTH
var/modifies_speech = FALSE
var/static/list/languages_possible_base = typecacheof(list(
/datum/language/common,
@@ -24,6 +23,8 @@
/datum/language/aphasia,
/datum/language/slime,
))
+ healing_factor = STANDARD_ORGAN_HEALING*5 //Fast!!
+ decay_factor = STANDARD_ORGAN_DECAY/2
/obj/item/organ/tongue/Initialize(mapload)
. = ..()
@@ -31,27 +32,34 @@
/obj/item/organ/tongue/proc/handle_speech(datum/source, list/speech_args)
-/obj/item/organ/tongue/proc/adjustTongueLoss(mob/living/carbon/M, damage_mod)
- if (maxHealth == "alien")
- return
- if (maxHealth == "bone")
- var/target = M.get_bodypart(BODY_ZONE_HEAD)
- M.apply_damage(damage_mod, BURN, target)
- to_chat(M, "The drink burns your skull! Oof, your bones! ")
- return
- if(damage+damage_mod < 0)
- damage = 0
+/obj/item/organ/tongue/emp_act(severity)
+ . = ..()
+ if(. & EMP_PROTECT_SELF)
return
+ if(organ_flags & ORGAN_SYNTHETIC)
+ var/errormessage = list("Runtime in tongue.dm, line 39: Undefined operation \"zapzap ow my tongue\"", "afhsjifksahgjkaslfhashfjsak", "-1.#IND", "Graham's number", "inside you all along", "awaiting at least 1 approving review before merging this taste request")
+ owner.say("The pH is appropriately [pick(errormessage)].")
+
+/obj/item/organ/tongue/applyOrganDamage(var/d, var/maximum = maxHealth)
+
+ if(!d) //Micro-optimization.
+ return
+ if(maximum < damage)
+ return
+ damage = CLAMP(damage + d, 0, maximum)
+ var/mess = check_damage_thresholds(owner)
+ prev_damage = damage
+ if(mess && owner)
+ to_chat(owner, mess)
- damage += damage_mod
if ((damage / maxHealth) > 1)
- to_chat(M, "Your tongue is singed beyond recognition, and disintegrates! ")
+ to_chat(owner, "Your tongue is singed beyond recognition, and disintegrates! ")
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Tongues lost to Fermi")
qdel(src)
else if ((damage / maxHealth) > 0.85)
- to_chat(M, "Your tongue feels like it's about to fall out!. ")
+ to_chat(owner, "Your tongue feels like it's about to fall out!. ")
else if ((damage / maxHealth) > 0.5)
- to_chat(M, "Your tongue is really starting to hurt. ")
+ to_chat(owner, "Your tongue is really starting to hurt. ")
/obj/item/organ/tongue/Insert(mob/living/carbon/M, special = 0)
@@ -168,7 +176,7 @@
icon_state = "tonguexeno"
say_mod = "hisses"
taste_sensitivity = 10 // LIZARDS ARE ALIENS CONFIRMED
- maxHealth = "alien" //Their blood is acid, so, no, though a tongueless xeno might be funny
+ maxHealth = 500 //They've a little mouth for a tongue, so it's pretty rhobust
modifies_speech = TRUE // not really, they just hiss
var/static/list/languages_possible_alien = typecacheof(list(
/datum/language/xenocommon,
@@ -189,9 +197,10 @@
desc = "Apparently skeletons alter the sounds they produce through oscillation of their teeth, hence their characteristic rattling."
icon_state = "tonguebone"
say_mod = "rattles"
+ organ_flags = ORGAN_NO_SPOIL
attack_verb = list("bitten", "chattered", "chomped", "enamelled", "boned")
taste_sensitivity = 101 // skeletons cannot taste anything
- maxHealth = "bone" //Take brute damage instead
+ maxHealth = 75 //Take brute damage instead
modifies_speech = TRUE
var/chattering = FALSE
var/phomeme_type = "sans"
@@ -201,6 +210,16 @@
. = ..()
phomeme_type = pick(phomeme_types)
+/obj/item/organ/tongue/bone/applyOrganDamage(var/d, var/maximum = maxHealth)
+ if(d < 0)
+ return
+ if(!owner)
+ return
+ var/target = owner.get_bodypart(BODY_ZONE_HEAD)
+ owner.apply_damage(d, BURN, target)
+ to_chat(owner, "You feel your skull burning! Oof, your bones! ")
+ return
+
/obj/item/organ/tongue/bone/handle_speech(datum/source, list/speech_args)
if (chattering)
chatter(speech_args[SPEECH_MESSAGE], phomeme_type, source)
@@ -214,7 +233,6 @@
name = "plasma bone \"tongue\""
desc = "Like animated skeletons, Plasmamen vibrate their teeth in order to produce speech."
icon_state = "tongueplasma"
- maxHealth = "alien"
modifies_speech = FALSE
/obj/item/organ/tongue/robot
@@ -262,6 +280,7 @@
icon_state = "tonguecybernetic"
taste_sensitivity = 10
maxHealth = 60 //It's robotic!
+ organ_flags = ORGAN_SYNTHETIC
/obj/item/organ/tongue/cybernetic/handle_speech(datum/source, list/speech_args)
speech_args[SPEECH_SPANS] |= SPAN_ROBOT
@@ -271,3 +290,4 @@
say_mod = "beeps"
desc = "A voice synthesizer used by IPCs to smoothly interface with organic lifeforms."
electronics_magic = FALSE
+ organ_flags = ORGAN_SYNTHETIC
diff --git a/code/modules/surgery/organs/vocal_cords.dm b/code/modules/surgery/organs/vocal_cords.dm
index 8103224306..a555010567 100644
--- a/code/modules/surgery/organs/vocal_cords.dm
+++ b/code/modules/surgery/organs/vocal_cords.dm
@@ -26,12 +26,14 @@
zone = BODY_ZONE_HEAD
slot = ORGAN_SLOT_ADAMANTINE_RESONATOR
icon_state = "adamantine_resonator"
+ decay_factor = 0
/obj/item/organ/vocal_cords/adamantine
name = "adamantine vocal cords"
desc = "When adamantine resonates, it causes all nearby pieces of adamantine to resonate as well. Adamantine golems use this to broadcast messages to nearby golems."
actions_types = list(/datum/action/item_action/organ_action/use/adamantine_vocal_cords)
icon_state = "adamantine_cords"
+ decay_factor = 0
/datum/action/item_action/organ_action/use/adamantine_vocal_cords/Trigger()
if(!IsAvailable())
@@ -62,6 +64,7 @@
var/cooldown_mod = 1
var/base_multiplier = 1
spans = list("colossus","yell")
+ decay_factor = 0
/datum/action/item_action/organ_action/colossus
name = "Voice of God"
@@ -623,10 +626,6 @@
/datum/action/item_action/organ_action/velvet
name = "Velvet chords"
var/obj/item/organ/vocal_cords/velvet/cords = null
- //icon_icon = 'icons/mob/screen_alert.dmi'
- //button_icon_state = "velvet_chords"
- //icon = 'icons/mob/screen_alert.dmi'
- //icon_state = "in_love"
/datum/action/item_action/organ_action/velvet/New()
..()
@@ -918,7 +917,7 @@
speaktrigger += "[(H.client?.prefs.lewdchem?"You are my whole world and all of my being belongs to you, ":"I cannot think of anything else but aiding your cause, ")] "//Redflags!!
//mood
- GET_COMPONENT_FROM(mood, /datum/component/mood, H)
+ var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
switch(mood.sanity)
if(SANITY_GREAT to INFINITY)
speaktrigger += "I'm beyond elated!! " //did you mean byond elated? hohoho
@@ -991,7 +990,7 @@
if (HAS_TRAIT(H, TRAIT_DEAF))//How the heck you managed to get here I have no idea, but just in case!
speaktrigger += "I can barely hear you! "
//And the brain damage. And the brain damage. And the brain damage. And the brain damage. And the brain damage.
- switch(H.getBrainLoss())
+ switch(H.getOrganLoss(ORGAN_SLOT_BRAIN))
if(20 to 40)
speaktrigger += "I have a mild head ache, "
if(40 to 80)
diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm
index 39077ae235..fe22ffaede 100644
--- a/code/modules/surgery/plastic_surgery.dm
+++ b/code/modules/surgery/plastic_surgery.dm
@@ -5,7 +5,7 @@
//reshape_face
/datum/surgery_step/reshape_face
name = "reshape face"
- implements = list(/obj/item/scalpel = 100, /obj/item/kitchen/knife = 50, TOOL_WIRECUTTER = 35)
+ implements = list(TOOL_SCALPEL = 100, /obj/item/kitchen/knife = 50, TOOL_WIRECUTTER = 35)
time = 64
/datum/surgery_step/reshape_face/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
@@ -48,4 +48,4 @@
"[user] screws up, disfiguring [target]'s appearance!",
"[user] finishes the operation on [target]'s face.")
ADD_TRAIT(target, TRAIT_DISFIGURED, TRAIT_GENERIC)
- return FALSE
+ return FALSE
diff --git a/code/modules/surgery/prosthetic_replacement.dm b/code/modules/surgery/prosthetic_replacement.dm
index fdceb1fb1f..8efa40a70a 100644
--- a/code/modules/surgery/prosthetic_replacement.dm
+++ b/code/modules/surgery/prosthetic_replacement.dm
@@ -1,7 +1,7 @@
/datum/surgery/prosthetic_replacement
name = "Prosthetic replacement"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/add_prosthetic)
- species = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
+ target_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
possible_locs = list(BODY_ZONE_R_ARM, BODY_ZONE_L_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG, BODY_ZONE_HEAD)
requires_bodypart = FALSE //need a missing limb
requires_bodypart_type = 0
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index b013e7f252..a920ea765a 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -1,155 +1,172 @@
-/datum/surgery
- var/name = "surgery"
- var/desc = "surgery description"
- var/status = 1
- var/list/steps = list() //Steps in a surgery
- var/step_in_progress = 0 //Actively performing a Surgery
- var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery
- var/list/species = list(/mob/living/carbon/human) //Acceptable Species
- var/location = BODY_ZONE_CHEST //Surgery location
- var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on incorrect limbs. 0 for any limb type
- var/list/possible_locs = list() //Multiple locations
- var/ignore_clothes = 0 //This surgery ignores clothes
- var/mob/living/carbon/target //Operation target mob
- var/obj/item/bodypart/operated_bodypart //Operable body part
- var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing.
- var/success_multiplier = 0 //Step success propability multiplier
- var/requires_real_bodypart = 0 //Some surgeries don't work on limbs that don't really exist
-
-/datum/surgery/New(surgery_target, surgery_location, surgery_bodypart)
- ..()
- if(surgery_target)
- target = surgery_target
- target.surgeries += src
- if(surgery_location)
- location = surgery_location
- if(surgery_bodypart)
- operated_bodypart = surgery_bodypart
-
-/datum/surgery/Destroy()
- if(target)
- target.surgeries -= src
- target = null
- operated_bodypart = null
- return ..()
-
-
-/datum/surgery/proc/can_start(mob/user, mob/living/carbon/target)
- // if 0 surgery wont show up in list
- // put special restrictions here
- return 1
-
-/datum/surgery/proc/next_step(mob/user, intent)
- if(step_in_progress)
- return 1
-
- var/try_to_fail = FALSE
- if(intent == INTENT_DISARM)
- try_to_fail = TRUE
-
- var/datum/surgery_step/S = get_surgery_step()
- if(S)
- var/obj/item/tool = user.get_active_held_item()
- if(S.try_op(user, target, user.zone_selected, tool, src, try_to_fail))
- return TRUE
- if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
- return TRUE
- if(tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it
- to_chat(user, "This step requires a different tool! ")
- return TRUE
-
-/datum/surgery/proc/get_surgery_step()
- var/step_type = steps[status]
- return new step_type
-
-/datum/surgery/proc/get_surgery_next_step()
- if(status < steps.len)
- var/step_type = steps[status + 1]
- return new step_type
- else
- return null
-
-/datum/surgery/proc/complete()
- SSblackbox.record_feedback("tally", "surgeries_completed", 1, type)
- qdel(src)
-
-/datum/surgery/proc/get_propability_multiplier()
- var/propability = 0.5
- var/turf/T = get_turf(target)
-
- if(locate(/obj/structure/table/optable, T))
- propability = 1
- else if(locate(/obj/structure/table, T))
- propability = 0.8
- else if(locate(/obj/structure/bed, T))
- propability = 0.7
-
- return propability + success_multiplier
-
-/datum/surgery/advanced
- name = "advanced surgery"
-
-/datum/surgery/advanced/can_start(mob/user, mob/living/carbon/target)
- if(!..())
- return FALSE
- //Abductor scientists need no instructions
- if(isabductor(user))
- var/mob/living/carbon/human/H = user
- var/datum/species/abductor/S = H.dna.species
- if(S.scientist)
- return TRUE
-
- if(iscyborg(user))
- var/mob/living/silicon/robot/R = user
- var/obj/item/surgical_processor/SP = locate() in R.module.modules
- if(!SP)
- return FALSE
- if(type in SP.advanced_surgeries)
- return TRUE
-
- var/turf/T = get_turf(target)
- var/obj/structure/table/optable/table = locate(/obj/structure/table/optable, T)
- if(!table || !table.computer)
- return FALSE
- if(table.computer.stat & (NOPOWER|BROKEN))
- return FALSE
- if(type in table.computer.advanced_surgeries)
- return TRUE
-
-/obj/item/disk/surgery
- name = "Surgery Procedure Disk"
- desc = "A disk that contains advanced surgery procedures, must be loaded into an Operating Console."
- icon_state = "datadisk1"
- materials = list(MAT_METAL=300, MAT_GLASS=100)
- var/list/surgeries
-
-/obj/item/disk/surgery/debug
- name = "Debug Surgery Disk"
- desc = "A disk that contains all existing surgery procedures."
- icon_state = "datadisk1"
- materials = list(MAT_METAL=300, MAT_GLASS=100)
-
-/obj/item/disk/surgery/debug/Initialize()
- . = ..()
- surgeries = subtypesof(/datum/surgery/advanced)
-
-//INFO
-//Check /mob/living/carbon/attackby for how surgery progresses, and also /mob/living/carbon/attack_hand.
-//As of Feb 21 2013 they are in code/modules/mob/living/carbon/carbon.dm, lines 459 and 51 respectively.
-//Other important variables are var/list/surgeries (/mob/living) and var/list/internal_organs (/mob/living/carbon)
-// var/list/bodyparts (/mob/living/carbon/human) is the LIMBS of a Mob.
-//Surgical procedures are initiated by attempt_initiate_surgery(), which is called by surgical drapes and bedsheets.
-
-
-//TODO
-//specific steps for some surgeries (fluff text)
-//more interesting failure options
-//randomised complications
-//more surgeries!
-//add a probability modifier for the state of the surgeon- health, twitching, etc. blindness, god forbid.
-//helper for converting a zone_sel.selecting to body part (for damage)
-
-
-//RESOLVED ISSUES //"Todo" jobs that have been completed
-//combine hands/feet into the arms - Hands/feet were removed - RR
-//surgeries (not steps) that can be initiated on any body part (corresponding with damage locations) - Call this one done, see possible_locs var - c0
+/datum/surgery
+ var/name = "surgery"
+ var/desc = "surgery description"
+ var/status = 1
+ var/list/steps = list() //Steps in a surgery
+ var/step_in_progress = 0 //Actively performing a Surgery
+ var/can_cancel = 1 //Can cancel this surgery after step 1 with cautery
+ var/list/target_mobtypes = list(/mob/living/carbon/human) //Acceptable Species
+ var/location = BODY_ZONE_CHEST //Surgery location
+ var/requires_bodypart_type = BODYPART_ORGANIC //Prevents you from performing an operation on incorrect limbs. 0 for any limb type
+ var/list/possible_locs = list() //Multiple locations
+ var/ignore_clothes = 0 //This surgery ignores clothes
+ var/mob/living/carbon/target //Operation target mob
+ var/obj/item/bodypart/operated_bodypart //Operable body part
+ var/requires_bodypart = TRUE //Surgery available only when a bodypart is present, or only when it is missing.
+ var/success_multiplier = 0 //Step success propability multiplier
+ var/requires_real_bodypart = 0 //Some surgeries don't work on limbs that don't really exist
+ var/lying_required = TRUE //Does the vicitm needs to be lying down.
+ var/requires_tech = FALSE
+ var/replaced_by
+
+/datum/surgery/New(surgery_target, surgery_location, surgery_bodypart)
+ ..()
+ if(surgery_target)
+ target = surgery_target
+ target.surgeries += src
+ if(surgery_location)
+ location = surgery_location
+ if(surgery_bodypart)
+ operated_bodypart = surgery_bodypart
+
+/datum/surgery/Destroy()
+ if(target)
+ target.surgeries -= src
+ target = null
+ operated_bodypart = null
+ return ..()
+
+
+/datum/surgery/proc/can_start(mob/user, mob/living/patient) //FALSE to not show in list
+ . = TRUE
+ if(replaced_by == /datum/surgery)
+ return FALSE
+
+ if(HAS_TRAIT(user, TRAIT_SURGEON) || HAS_TRAIT(user.mind, TRAIT_SURGEON))
+ if(replaced_by)
+ return FALSE
+ else
+ return TRUE
+
+ if(!requires_tech && !replaced_by)
+ return TRUE
+ // True surgeons (like abductor scientists) need no instructions
+
+ if(requires_tech)
+ . = FALSE
+
+ if(iscyborg(user))
+ var/mob/living/silicon/robot/R = user
+ var/obj/item/surgical_processor/SP = locate() in R.module.modules
+ if(SP)
+ if (replaced_by in SP.advanced_surgeries)
+ return .
+ if(type in SP.advanced_surgeries)
+ return TRUE
+
+
+ var/turf/T = get_turf(patient)
+ var/obj/structure/table/optable/table = locate(/obj/structure/table/optable, T)
+ if(table)
+ if(!table.computer)
+ return .
+ if(table.computer.stat & (NOPOWER|BROKEN))
+ return .
+ if(replaced_by in table.computer.advanced_surgeries)
+ return FALSE
+ if(type in table.computer.advanced_surgeries)
+ return TRUE
+
+/datum/surgery/proc/next_step(mob/user, intent)
+ if(step_in_progress)
+ return 1
+
+ var/try_to_fail = FALSE
+ if(intent == INTENT_DISARM)
+ try_to_fail = TRUE
+
+ var/datum/surgery_step/S = get_surgery_step()
+ if(S)
+ var/obj/item/tool = user.get_active_held_item()
+ if(S.try_op(user, target, user.zone_selected, tool, src, try_to_fail))
+ return TRUE
+ if(iscyborg(user) && user.a_intent != INTENT_HARM) //to save asimov borgs a LOT of heartache
+ return TRUE
+ if(tool && tool.item_flags & SURGICAL_TOOL) //Just because you used the wrong tool it doesn't mean you meant to whack the patient with it
+ to_chat(user, "This step requires a different tool! ")
+ return TRUE
+
+/datum/surgery/proc/get_surgery_step()
+ var/step_type = steps[status]
+ return new step_type
+
+/datum/surgery/proc/get_surgery_next_step()
+ if(status < steps.len)
+ var/step_type = steps[status + 1]
+ return new step_type
+ else
+ return null
+
+/datum/surgery/proc/complete()
+ SSblackbox.record_feedback("tally", "surgeries_completed", 1, type)
+ qdel(src)
+
+/datum/surgery/proc/get_propability_multiplier()
+ var/propability = 0.5
+ var/turf/T = get_turf(target)
+
+ if(locate(/obj/structure/table/optable, T))
+ propability = 1
+ else if(locate(/obj/structure/table, T))
+ propability = 0.8
+ else if(locate(/obj/structure/bed, T))
+ propability = 0.7
+
+ return propability + success_multiplier
+
+/datum/surgery/advanced
+ name = "advanced surgery"
+ requires_tech = TRUE
+
+/obj/item/disk/surgery
+ name = "Surgery Procedure Disk"
+ desc = "A disk that contains advanced surgery procedures, must be loaded into an Operating Console."
+ icon_state = "datadisk1"
+ materials = list(MAT_METAL=300, MAT_GLASS=100)
+ var/list/surgeries
+
+/obj/item/disk/surgery/debug
+ name = "Debug Surgery Disk"
+ desc = "A disk that contains all existing surgery procedures."
+ icon_state = "datadisk1"
+ materials = list(MAT_METAL=300, MAT_GLASS=100)
+
+/obj/item/disk/surgery/debug/Initialize()
+ . = ..()
+ surgeries = list()
+ var/list/req_tech_surgeries = subtypesof(/datum/surgery)
+ for(var/i in req_tech_surgeries)
+ var/datum/surgery/beep = i
+ if(initial(beep.requires_tech))
+ surgeries += beep
+
+//INFO
+//Check /mob/living/carbon/attackby for how surgery progresses, and also /mob/living/carbon/attack_hand.
+//As of Feb 21 2013 they are in code/modules/mob/living/carbon/carbon.dm, lines 459 and 51 respectively.
+//Other important variables are var/list/surgeries (/mob/living) and var/list/internal_organs (/mob/living/carbon)
+// var/list/bodyparts (/mob/living/carbon/human) is the LIMBS of a Mob.
+//Surgical procedures are initiated by attempt_initiate_surgery(), which is called by surgical drapes and bedsheets.
+
+
+//TODO
+//specific steps for some surgeries (fluff text)
+//more interesting failure options
+//randomised complications
+//more surgeries!
+//add a probability modifier for the state of the surgeon- health, twitching, etc. blindness, god forbid.
+//helper for converting a zone_sel.selecting to body part (for damage)
+
+
+//RESOLVED ISSUES //"Todo" jobs that have been completed
+//combine hands/feet into the arms - Hands/feet were removed - RR
+//surgeries (not steps) that can be initiated on any body part (corresponding with damage locations) - Call this one done, see possible_locs var - c0
\ No newline at end of file
diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm
index c5a944fbb2..71f813a5b5 100644
--- a/code/modules/surgery/surgery_step.dm
+++ b/code/modules/surgery/surgery_step.dm
@@ -8,7 +8,9 @@
var/repeatable = FALSE //can this step be repeated? Make shure it isn't last step, or it used in surgery with `can_cancel = 1`. Or surgion will be stuck in the loop
var/list/chems_needed = list() //list of chems needed to complete the step. Even on success, the step will have no effect if there aren't the chems required in the mob.
var/require_all_chems = TRUE //any on the list or all on the list?
-/datum/surgery_step/proc/try_op(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
+ var/silicons_obey_prob = FALSE
+
+/datum/surgery_step/proc/try_op(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
var/success = FALSE
if(accept_hand)
if(!tool)
@@ -46,7 +48,8 @@
else
surgery.status--
return FALSE
-/datum/surgery_step/proc/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
+
+/datum/surgery_step/proc/initiate(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE)
surgery.step_in_progress = TRUE
var/speed_mod = 1
var/advance = FALSE
@@ -60,7 +63,8 @@
if(implement_type) //this means it isn't a require hand or any item step.
prob_chance = implements[implement_type]
prob_chance *= surgery.get_propability_multiplier()
- if((prob(prob_chance) || iscyborg(user)) && chem_check(target) && !try_to_fail)
+
+ if((prob(prob_chance) || (iscyborg(user) && !silicons_obey_prob)) && chem_check(target) && !try_to_fail)
if(success(user, target, target_zone, tool, surgery))
advance = TRUE
else
@@ -73,19 +77,18 @@
surgery.step_in_progress = FALSE
return advance
-
-/datum/surgery_step/proc/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+/datum/surgery_step/proc/preop(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "You begin to perform surgery on [target]... ",
"[user] begins to perform surgery on [target].",
"[user] begins to perform surgery on [target].")
-/datum/surgery_step/proc/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+/datum/surgery_step/proc/success(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "You succeed. ",
"[user] succeeds!",
"[user] finishes.")
return TRUE
-/datum/surgery_step/proc/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
+/datum/surgery_step/proc/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery)
display_results(user, target, "You screw up! ",
"[user] screws up! ",
"[user] finishes.", TRUE) //By default the patient will notice if the wrong thing has been cut
@@ -93,7 +96,8 @@
/datum/surgery_step/proc/tool_check(mob/user, obj/item/tool)
return TRUE
-/datum/surgery_step/proc/chem_check(mob/living/carbon/target)
+
+/datum/surgery_step/proc/chem_check(mob/living/target)
if(!LAZYLEN(chems_needed))
return TRUE
if(require_all_chems)
diff --git a/code/modules/surgery/tools.dm b/code/modules/surgery/tools.dm
index db7445e0b0..001ef8d0e6 100644
--- a/code/modules/surgery/tools.dm
+++ b/code/modules/surgery/tools.dm
@@ -7,16 +7,30 @@
item_flags = SURGICAL_TOOL
flags_1 = CONDUCT_1
w_class = WEIGHT_CLASS_TINY
+ tool_behaviour = TOOL_RETRACTOR
+ toolspeed = 1
-/obj/item/retractor/adv
- name = "Advanced Retractor"
- desc = "A high-class, premium retractor, featuring precision crafted, silver-plated hook-ends and an electrum handle."
+/obj/item/retractor/advanced
+ name = "mechanical pinches"
+ desc = "An agglomerate of rods and gears."
icon = 'icons/obj/surgery.dmi'
- icon_state = "retractor"
- materials = list(MAT_METAL=6000, MAT_GLASS=3000)
- flags_1 = CONDUCT_1
- w_class = WEIGHT_CLASS_TINY
- toolspeed = 0.65
+ icon_state = "retractor_a"
+ toolspeed = 0.7
+
+/obj/item/retractor/advanced/attack_self(mob/user)
+ playsound(get_turf(user), 'sound/items/change_drill.ogg', 50, TRUE)
+ if(tool_behaviour == TOOL_RETRACTOR)
+ tool_behaviour = TOOL_HEMOSTAT
+ to_chat(user, "You configure the gears of [src], they are now in hemostat mode. ")
+ icon_state = "hemostat_a"
+ else
+ tool_behaviour = TOOL_RETRACTOR
+ to_chat(user, "You configure the gears of [src], they are now in retractor mode. ")
+ icon_state = "retractor_a"
+
+/obj/item/retractor/advanced/examine(mob/living/user)
+ . = ..()
+ to_chat(user, "You focus the lenses of [src], it is now in mending mode. ")
+ icon_state = "cautery_a"
+ else
+ tool_behaviour = TOOL_DRILL
+ to_chat(user, "You dilate the lenses of [src], it is now in drilling mode. ")
+ icon_state = "surgicaldrill_a"
+
+/obj/item/surgicaldrill/advanced/examine(mob/living/user)
+ . = ..()
+ to_chat(user, "")
/obj/item/surgicaldrill/augment
name = "surgical drill"
@@ -159,30 +167,47 @@
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
sharpness = IS_SHARP_ACCURATE
+ tool_behaviour = TOOL_SCALPEL
+ toolspeed = 1
/obj/item/scalpel/Initialize()
. = ..()
AddComponent(/datum/component/butchering, 80 * toolspeed, 100, 0)
-/obj/item/scalpel/adv
- name = "Precision Scalpel"
- desc = "A perfectly balanced electrum scalpel with a silicon-coated edge to eliminate wear and tear."
+/obj/item/scalpel/advanced
+ name = "laser scalpel"
+ desc = "An advanced scalpel which uses laser technology to cut."
icon = 'icons/obj/surgery.dmi'
- icon_state = "scalpel"
- lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
- flags_1 = CONDUCT_1
- force = 8
- w_class = WEIGHT_CLASS_TINY
- throwforce = 7
- throw_speed = 3
- throw_range = 6
- materials = list(MAT_METAL=4000, MAT_GLASS=1000)
- attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
- toolspeed = 0.65
- hitsound = 'sound/weapons/bladeslice.ogg'
+ icon_state = "scalpel_a"
+ hitsound = 'sound/weapons/blade1.ogg'
+ force = 16
+ toolspeed = 0.7
+ light_color = LIGHT_COLOR_GREEN
sharpness = IS_SHARP_ACCURATE
+/obj/item/scalpel/advanced/Initialize()
+ . = ..()
+ set_light(1)
+
+/obj/item/scalpel/advanced/attack_self(mob/user)
+ playsound(get_turf(user), 'sound/machines/click.ogg', 50, TRUE)
+ if(tool_behaviour == TOOL_SCALPEL)
+ tool_behaviour = TOOL_SAW
+ to_chat(user, "You increase the power of [src], now it can cut bones. ")
+ set_light(2)
+ force += 1 //we don't want to ruin sharpened stuff
+ icon_state = "saw_a"
+ else
+ tool_behaviour = TOOL_SCALPEL
+ to_chat(user, "You lower the power of [src], it can no longer cut bones. ")
+ set_light(1)
+ force -= 1
+ icon_state = "scalpel_a"
+
+/obj/item/scalpel/advanced/examine(mob/living/user)
+ . = ..()
+ to_chat(user, "")
+
/obj/item/scalpel/augment
name = "scalpel"
desc = "Ultra-sharp blade attached directly to your bone for extra-accuracy."
@@ -224,30 +249,13 @@
materials = list(MAT_METAL=10000, MAT_GLASS=6000)
attack_verb = list("attacked", "slashed", "sawed", "cut")
sharpness = IS_SHARP
+ tool_behaviour = TOOL_SAW
+ toolspeed = 1
/obj/item/circular_saw/Initialize()
. = ..()
AddComponent(/datum/component/butchering, 40 * toolspeed, 100, 5, 'sound/weapons/circsawhit.ogg') //saws are very accurate and fast at butchering
-/obj/item/circular_saw/adv
- name = "Diamond-Grit Circular Saw"
- desc = "For those Assistants with REALLY thick skulls."
- icon = 'icons/obj/surgery.dmi'
- icon_state = "saw"
- lefthand_file = 'icons/mob/inhands/equipment/medical_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/equipment/medical_righthand.dmi'
- hitsound = 'sound/weapons/circsawhit.ogg'
- throwhitsound = 'sound/weapons/pierce.ogg'
- flags_1 = CONDUCT_1
- force = 13
- w_class = WEIGHT_CLASS_NORMAL
- throwforce = 6
- throw_speed = 1
- throw_range = 3
- materials = list(MAT_METAL=10000, MAT_GLASS=6000)
- attack_verb = list("attacked", "slashed", "sawed", "cut")
- toolspeed = 0.65
- sharpness = IS_SHARP
/obj/item/circular_saw/augment
name = "circular saw"
@@ -332,7 +340,7 @@
icon_state = "spectrometer"
item_flags = NOBLUDGEON
var/list/advanced_surgeries = list()
-
+
/obj/item/surgical_processor/afterattack(obj/item/O, mob/user, proximity)
. = ..()
if(!proximity)
diff --git a/code/modules/tooltip/tooltip.html b/code/modules/tooltip/tooltip.html
index 3e2f26a09f..3cab68da6a 100644
--- a/code/modules/tooltip/tooltip.html
+++ b/code/modules/tooltip/tooltip.html
@@ -122,8 +122,8 @@
//Get the real icon size according to the client view
var mapWidth = map['view-size'].x,
mapHeight = map['view-size'].y,
- tilesShown = tooltip.client_view_w
- realIconSize = mapWidth / tilesShown,
+ tilesShown = tooltip.client_view_h
+ realIconSize = mapHeight / tilesShown,
resizeRatio = realIconSize / tooltip.tileSize,
//Calculate letterboxing offsets
leftOffset = (map.size.x - mapWidth) / 2,
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index 8da5d7c113..642052026b 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -2,6 +2,7 @@
//Keep this sorted alphabetically
#ifdef UNIT_TESTS
+#include "component_tests.dm"
#include "reagent_id_typos.dm"
#include "reagent_recipe_collisions.dm"
#include "spawn_humans.dm"
diff --git a/code/modules/unit_tests/component_tests.dm b/code/modules/unit_tests/component_tests.dm
new file mode 100644
index 0000000000..409d7f4322
--- /dev/null
+++ b/code/modules/unit_tests/component_tests.dm
@@ -0,0 +1,12 @@
+/datum/unit_test/component_duping/Run()
+ var/list/bad_dms = list()
+ var/list/bad_dts = list()
+ for(var/t in typesof(/datum/component))
+ var/datum/component/comp = t
+ if(!isnum(initial(comp.dupe_mode)))
+ bad_dms += t
+ var/dupe_type = initial(comp.dupe_type)
+ if(dupe_type && !ispath(dupe_type))
+ bad_dts += t
+ if(length(bad_dms) || length(bad_dts))
+ Fail("Components with invalid dupe modes: ([bad_dms.Join(",")]) ||| Components with invalid dupe types: ([bad_dts.Join(",")])")
\ No newline at end of file
diff --git a/code/modules/uplink/uplink_devices.dm b/code/modules/uplink/uplink_devices.dm
index b008682745..5c47a2d342 100644
--- a/code/modules/uplink/uplink_devices.dm
+++ b/code/modules/uplink/uplink_devices.dm
@@ -25,18 +25,18 @@
/obj/item/uplink/nuclear/Initialize()
. = ..()
- GET_COMPONENT(hidden_uplink, /datum/component/uplink)
+ var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
/obj/item/uplink/nuclear_restricted/Initialize()
. = ..()
- GET_COMPONENT(hidden_uplink, /datum/component/uplink)
+ var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.allow_restricted = FALSE
hidden_uplink.set_gamemode(/datum/game_mode/nuclear)
/obj/item/uplink/clownop/Initialize()
. = ..()
- GET_COMPONENT(hidden_uplink, /datum/component/uplink)
+ var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.set_gamemode(/datum/game_mode/nuclear/clown_ops)
/obj/item/uplink/old
@@ -45,7 +45,7 @@
/obj/item/uplink/old/Initialize(mapload, owner, tc_amount = 10)
. = ..()
- GET_COMPONENT(hidden_uplink, /datum/component/uplink)
+ var/datum/component/uplink/hidden_uplink = GetComponent(/datum/component/uplink)
hidden_uplink.name = "dusty radio"
// Multitool uplink
diff --git a/code/modules/uplink/uplink_items.dm b/code/modules/uplink/uplink_items.dm
index 09e955d2f9..280740688e 100644
--- a/code/modules/uplink/uplink_items.dm
+++ b/code/modules/uplink/uplink_items.dm
@@ -75,6 +75,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
var/player_minimum //The minimum crew size needed for this item to be added to uplinks.
var/purchase_log_vis = TRUE // Visible in the purchase log?
var/restricted = FALSE // Adds restrictions for VR/Events
+ var/illegal_tech = TRUE // Can this item be deconstructed to unlock certain techweb research nodes?
/datum/uplink_item/New()
. = ..()
@@ -769,6 +770,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
item = /obj/item/ammo_box/a357
cost = 4
exclude_modes = list(/datum/game_mode/nuclear/clown_ops)
+ illegal_tech = FALSE
/datum/uplink_item/ammo/a40mm
name = "40mm Grenade"
@@ -898,6 +900,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
item = /obj/item/ammo_box/foambox/riot
cost = 2
surplus = 0
+ illegal_tech = FALSE
/datum/uplink_item/ammo/bioterror
name = "Box of Bioterror Syringes"
@@ -1487,9 +1490,10 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
/datum/uplink_item/device_tools/singularity_beacon
name = "Power Beacon"
desc = "When screwed to wiring attached to an electric grid and activated, this large device pulls any \
- active gravitational singularities or tesla balls towards it. This will not work when the engine is still \
- in containment. Because of its size, it cannot be carried. Ordering this \
- sends you a small beacon that will teleport the larger beacon to your location upon activation."
+ active gravitational singularities or tesla balls towards it (provided they are not safely \
+ contained), as well as increasing the odds of incoming meteor waves. \
+ Because of its size, it cannot be carried. Ordering this sends you a small beacon \
+ that will teleport the larger beacon to your location upon activation."
item = /obj/item/sbeacondrop
cost = 14
@@ -1707,12 +1711,20 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
cost = 14 //High cost because of the potential for extreme damage in the hands of a skilled gas masked scientist.
restricted_roles = list("Research Director", "Scientist")
+/datum/uplink_item/role_restricted/alientech
+ name = "Alien Research Disk"
+ desc = "A technology disk holding a terabyte of highly confidential abductor technology. \
+ Simply insert into research console of choice and import the files from the disk. Because of its foreign nature, it may require multiple uploads to work properly."
+ item = /obj/item/disk/tech_disk/abductor
+ cost = 12
+ restricted_roles = list("Research Director", "Scientist", "Roboticist")
+
/datum/uplink_item/role_restricted/brainwash_disk
name = "Brainwashing Surgery Program"
desc = "A disk containing the procedure to perform a brainwashing surgery, allowing you to implant an objective onto a target. \
Insert into an Operating Console to enable the procedure."
item = /obj/item/disk/surgery/brainwashing
- restricted_roles = list("Medical Doctor")
+ restricted_roles = list("Medical Doctor", "Roboticist")
cost = 3
/datum/uplink_item/role_restricted/clown_bomb
@@ -1908,6 +1920,13 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
Radio headset does not include encryption key. No gun included."
item = /obj/item/storage/box/syndie_kit/centcom_costume
+/datum/uplink_item/badass/claymore
+ name = "Claymore"
+ cost = 8
+ player_minimum = 25
+ desc = "A claymore. We don't know why you'd do this."
+ item = /obj/item/claymore
+
/datum/uplink_item/badass/costumes/clown
name = "Clown Costume"
desc = "Nothing is more terrifying than clowns with fully automatic weaponry."
@@ -1926,6 +1945,7 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
item = /obj/item/toy/syndicateballoon
cost = 20
cant_discount = TRUE
+ illegal_tech = FALSE
/datum/uplink_item/badass/syndiecash
name = "Syndicate Briefcase Full of Cash"
@@ -1949,9 +1969,11 @@ datum/uplink_item/stealthy_weapons/taeclowndo_shoes
item = /obj/item/toy/cards/deck/syndicate
cost = 1
surplus = 40
+ illegal_tech = FALSE
/datum/uplink_item/badass/syndiecigs
name = "Syndicate Smokes"
desc = "Strong flavor, dense smoke, infused with omnizine."
item = /obj/item/storage/fancy/cigarettes/cigpack_syndicate
cost = 2
+ illegal_tech = FALSE
diff --git a/code/modules/vehicles/scooter.dm b/code/modules/vehicles/scooter.dm
index 9af5b13a7d..8c21b050aa 100644
--- a/code/modules/vehicles/scooter.dm
+++ b/code/modules/vehicles/scooter.dm
@@ -75,7 +75,7 @@
H.adjustStaminaLoss(40)
var/head_slot = H.get_item_by_slot(SLOT_HEAD)
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
- H.adjustBrainLoss(3)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3)
H.updatehealth()
visible_message("[src] crashes into [A], sending [H] flying! ")
playsound(src, 'sound/effects/bang.ogg', 50, 1)
@@ -201,7 +201,7 @@
H.adjustStaminaLoss(10)
var/head_slot = H.get_item_by_slot(SLOT_HEAD)
if(!head_slot || !(istype(head_slot,/obj/item/clothing/head/helmet) || istype(head_slot,/obj/item/clothing/head/hardhat)))
- H.adjustBrainLoss(1)
+ H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
H.updatehealth()
visible_message("[src] crashes into [A], sending [H] flying! ")
playsound(src, 'sound/effects/bang.ogg', 50, 1)
diff --git a/code/modules/vehicles/secway.dm b/code/modules/vehicles/secway.dm
index 33f0d794c8..114a6373f4 100644
--- a/code/modules/vehicles/secway.dm
+++ b/code/modules/vehicles/secway.dm
@@ -4,9 +4,59 @@
desc = "A brave security cyborg gave its life to help you look like a complete tool."
icon_state = "secway"
key_type = /obj/item/key/security
+ var/chargemax = 150
+ var/chargerate = 0.35
+ var/charge = 150
+ var/chargespeed = 1
+ var/normalspeed = 2
+ var/last_tick = 0
+ var/list/progressbars_by_rider = list()
/obj/vehicle/ridden/secway/Initialize()
. = ..()
var/datum/component/riding/D = LoadComponent(/datum/component/riding)
D.vehicle_move_delay = 1
D.set_riding_offsets(RIDING_OFFSET_ALL, list(TEXT_NORTH = list(0, 4), TEXT_SOUTH = list(0, 4), TEXT_EAST = list(0, 4), TEXT_WEST = list( 0, 4)))
+ START_PROCESSING(SSfastprocess, src)
+
+/obj/vehicle/ridden/secway/process()
+ var/diff = world.time - last_tick
+ var/regen = chargerate * diff
+ charge = CLAMP(charge + regen, 0, chargemax)
+ last_tick = world.time
+
+/obj/vehicle/ridden/secway/relaymove(mob/user, direction)
+ var/new_speed = normalspeed
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ if(H.sprinting && charge)
+ charge--
+ new_speed = chargespeed
+ var/datum/component/riding/D = GetComponent(/datum/component/riding)
+ D.vehicle_move_delay = new_speed
+ for(var/i in progressbars_by_rider)
+ var/datum/progressbar/B = progressbars_by_rider[i]
+ B.update(charge)
+ return ..()
+
+/obj/vehicle/ridden/secway/buckle_mob(mob/living/M, force, check_loc)
+ . = ..(M, force, check_loc)
+ if(.)
+ if(progressbars_by_rider[M])
+ qdel(progressbars_by_rider[M])
+ var/datum/progressbar/D = new(M, chargemax, src)
+ D.update(charge)
+ progressbars_by_rider[M] = D
+
+/obj/vehicle/ridden/secway/unbuckle_mob(mob/living/M, force)
+ . = ..(M, force)
+ if(.)
+ qdel(progressbars_by_rider[M])
+ progressbars_by_rider -= M
+
+/obj/vehicle/ridden/secway/Destroy()
+ for(var/i in progressbars_by_rider)
+ qdel(progressbars_by_rider[i])
+ progressbars_by_rider.Cut()
+ STOP_PROCESSING(SSfastprocess, src)
+ return ..()
diff --git a/code/modules/vending/autodrobe.dm b/code/modules/vending/autodrobe.dm
index c577643df3..3879fc70cb 100644
--- a/code/modules/vending/autodrobe.dm
+++ b/code/modules/vending/autodrobe.dm
@@ -7,107 +7,109 @@
product_slogans = "Dress for success!;Suited and booted!;It's show time!;Why leave style up to fate? Use AutoDrobe!"
vend_reply = "Thank you for using AutoDrobe!"
products = list(/obj/item/clothing/suit/chickensuit = 1,
- /obj/item/clothing/head/chicken = 1,
- /obj/item/clothing/under/gladiator = 1,
- /obj/item/clothing/head/helmet/gladiator = 1,
- /obj/item/clothing/under/gimmick/rank/captain/suit = 1,
- /obj/item/clothing/head/flatcap = 1,
- /obj/item/clothing/suit/toggle/labcoat/mad = 1,
- /obj/item/clothing/shoes/jackboots = 1,
- /obj/item/clothing/under/schoolgirl = 1,
- /obj/item/clothing/under/schoolgirl/red = 1,
- /obj/item/clothing/under/schoolgirl/green = 1,
- /obj/item/clothing/under/schoolgirl/orange = 1,
- /obj/item/clothing/head/kitty = 1,
- /obj/item/clothing/under/skirt/black = 1,
- /obj/item/clothing/head/beret = 1,
- /obj/item/clothing/accessory/waistcoat = 1,
- /obj/item/clothing/under/suit_jacket = 1,
- /obj/item/clothing/head/that = 1,
- /obj/item/clothing/under/kilt = 1,
- /obj/item/clothing/head/beret = 1,
- /obj/item/clothing/accessory/waistcoat = 1,
- /obj/item/clothing/glasses/monocle =1,
- /obj/item/clothing/head/bowler = 1,
- /obj/item/cane = 1,
- /obj/item/clothing/under/sl_suit = 1,
- /obj/item/clothing/mask/fakemoustache = 1,
- /obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,
- /obj/item/clothing/head/plaguedoctorhat = 1,
- /obj/item/clothing/mask/gas/plaguedoctor = 1,
- /obj/item/clothing/suit/toggle/owlwings = 1,
- /obj/item/clothing/under/owl = 1,
- /obj/item/clothing/mask/gas/owl_mask = 1,
- /obj/item/clothing/suit/toggle/owlwings/griffinwings = 1,
- /obj/item/clothing/under/griffin = 1,
- /obj/item/clothing/shoes/griffin = 1,
- /obj/item/clothing/head/griffin = 1,
- /obj/item/clothing/suit/apron = 1,
- /obj/item/clothing/under/waiter = 1,
- /obj/item/clothing/suit/jacket/miljacket = 1,
- /obj/item/clothing/under/pirate = 1,
- /obj/item/clothing/suit/pirate = 1,
- /obj/item/clothing/head/pirate = 1,
- /obj/item/clothing/head/bandana = 1,
- /obj/item/clothing/head/bandana = 1,
- /obj/item/clothing/under/soviet = 1,
- /obj/item/clothing/head/ushanka = 1,
- /obj/item/clothing/suit/imperium_monk = 1,
- /obj/item/clothing/mask/gas/cyborg = 1,
- /obj/item/clothing/suit/chaplain/holidaypriest = 1,
- /obj/item/clothing/head/wizard/marisa/fake = 1,
- /obj/item/clothing/suit/wizrobe/marisa/fake = 1,
- /obj/item/clothing/under/sundress = 1,
- /obj/item/clothing/head/witchwig = 1,
- /obj/item/staff/broom = 1,
- /obj/item/clothing/suit/wizrobe/fake = 1,
- /obj/item/clothing/head/wizard/fake = 1,
- /obj/item/staff = 3,
- /obj/item/clothing/under/rank/mime/skirt = 1,
- /obj/item/clothing/under/gimmick/rank/captain/suit/skirt = 1,
- /obj/item/clothing/mask/gas/sexyclown = 1,
- /obj/item/clothing/under/rank/clown/sexy = 1,
- /obj/item/clothing/mask/gas/sexymime = 1,
- /obj/item/clothing/under/sexymime = 1,
- /obj/item/clothing/mask/rat/bat = 1,
- /obj/item/clothing/mask/rat/bee = 1,
- /obj/item/clothing/mask/rat/bear = 1,
- /obj/item/clothing/mask/rat/raven = 1,
- /obj/item/clothing/mask/rat/jackal = 1,
- /obj/item/clothing/mask/rat/fox = 1,
- /obj/item/clothing/mask/frog = 1,
- /obj/item/clothing/mask/rat/tribal = 1,
- /obj/item/clothing/mask/rat = 1,
- /obj/item/clothing/suit/apron/overalls = 1,
- /obj/item/clothing/head/rabbitears =1,
- /obj/item/clothing/head/sombrero = 1,
- /obj/item/clothing/head/sombrero/green = 1,
- /obj/item/clothing/suit/poncho = 1,
- /obj/item/clothing/suit/poncho/green = 1,
- /obj/item/clothing/suit/poncho/red = 1,
- /obj/item/clothing/under/maid = 1,
- /obj/item/clothing/under/janimaid = 1,
- /obj/item/clothing/glasses/cold=1,
- /obj/item/clothing/glasses/heat=1,
- /obj/item/clothing/suit/whitedress = 1,
- /obj/item/clothing/under/jester = 1,
- /obj/item/clothing/head/jester = 1,
- /obj/item/clothing/under/villain = 1,
- /obj/item/clothing/shoes/singery = 1,
- /obj/item/clothing/under/singery = 1,
- /obj/item/clothing/shoes/singerb = 1,
- /obj/item/clothing/under/singerb = 1,
- /obj/item/clothing/suit/hooded/carp_costume = 1,
- /obj/item/clothing/suit/hooded/ian_costume = 1,
- /obj/item/clothing/suit/hooded/bee_costume = 1,
- /obj/item/clothing/suit/snowman = 1,
- /obj/item/clothing/head/snowman = 1,
- /obj/item/clothing/mask/joy = 1,
- /obj/item/clothing/head/cueball = 1,
- /obj/item/clothing/under/scratch = 1,
- /obj/item/clothing/under/sailor = 1,
- /obj/item/clothing/ears/headphones = 2,
- /obj/item/clothing/head/wig/random = 3)
+ /obj/item/clothing/head/chicken = 1,
+ /obj/item/clothing/under/gladiator = 1,
+ /obj/item/clothing/head/helmet/gladiator = 1,
+ /obj/item/clothing/under/gimmick/rank/captain/suit = 1,
+ /obj/item/clothing/head/flatcap = 1,
+ /obj/item/clothing/suit/toggle/labcoat/mad = 1,
+ /obj/item/clothing/shoes/jackboots = 1,
+ /obj/item/clothing/under/schoolgirl = 1,
+ /obj/item/clothing/under/schoolgirl/red = 1,
+ /obj/item/clothing/under/schoolgirl/green = 1,
+ /obj/item/clothing/under/schoolgirl/orange = 1,
+ /obj/item/clothing/head/kitty = 1,
+ /obj/item/clothing/under/skirt/black = 1,
+ /obj/item/clothing/head/beret = 1,
+ /obj/item/clothing/accessory/waistcoat = 1,
+ /obj/item/clothing/under/suit_jacket = 1,
+ /obj/item/clothing/head/that = 1,
+ /obj/item/clothing/under/kilt = 1,
+ /obj/item/clothing/head/beret = 1,
+ /obj/item/clothing/accessory/waistcoat = 1,
+ /obj/item/clothing/glasses/monocle =1,
+ /obj/item/clothing/head/bowler = 1,
+ /obj/item/cane = 1,
+ /obj/item/clothing/under/sl_suit = 1,
+ /obj/item/clothing/mask/fakemoustache = 1,
+ /obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,
+ /obj/item/clothing/head/plaguedoctorhat = 1,
+ /obj/item/clothing/mask/gas/plaguedoctor = 1,
+ /obj/item/clothing/suit/toggle/owlwings = 1,
+ /obj/item/clothing/under/owl = 1,
+ /obj/item/clothing/mask/gas/owl_mask = 1,
+ /obj/item/clothing/suit/toggle/owlwings/griffinwings = 1,
+ /obj/item/clothing/under/griffin = 1,
+ /obj/item/clothing/shoes/griffin = 1,
+ /obj/item/clothing/head/griffin = 1,
+ /obj/item/clothing/suit/apron = 1,
+ /obj/item/clothing/under/waiter = 1,
+ /obj/item/clothing/suit/jacket/miljacket = 1,
+ /obj/item/clothing/under/pirate = 1,
+ /obj/item/clothing/suit/pirate = 1,
+ /obj/item/clothing/head/pirate = 1,
+ /obj/item/clothing/head/bandana = 1,
+ /obj/item/clothing/head/bandana = 1,
+ /obj/item/clothing/under/soviet = 1,
+ /obj/item/clothing/head/ushanka = 1,
+ /obj/item/clothing/suit/imperium_monk = 1,
+ /obj/item/clothing/mask/gas/cyborg = 1,
+ /obj/item/clothing/suit/chaplain/holidaypriest = 1,
+ /obj/item/clothing/head/wizard/marisa/fake = 1,
+ /obj/item/clothing/suit/wizrobe/marisa/fake = 1,
+ /obj/item/clothing/under/sundress = 1,
+ /obj/item/clothing/head/witchwig = 1,
+ /obj/item/staff/broom = 1,
+ /obj/item/clothing/suit/wizrobe/fake = 1,
+ /obj/item/clothing/head/wizard/fake = 1,
+ /obj/item/staff = 3,
+ /obj/item/clothing/under/rank/mime/skirt = 1,
+ /obj/item/clothing/under/gimmick/rank/captain/suit/skirt = 1,
+ /obj/item/clothing/mask/gas/sexyclown = 1,
+ /obj/item/clothing/under/rank/clown/sexy = 1,
+ /obj/item/clothing/mask/gas/sexymime = 1,
+ /obj/item/clothing/under/sexymime = 1,
+ /obj/item/clothing/mask/rat/bat = 1,
+ /obj/item/clothing/mask/rat/bee = 1,
+ /obj/item/clothing/mask/rat/bear = 1,
+ /obj/item/clothing/mask/rat/raven = 1,
+ /obj/item/clothing/mask/rat/jackal = 1,
+ /obj/item/clothing/mask/rat/fox = 1,
+ /obj/item/clothing/mask/frog = 1,
+ /obj/item/clothing/mask/rat/tribal = 1,
+ /obj/item/clothing/mask/rat = 1,
+ /obj/item/clothing/suit/apron/overalls = 1,
+ /obj/item/clothing/head/rabbitears =1,
+ /obj/item/clothing/head/sombrero = 1,
+ /obj/item/clothing/head/sombrero/green = 1,
+ /obj/item/clothing/suit/poncho = 1,
+ /obj/item/clothing/suit/poncho/green = 1,
+ /obj/item/clothing/suit/poncho/red = 1,
+ /obj/item/clothing/under/maid = 1,
+ /obj/item/clothing/under/janimaid = 1,
+ /obj/item/clothing/glasses/cold=1,
+ /obj/item/clothing/glasses/heat=1,
+ /obj/item/clothing/suit/whitedress = 1,
+ /obj/item/clothing/under/jester = 1,
+ /obj/item/clothing/head/jester = 1,
+ /obj/item/clothing/under/villain = 1,
+ /obj/item/clothing/shoes/singery = 1,
+ /obj/item/clothing/under/singery = 1,
+ /obj/item/clothing/shoes/singerb = 1,
+ /obj/item/clothing/under/singerb = 1,
+ /obj/item/clothing/suit/hooded/carp_costume = 1,
+ /obj/item/clothing/suit/hooded/ian_costume = 1,
+ /obj/item/clothing/suit/hooded/bee_costume = 1,
+ /obj/item/clothing/suit/snowman = 1,
+ /obj/item/clothing/head/snowman = 1,
+ /obj/item/clothing/mask/joy = 1,
+ /obj/item/clothing/head/cueball = 1,
+ /obj/item/clothing/under/scratch = 1,
+ /obj/item/clothing/under/sailor = 1,
+ /obj/item/clothing/ears/headphones = 2,
+ /obj/item/clothing/head/wig/random = 3,
+ /obj/item/clothing/suit/ran = 2,
+ /obj/item/clothing/head/ran = 2)
contraband = list(/obj/item/clothing/suit/judgerobe = 1,
/obj/item/clothing/head/powdered_wig = 1,
/obj/item/gun/magic/wand = 2,
diff --git a/code/modules/vending/magivend.dm b/code/modules/vending/magivend.dm
index b414638be9..30c6ae6161 100644
--- a/code/modules/vending/magivend.dm
+++ b/code/modules/vending/magivend.dm
@@ -4,7 +4,7 @@
icon_state = "MagiVend"
product_slogans = "Sling spells the proper way with MagiVend!;Be your own Houdini! Use MagiVend!"
vend_reply = "Have an enchanted evening!"
- product_ads = "FJKLFJSD;AJKFLBJAKL;1234 LOONIES LOL!;>MFW;Kill them fuckers!;GET DAT FUKKEN DISK;HONK!;EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!"
+ product_ads = "EI NATH;Destroy the station!;Admin conspiracies since forever!;Space-time bending hardware!;Now-magic proofing venders!"
products = list(/obj/item/clothing/head/wizard = 1,
/obj/item/clothing/suit/wizrobe = 1,
/obj/item/clothing/head/wizard/red = 1,
@@ -14,5 +14,5 @@
/obj/item/clothing/shoes/sandal/magic = 1,
/obj/item/staff = 2)
contraband = list(/obj/item/reagent_containers/glass/bottle/wizarditis = 1) //No one can get to the machine to hack it anyways; for the lulz - Microwave
- armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50)
+ armor = list("melee" = 100, "bullet" = 100, "laser" = 100, "energy" = 100, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 50, "magic" = 100)
resistance_flags = FIRE_PROOF
diff --git a/code/modules/vending/wardrobes.dm b/code/modules/vending/wardrobes.dm
index fbc7713f25..e64435accc 100644
--- a/code/modules/vending/wardrobes.dm
+++ b/code/modules/vending/wardrobes.dm
@@ -63,7 +63,7 @@
product_ads = "Guaranteed to protect your feet from industrial accidents!;Afraid of radiation? Then wear yellow!"
vend_reply = "Thank you for using the EngiDrobe!"
products = list(/obj/item/clothing/accessory/pocketprotector = 5,
- /obj/item/storage/backpack/duffelbag/engineering = 2,
+ /obj/item/storage/backpack/duffelbag/engineering = 3,
/obj/item/storage/backpack/industrial = 3,
/obj/item/storage/backpack/satchel/eng = 3,
/obj/item/clothing/suit/hooded/wintercoat/engineering = 3,
@@ -71,7 +71,8 @@
/obj/item/clothing/under/rank/engineer/skirt = 5,
/obj/item/clothing/suit/hazardvest = 5,
/obj/item/clothing/shoes/workboots = 5,
- /obj/item/clothing/head/hardhat = 5)
+ /obj/item/clothing/head/hardhat = 5,
+ /obj/item/clothing/head/hardhat/weldhat = 3)
refill_canister = /obj/item/vending_refill/wardrobe/engi_wardrobe
/obj/item/vending_refill/wardrobe/engi_wardrobe
@@ -87,7 +88,8 @@
/obj/item/storage/backpack/duffelbag/engineering = 3,
/obj/item/storage/backpack/satchel/eng = 3,
/obj/item/storage/backpack/industrial = 3,
- /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos = 5,
+ /obj/item/clothing/head/hardhat/weldhat/dblue = 3,
+ /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos = 3,
/obj/item/clothing/under/rank/atmospheric_technician = 5,
/obj/item/clothing/under/rank/atmospheric_technician/skirt = 5,
/obj/item/clothing/shoes/sneakers/black = 5)
diff --git a/modular_citadel/code/modules/vore/eating/belly_dat_vr.dm b/code/modules/vore/eating/belly_dat_vr.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/eating/belly_dat_vr.dm
rename to code/modules/vore/eating/belly_dat_vr.dm
diff --git a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm b/code/modules/vore/eating/belly_obj.dm
similarity index 78%
rename from modular_citadel/code/modules/vore/eating/belly_obj_vr.dm
rename to code/modules/vore/eating/belly_obj.dm
index 1ad29c1af3..5c2b45dace 100644
--- a/modular_citadel/code/modules/vore/eating/belly_obj_vr.dm
+++ b/code/modules/vore/eating/belly_obj.dm
@@ -38,6 +38,7 @@
var/swallow_time = 10 SECONDS // for mob transfering automation
var/vore_capacity = 1 // simple animal nom capacity
var/is_wet = TRUE // Is this belly inside slimy parts?
+ var/wet_loop = TRUE // Does this belly have a slimy internal loop?
//I don't think we've ever altered these lists. making them static until someone actually overrides them somewhere.
var/tmp/static/list/digest_modes = list(DM_HOLD,DM_DIGEST,DM_HEAL,DM_NOISY,DM_ABSORB,DM_UNABSORB) // Possible digest modes
@@ -138,13 +139,17 @@
"digest_messages_prey",
"examine_messages",
"emote_lists",
- "is_wet"
+ "is_wet",
+ "wet_loop"
)
//ommitted list
// "shrink_grow_size",
-/obj/belly/New(var/newloc)
- . = ..(newloc)
+/obj/belly/Initialize()
+ . = ..()
+ take_ownership(src.loc)
+
+/obj/belly/proc/take_ownership(var/newloc)
//If not, we're probably just in a prefs list or something.
if(isliving(newloc))
owner = loc
@@ -152,13 +157,11 @@
SSbellies.belly_list += src
/obj/belly/Destroy()
- if(owner)
- Remove(owner)
- return ..()
-
-/obj/belly/proc/Remove(mob/living/owner)
- owner.vore_organs -= src
- owner = null
+ SSbellies.belly_list -= src
+ if(owner?.vore_organs)
+ owner.vore_organs -= src
+ owner = null
+ . = ..()
// Called whenever an atom enters this belly
/obj/belly/Entered(var/atom/movable/thing,var/atom/OldLoc)
@@ -169,13 +172,22 @@
to_chat(owner,"[thing] slides into your [lowertext(name)]. ")
//Sound w/ antispam flag setting
- if(is_wet && (world.time > recent_sound))
- var/turf/source = get_turf(owner)
- var/sound/eating = GLOB.vore_sounds[vore_sound]
- for(var/mob/living/M in get_hearers_in_view(3, source))
- if(M.client && M.client.prefs.cit_toggles & EATING_NOISES)
- SEND_SOUND(M, eating)
- recent_sound = (world.time + 20 SECONDS)
+ if(vore_sound && !recent_sound)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
+ LAZYCLEARLIST(hearing_mobs)
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
+ if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
+ continue
+ LAZYADD(hearing_mobs, H)
+ last_hearcheck = world.time
+ for(var/mob/living/H in hearing_mobs)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ var/sound/eating = GLOB.pred_vore_sounds[vore_sound]
+ SEND_SOUND(H,eating)
+ else if(H && H in contents && H.client)
+ var/sound/eating = GLOB.prey_vore_sounds[vore_sound]
+ SEND_SOUND(H,eating)
+ recent_sound = TRUE
//Messages if it's a mob
if(isliving(thing))
@@ -187,7 +199,7 @@
// If that location is another mob, contents are transferred into whichever of its bellies the owning mob is in.
// Returns the number of mobs so released.
/obj/belly/proc/release_all_contents(var/include_absorbed = FALSE, var/silent = FALSE)
- var/atom/destination = drop_location()
+// var/atom/destination = drop_location()
//Don't bother if we don't have contents
if(!contents.len)
return FALSE
@@ -207,22 +219,30 @@
SEND_SIGNAL(L, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
SEND_SIGNAL(OW, COMSIG_ADD_MOOD_EVENT, "emptypred", /datum/mood_event/emptypred)
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "emptyprey", /datum/mood_event/emptyprey)
- AM.forceMove(destination) // Move the belly contents into the same location as belly's owner.
- count++
- for(var/mob/living/M in get_hearers_in_view(2, get_turf(owner)))
- if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES))
- var/sound/releasement = GLOB.release_sounds[release_sound]
- SEND_SOUND(M, releasement)
+ count += release_specific_contents(AM, silent = TRUE)
//Clean up our own business
items_preserved.Cut()
- if(isanimal(owner))
- owner.update_icons()
+ owner.update_icons()
if(!silent)
+ if(release_sound && !recent_sound)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
+ LAZYCLEARLIST(hearing_mobs)
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
+ if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
+ continue
+ LAZYADD(hearing_mobs, H)
+ last_hearcheck = world.time
+ for(var/mob/living/H in hearing_mobs)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ var/sound/releasement = GLOB.pred_release_sounds[release_sound]
+ SEND_SOUND(H,releasement)
+ else if(H && H in contents && H.client)
+ var/sound/releasement = GLOB.prey_release_sounds[release_sound]
+ SEND_SOUND(H,releasement)
+ recent_sound = TRUE
owner.visible_message("[owner] expels everything from their [lowertext(name)]! ")
- items_preserved.Cut()
- owner.update_icons()
return count
@@ -235,16 +255,13 @@
M.forceMove(drop_location()) // Move the belly contents into the same location as belly's owner.
items_preserved -= M
- if(!silent)
- for(var/mob/living/H in get_hearers_in_view(2, get_turf(owner)))
- if(H.client && (H.client.prefs.cit_toggles & EATING_NOISES))
- var/sound/releasement = GLOB.release_sounds[release_sound]
- SEND_SOUND(H, releasement)
+
if(istype(M,/mob/living))
var/mob/living/ML = M
var/mob/living/OW = owner
- ML.stop_sound_channel(CHANNEL_PREYLOOP)
+ if(ML.client)
+ ML.stop_sound_channel(CHANNEL_PREYLOOP) //Stop the internal loop, it'll restart if the isbelly check on next tick anyway
ML.cure_blind("belly_[REF(src)]")
SEND_SIGNAL(OW, COMSIG_CLEAR_MOOD_EVENT, "fedpred", /datum/mood_event/fedpred)
SEND_SIGNAL(ML, COMSIG_CLEAR_MOOD_EVENT, "fedprey", /datum/mood_event/fedprey)
@@ -263,12 +280,27 @@
Pred.reagents.trans_to(Prey, Pred.reagents.total_volume / absorbed_count)
//Clean up our own business
- if(isanimal(owner))
- owner.update_icons()
+ owner.update_icons()
if(!silent)
+ if(release_sound && !recent_sound)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
+ LAZYCLEARLIST(hearing_mobs)
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
+ if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
+ continue
+ LAZYADD(hearing_mobs, H)
+ last_hearcheck = world.time
+ for(var/mob/living/H in hearing_mobs)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ var/sound/releasement = GLOB.pred_release_sounds[release_sound]
+ SEND_SOUND(H,releasement)
+ else if(H && H in contents && H.client)
+ var/sound/releasement = GLOB.prey_release_sounds[release_sound]
+ SEND_SOUND(H,releasement)
+ recent_sound = TRUE
owner.visible_message("[owner] expels [M] from their [lowertext(name)]! ")
- owner.update_icons()
+
return TRUE
// Actually perform the mechanics of devouring the tasty prey.
@@ -312,15 +344,26 @@
/obj/belly/proc/transfer_contents(var/atom/movable/content, var/obj/belly/target, silent = FALSE)
if(!(content in src) || !istype(target))
return
+ content.forceMove(target)
for(var/mob/living/M in contents)
M.cure_blind("belly_[REF(src)]")
- target.nom_mob(content, target.owner)
- if(!silent)
- var/turf/source = get_turf(owner)
- var/sound/eating = GLOB.vore_sounds[vore_sound]
- for(var/mob/living/M in get_hearers_in_view(3, source))
- if(M.client && M.client.prefs.cit_toggles & EATING_NOISES)
- SEND_SOUND(M, eating)
+// target.nom_mob(content, target.owner)
+ if(vore_sound && !recent_sound && !silent)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
+ LAZYCLEARLIST(hearing_mobs)
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
+ if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
+ continue
+ LAZYADD(hearing_mobs, H)
+ last_hearcheck = world.time
+ for(var/mob/living/H in hearing_mobs)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ var/sound/eating = GLOB.pred_vore_sounds[vore_sound]
+ SEND_SOUND(H,eating)
+ else if(H && H in contents && H.client)
+ var/sound/eating = GLOB.prey_vore_sounds[vore_sound]
+ SEND_SOUND(H,eating)
+ recent_sound = TRUE
owner.updateVRPanel()
for(var/mob/living/M in contents)
@@ -424,9 +467,12 @@
if(!M.dropItemToGround(W))
qdel(W)
+ //Incase they have the loop going, let's double check to stop it.
+ M.stop_sound_channel(CHANNEL_PREYLOOP)
+
// Delete the digested mob
qdel(M)
- M.stop_sound_channel(CHANNEL_PREYLOOP)
+
//Update owner
owner.updateVRPanel()
@@ -470,7 +516,7 @@
/obj/belly/drop_location()
//Should be the case 99.99% of the time
if(owner)
- return owner.loc
+ return owner.drop_location()
//Sketchy fallback for safety, put them somewhere safe.
else if(ismob(src))
testing("[src] (\ref[src]) doesn't have an owner, and dropped someone at a latespawn point!")
@@ -525,24 +571,31 @@
struggle_outer_message = "" + struggle_outer_message + " "
struggle_user_message = "" + struggle_user_message + " "
- var/turf/source = get_turf(owner)
- var/sound/struggle_snuggle = sound(get_sfx("struggle_sound"))
+ var/sound/pred_struggle_snuggle = sound(get_sfx("struggle_sound"))
+ var/sound/prey_struggle_snuggle = sound(get_sfx("prey_struggle"))
var/sound/struggle_rustle = sound(get_sfx("rustle"))
+ LAZYCLEARLIST(hearing_mobs)
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
+ if(!H.client || !(H.client.prefs.cit_toggles & EATING_NOISES))
+ continue
+ LAZYADD(hearing_mobs, H)
+
if(is_wet)
- for(var/mob/living/M in get_hearers_in_view(3, source))
- if(M.client && M.client.prefs.cit_toggles & EATING_NOISES)
- SEND_SOUND(M, struggle_snuggle)
+ for(var/mob/living/H in hearing_mobs)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_struggle_snuggle)
+ else if(H && H in contents && H.client)
+ SEND_SOUND(H,prey_struggle_snuggle)
else
- for(var/mob/living/M in get_hearers_in_view(3, source))
- if(M.client && M.client.prefs.cit_toggles & EATING_NOISES)
- SEND_SOUND(M, struggle_rustle)
+ for(var/mob/living/H in hearing_mobs)
+ if(H && H.client)
+ SEND_SOUND(H, struggle_rustle)
- var/list/watching = hearers(3, owner)
- for(var/mob/living/M in watching)
- if(M.client && (M.client.prefs.cit_toggles & EATING_NOISES)) //Might as well censor the normies here too.
- M.show_message(struggle_outer_message, 1) // visible
+ for(var/mob/living/H in hearing_mobs)
+ if(H && H.client && (isturf(H.loc)))
+ H.show_message(struggle_outer_message, 1) // visible
to_chat(R,struggle_user_message)
@@ -551,8 +604,10 @@
to_chat(R,"You start to climb out of \the [lowertext(name)]. ")
to_chat(owner,"Someone is attempting to climb out of your [lowertext(name)]! ")
if(do_after(R, escapetime))
- if((owner.stat || escapable) && (R.loc == src)) //Can still escape?
+ if((escapable) && (R.loc == src)) //Can still escape?
release_specific_contents(R)
+ to_chat(R,"You climb out of \the [lowertext(name)]. ")
+ to_chat(owner,"[R] climbs out of your [lowertext(name)]! ")
return
else if(R.loc != src) //Aren't even in the belly. Quietly fail.
return
@@ -560,41 +615,41 @@
to_chat(R,"Your attempt to escape [lowertext(name)] has failed! ")
to_chat(owner,"The attempt to escape from your [lowertext(name)] has failed! ")
return
- else if(prob(transferchance) && transferlocation) //Next, let's have it see if they end up getting into an even bigger mess then when they started.
- var/obj/belly/dest_belly
- for(var/belly in owner.vore_organs)
- var/obj/belly/B = belly
- if(B.name == transferlocation)
- dest_belly = B
- break
+ else if(prob(transferchance) && transferlocation) //Next, let's have it see if they end up getting into an even bigger mess then when they started.
+ var/obj/belly/dest_belly
+ for(var/belly in owner.vore_organs)
+ var/obj/belly/B = belly
+ if(B.name == transferlocation)
+ dest_belly = B
+ break
- if(!dest_belly)
- to_chat(owner, "Something went wrong with your belly transfer settings. Your [lowertext(name)] has had it's transfer chance and transfer location cleared as a precaution. ")
- transferchance = 0
- transferlocation = null
+ if(!dest_belly)
+ to_chat(owner, "Something went wrong with your belly transfer settings. Your [lowertext(name)] has had it's transfer chance and transfer location cleared as a precaution. ")
+ transferchance = 0
+ transferlocation = null
+ return
+
+ to_chat(R,"Your attempt to escape [lowertext(name)] has failed and your struggles only results in you sliding into [owner]'s [transferlocation]! ")
+ to_chat(owner,"Someone slid into your [transferlocation] due to their struggling inside your [lowertext(name)]! ")
+ transfer_contents(R, dest_belly)
return
- to_chat(R,"Your attempt to escape [lowertext(name)] has failed and your struggles only results in you sliding into [owner]'s [transferlocation]! ")
- to_chat(owner,"Someone slid into your [transferlocation] due to their struggling inside your [lowertext(name)]! ")
- transfer_contents(R, dest_belly)
- return
+ else if(prob(absorbchance) && digest_mode != DM_ABSORB) //After that, let's have it run the absorb chance.
+ to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to cling more tightly... ")
+ to_chat(owner,"You feel your [lowertext(name)] start to cling onto its contents... ")
+ digest_mode = DM_ABSORB
+ return
- else if(prob(absorbchance) && digest_mode != DM_ABSORB) //After that, let's have it run the absorb chance.
- to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to cling more tightly... ")
- to_chat(owner,"You feel your [lowertext(name)] start to cling onto its contents... ")
- digest_mode = DM_ABSORB
- return
+ else if(prob(digestchance) && digest_mode != DM_DIGEST) //Finally, let's see if it should run the digest chance.
+ to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to get more active... ")
+ to_chat(owner,"You feel your [lowertext(name)] beginning to become active! ")
+ digest_mode = DM_DIGEST
+ return
- else if(prob(digestchance) && digest_mode != DM_DIGEST) //Finally, let's see if it should run the digest chance.
- to_chat(R,"In response to your struggling, \the [lowertext(name)] begins to get more active... ")
- to_chat(owner,"You feel your [lowertext(name)] beginning to become active! ")
- digest_mode = DM_DIGEST
- return
-
- else //Nothing interesting happened.
- to_chat(R,"You make no progress in escaping [owner]'s [lowertext(name)]. ")
- to_chat(owner,"Your prey appears to be unable to make any progress in escaping your [lowertext(name)]. ")
- return
+ else //Nothing interesting happened.
+ to_chat(R,"You make no progress in escaping [owner]'s [lowertext(name)]. ")
+ to_chat(owner,"Your prey appears to be unable to make any progress in escaping your [lowertext(name)]. ")
+ return
/obj/belly/proc/get_mobs_and_objs_in_belly()
var/list/see = list()
@@ -641,6 +696,7 @@
dupe.swallow_time = swallow_time
dupe.vore_capacity = vore_capacity
dupe.is_wet = is_wet
+ dupe.wet_loop = wet_loop
//// Object-holding variables
//struggle_messages_outside - strings
diff --git a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm b/code/modules/vore/eating/bellymodes.dm
similarity index 76%
rename from modular_citadel/code/modules/vore/eating/bellymodes_vr.dm
rename to code/modules/vore/eating/bellymodes.dm
index da323f02e2..0ecaf49abc 100644
--- a/modular_citadel/code/modules/vore/eating/bellymodes_vr.dm
+++ b/code/modules/vore/eating/bellymodes.dm
@@ -18,27 +18,29 @@
return SSBELLIES_PROCESSED
next_process = times_fired + (6 SECONDS/wait) //Set up our next process time.
+ var/to_update = FALSE
/////////////////////////// Auto-Emotes ///////////////////////////
if(contents.len && next_emote <= times_fired)
next_emote = times_fired + round(emote_time/wait,1)
var/list/EL = emote_lists[digest_mode]
- for(var/mob/living/M in contents)
- if(M.digestable || !(digest_mode == DM_DIGEST)) // don't give digesty messages to indigestible people
- to_chat(M,"[pick(EL)] ")
+ if(LAZYLEN(EL))
+ for(var/mob/living/M in contents)
+ if(M.digestable || !(digest_mode == DM_DIGEST)) // don't give digesty messages to indigestible people
+ to_chat(M,"[pick(EL)] ")
///////////////////// Prey Loop Refresh/hack //////////////////////
for(var/mob/living/M in contents)
- if(isbelly(M.loc))
+ if(M && isbelly(M.loc))
if(world.time > M.next_preyloop)
- if(is_wet)
+ if(is_wet && wet_loop)
if(!M.client)
continue
M.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case
if(M.client.prefs.cit_toggles & DIGESTION_NOISES)
- var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
+ var/sound/preyloop = sound('sound/vore/prey/loop.ogg')
M.playsound_local(get_turf(src),preyloop, 80,0, channel = CHANNEL_PREYLOOP)
- M.next_preyloop = (world.time + 52 SECONDS)
+ M.next_preyloop = (world.time + 51 SECONDS)
/////////////////////////// Exit Early ////////////////////////////
@@ -56,7 +58,6 @@
var/sound/prey_death = sound(get_sfx("death_prey"))
var/sound/pred_digest = sound(get_sfx("digest_pred"))
var/sound/pred_death = sound(get_sfx("death_pred"))
- var/turf/source = get_turf(owner)
///////////////////////////// DM_HOLD /////////////////////////////
if(digest_mode == DM_HOLD)
@@ -70,18 +71,18 @@
for (var/mob/living/M in contents)
if(prob(25))
- if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, source))
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
continue
LAZYADD(hearing_mobs, H)
last_hearcheck = world.time
for(var/mob/living/H in hearing_mobs)
- if(!isbelly(H.loc))
- H.playsound_local(source, null, 45, falloff = 0, S = pred_digest)
- else if(H in contents)
- H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_digest)
+ else if(H && H in contents && H.client)
+ SEND_SOUND(H,prey_digest)
//Pref protection!
if (!M.digestable || M.absorbed)
@@ -107,21 +108,22 @@
M.visible_message("You watch as [owner]'s form loses its additions. ")
owner.nutrition += 400 // so eating dead mobs gives you *something*.
- if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, source))
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
continue
LAZYADD(hearing_mobs, H)
last_hearcheck = world.time
for(var/mob/living/H in hearing_mobs)
- if(!isbelly(H.loc))
- H.playsound_local(source, null, 45, falloff = 0, S = pred_death)
- else if(H in contents)
- H.playsound_local(source, null, 65, falloff = 0, S = prey_death)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_death)
+ else if(H && H in contents && H.client)
+ SEND_SOUND(H,prey_death)
M.stop_sound_channel(CHANNEL_PREYLOOP)
digestion_death(M)
owner.update_icons()
+ to_update = TRUE
continue
@@ -136,48 +138,45 @@
if(istype(T,/obj/item/reagent_containers/food) || istype(T,/obj/item/organ))
digest_item(T)
- owner.updateVRPanel()
-
///////////////////////////// DM_HEAL /////////////////////////////
if(digest_mode == DM_HEAL)
for (var/mob/living/M in contents)
if(prob(25))
- if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, source))
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
continue
LAZYADD(hearing_mobs, H)
last_hearcheck = world.time
for(var/mob/living/H in hearing_mobs)
- if(!isbelly(H.loc))
- H.playsound_local(source, null, 45, falloff = 0, S = pred_digest)
- else if(H in contents)
- H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_digest)
+ else if(H && H in contents && H.client)
+ SEND_SOUND(H,prey_digest)
if(M.stat != DEAD)
if(owner.nutrition >= NUTRITION_LEVEL_STARVING && (M.health < M.maxHealth))
M.adjustBruteLoss(-3)
M.adjustFireLoss(-3)
owner.nutrition -= 5
- return
////////////////////////// DM_NOISY /////////////////////////////////
//for when you just want people to squelch around
if(digest_mode == DM_NOISY)
if(prob(35))
- if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, source))
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
continue
LAZYADD(hearing_mobs, H)
last_hearcheck = world.time
for(var/mob/living/H in hearing_mobs)
- if(!isbelly(H.loc))
- H.playsound_local(source, null, 45, falloff = 0, S = pred_digest)
- else if(H in contents)
- H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_digest)
+ else if(H && H in contents && H.client)
+ SEND_SOUND(H,prey_digest)
//////////////////////////// DM_ABSORB ////////////////////////////
@@ -186,18 +185,18 @@
for (var/mob/living/M in contents)
if(prob(10))//Less often than gurgles. People might leave this on forever.
- if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, source))
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
continue
LAZYADD(hearing_mobs, H)
last_hearcheck = world.time
for(var/mob/living/H in hearing_mobs)
- if(!isbelly(H.loc))
- H.playsound_local(source, null, 45, falloff = 0, S = pred_digest)
- else if(H in contents)
- H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_digest)
+ else if(H && H in contents && H.client)
+ SEND_SOUND(H,prey_digest)
if(M.absorbed)
continue
@@ -208,16 +207,18 @@
owner.nutrition += oldnutrition
else if(M.nutrition < 100) //When they're finally drained.
absorb_living(M)
+ to_update = TRUE
//////////////////////////// DM_UNABSORB ////////////////////////////
else if(digest_mode == DM_UNABSORB)
for (var/mob/living/M in contents)
if(M.absorbed && owner.nutrition >= 100)
- M.absorbed = 0
+ M.absorbed = FALSE
to_chat(M,"You suddenly feel solid again ")
to_chat(owner,"You feel like a part of you is missing. ")
owner.nutrition -= 100
+ to_update = TRUE
//////////////////////////DM_DRAGON /////////////////////////////////////
//because dragons need snowflake guts
@@ -228,18 +229,18 @@
for (var/mob/living/M in contents)
if(prob(55)) //if you're hearing this, you're a vore ho anyway.
- if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, source))
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
continue
LAZYADD(hearing_mobs, H)
last_hearcheck = world.time
for(var/mob/living/H in hearing_mobs)
- if(!isbelly(H.loc))
- H.playsound_local(source, null, 45, falloff = 0, S = pred_digest)
- else if(H in contents)
- H.playsound_local(source, null, 65, falloff = 0, S = prey_digest)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_digest)
+ else if(H && H in contents && H.client)
+ SEND_SOUND(H,prey_digest)
//No digestion protection for megafauna.
@@ -261,22 +262,23 @@
to_chat(owner, "[digest_alert_owner] ")
to_chat(M, "[digest_alert_prey] ")
M.visible_message("You watch as [owner]'s guts loudly rumble as it finishes off a meal. ")
- if((world.time - NORMIE_HEARCHECK) > last_hearcheck)
+ if((world.time + NORMIE_HEARCHECK) > last_hearcheck)
LAZYCLEARLIST(hearing_mobs)
- for(var/mob/living/H in get_hearers_in_view(3, source))
+ for(var/mob/living/H in get_hearers_in_view(3, owner))
if(!H.client || !(H.client.prefs.cit_toggles & DIGESTION_NOISES))
continue
LAZYADD(hearing_mobs, H)
last_hearcheck = world.time
for(var/mob/living/H in hearing_mobs)
- if(!isbelly(H.loc))
- H.playsound_local(source, null, 45, falloff = 0, S = pred_death)
- else if(H in contents)
- H.playsound_local(source, null, 65, falloff = 0, S = prey_death)
+ if(H && H.client && (isturf(H.loc) || (H.loc != src.contents)))
+ SEND_SOUND(H,pred_death)
+ else if(H && H in contents && H.client)
+ SEND_SOUND(H,prey_death)
M.spill_organs(FALSE,TRUE,TRUE)
M.stop_sound_channel(CHANNEL_PREYLOOP)
digestion_death(M)
owner.update_icons()
+ to_update = TRUE
continue
@@ -291,4 +293,11 @@
if(istype(T,/obj/item/reagent_containers/food) || istype(T,/obj/item/organ))
digest_item(T)
- owner.updateVRPanel()
\ No newline at end of file
+ if(to_update)
+ for(var/mob/living/M in contents)
+ if(M.client)
+ M.updateVRPanel()
+ if(owner.client)
+ owner.updateVRPanel()
+
+ return SSBELLIES_PROCESSED
\ No newline at end of file
diff --git a/modular_citadel/code/modules/vore/eating/digest_act_vr.dm b/code/modules/vore/eating/digest_act.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/eating/digest_act_vr.dm
rename to code/modules/vore/eating/digest_act.dm
diff --git a/modular_citadel/code/modules/vore/eating/living_vr.dm b/code/modules/vore/eating/living.dm
similarity index 93%
rename from modular_citadel/code/modules/vore/eating/living_vr.dm
rename to code/modules/vore/eating/living.dm
index d9adde04d1..9fdb7aa764 100644
--- a/modular_citadel/code/modules/vore/eating/living_vr.dm
+++ b/code/modules/vore/eating/living.dm
@@ -8,7 +8,7 @@
var/feeding = FALSE // Are we going to feed someone else?
var/vore_taste = null // What the character tastes like
var/no_vore = FALSE // If the character/mob can vore.
- var/openpanel = 0 // Is the vore panel open?
+ var/openpanel = FALSE // Is the vore panel open?
var/absorbed = FALSE //are we absorbed?
var/next_preyloop
var/vore_init = FALSE //Has this mob's vore been initialized yet?
@@ -23,16 +23,16 @@
M.verbs += /mob/living/proc/escapeOOC
if(M.no_vore) //If the mob isn't supposed to have a stomach, let's not give it an insidepanel so it can make one for itself, or a stomach.
- return 1
+ return TRUE
M.verbs += /mob/living/proc/insidePanel
//Tries to load prefs if a client is present otherwise gives freebie stomach
- spawn(10 SECONDS) // long delay because the server delays in its startup. just on the safe side.
+ spawn(2 SECONDS) // long delay because the server delays in its startup. just on the safe side.
if(M)
M.init_vore()
- //Return 1 to hook-caller
- return 1
+ //return TRUE to hook-caller
+ return TRUE
/mob/living/proc/init_vore()
vore_init = TRUE
@@ -54,10 +54,10 @@
LAZYINITLIST(vore_organs)
var/obj/belly/B = new /obj/belly(src)
vore_selected = B
- B.immutable = 1
+ B.immutable = TRUE
B.name = "Stomach"
B.desc = "It appears to be rather warm and wet. Makes sense, considering it's inside [name]."
- B.can_taste = 1
+ B.can_taste = TRUE
return TRUE
// Handle being clicked, perhaps with something to devour
@@ -84,7 +84,7 @@
return
feed_self_to_grabbed(user, pred)
- if(pred == user) //you click yourself
+ else if(pred == user) //you click yourself
if(!is_vore_predator(src))
to_chat(user, "You aren't voracious enough. ")
return
@@ -126,7 +126,7 @@
//Sanity
if(!user || !prey || !pred || !istype(belly) || !(belly in pred.vore_organs))
testing("[user] attempted to feed [prey] to [pred], via [lowertext(belly.name)] but it went wrong.")
- return FALSE
+ return
if (!prey.devourable)
to_chat(user, "This can't be eaten!")
@@ -151,9 +151,14 @@
user.visible_message(attempt_msg)
// Now give the prey time to escape... return if they did
- var/swallow_time = delay || ishuman(prey) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time
+ var/swallow_time
+ if(delay)
+ swallow_time = delay
+ else
+ swallow_time = istype(prey, /mob/living/carbon/human) ? belly.human_prey_swallow_time : belly.nonhuman_prey_swallow_time
- if(!do_mob(src, user, swallow_time))
+ //Timer and progress bar
+ if(!do_after(user, swallow_time, prey))
return FALSE // Prey escaped (or user disabled) before timer expired.
if(!prey.Adjacent(user)) //double check'd just in case they moved during the timer and the do_mob didn't fail for whatever reason
@@ -162,13 +167,6 @@
// If we got this far, nom successful! Announce it!
user.visible_message(success_msg)
- // incredibly contentious eating noises time
- var/turf/source = get_turf(user)
- var/sound/eating = GLOB.vore_sounds[belly.vore_sound]
- for(var/mob/living/M in get_hearers_in_view(3, source))
- if(M.client && M.client.prefs.cit_toggles & EATING_NOISES)
- SEND_SOUND(M, eating)
-
// Actually shove prey into the belly.
belly.nom_mob(prey, user)
stop_pulling()
@@ -183,7 +181,7 @@
if(prey.ckey)
prey_stat = prey.stat//only return this if they're not an unmonkey or whatever
if(!prey.client)//if they disconnected, tell us
- prey_braindead = 1
+ prey_braindead = TRUE
if (pred == user)
message_admins("[ADMIN_LOOKUPFLW(pred)] ate [ADMIN_LOOKUPFLW(prey)][!prey_braindead ? "" : " (BRAINDEAD)"][prey_stat ? " (DEAD/UNCONSCIOUS)" : ""].")
pred.log_message("[key_name(pred)] ate [key_name(prey)].", LOG_ATTACK)
@@ -212,15 +210,15 @@
//Other overridden resists go here
- return 0
+ return FALSE
// internal slimy button in case the loop stops playing but the player wants to hear it
/mob/living/proc/preyloop_refresh()
set name = "Internal loop refresh"
set category = "Vore"
+ src.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case
if(isbelly(loc))
- src.stop_sound_channel(CHANNEL_PREYLOOP) // sanity just in case
- var/sound/preyloop = sound('sound/vore/prey/loop.ogg', repeat = TRUE)
+ var/sound/preyloop = sound('sound/vore/prey/loop.ogg')
SEND_SOUND(src, preyloop)
else
to_chat(src, "You aren't inside anything, you clod. ")
@@ -265,28 +263,28 @@
//
/mob/living/proc/save_vore_prefs()
if(!client || !client.prefs_vr)
- return 0
+ return FALSE
if(!copy_to_prefs_vr())
- return 0
+ return FALSE
if(!client.prefs_vr.save_vore())
- return 0
+ return FALSE
- return 1
+ return TRUE
/mob/living/proc/apply_vore_prefs()
if(!client || !client.prefs_vr)
- return 0
+ return FALSE
if(!client.prefs_vr.load_vore())
- return 0
+ return FALSE
if(!copy_from_prefs_vr())
- return 0
+ return FALSE
- return 1
+ return TRUE
/mob/living/proc/copy_to_prefs_vr()
if(!client || !client.prefs_vr)
to_chat(src,"You attempted to save your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev. ")
- return 0
+ return FALSE
var/datum/vore_preferences/P = client.prefs_vr
@@ -302,7 +300,7 @@
P.belly_prefs = serialized
- return 1
+ return TRUE
//
// Proc for applying vore preferences, given bellies
@@ -310,7 +308,7 @@
/mob/living/proc/copy_from_prefs_vr()
if(!client || !client.prefs_vr)
to_chat(src,"You attempted to apply your vore prefs but somehow you're in this character without a client.prefs_vr variable. Tell a dev. ")
- return 0
+ return FALSE
vorepref_init = TRUE
var/datum/vore_preferences/P = client.prefs_vr
@@ -325,7 +323,7 @@
for(var/entry in P.belly_prefs)
list_to_object(entry,src)
- return 1
+ return TRUE
//
// Release everything in every vore organ
diff --git a/modular_citadel/code/modules/vore/eating/vore_vr.dm b/code/modules/vore/eating/vore.dm
similarity index 94%
rename from modular_citadel/code/modules/vore/eating/vore_vr.dm
rename to code/modules/vore/eating/vore.dm
index dc813d70aa..a9b14dcdc8 100644
--- a/modular_citadel/code/modules/vore/eating/vore_vr.dm
+++ b/code/modules/vore/eating/vore.dm
@@ -84,22 +84,22 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
/datum/vore_preferences/proc/load_vore()
if(!client || !client_ckey)
- return 0 //No client, how can we save?
+ return FALSE //No client, how can we save?
if(!client.prefs || !client.prefs.default_slot)
- return 0 //Need to know what character to load!
+ return FALSE //Need to know what character to load!
slot = client.prefs.default_slot
load_path(client_ckey,slot)
- if(!path) return 0 //Path couldn't be set?
+ if(!path) return FALSE //Path couldn't be set?
if(!fexists(path)) //Never saved before
save_vore() //Make the file first
- return 1
+ return TRUE
var/list/json_from_file = json_decode(file2text(path))
if(!json_from_file)
- return 0 //My concern grows
+ return FALSE //My concern grows
var/version = json_from_file["version"]
json_from_file = patch_version(json_from_file,version)
@@ -120,11 +120,11 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
if(isnull(belly_prefs))
belly_prefs = list()
- return 1
+ return TRUE
/datum/vore_preferences/proc/save_vore()
if(!path)
- return 0
+ return FALSE
var/version = VORE_VERSION //For "good times" use in the future
var/list/settings_list = list(
@@ -140,7 +140,7 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
var/json_to_file = json_encode(settings_list)
if(!json_to_file)
testing("Saving: [path] failed jsonencode")
- return 0
+ return FALSE
//Write it out
//#ifdef RUST_G
@@ -153,9 +153,9 @@ GLOBAL_LIST_EMPTY(vore_preferences_datums)
//#endif
if(!fexists(path))
testing("Saving: [path] failed file write")
- return 0
+ return FALSE
- return 1
+ return TRUE
/* commented out list things
"allowmobvore" = allowmobvore,
diff --git a/modular_citadel/code/modules/vore/eating/voreitems.dm b/code/modules/vore/eating/voreitems.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/eating/voreitems.dm
rename to code/modules/vore/eating/voreitems.dm
diff --git a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm b/code/modules/vore/eating/vorepanel.dm
similarity index 92%
rename from modular_citadel/code/modules/vore/eating/vorepanel_vr.dm
rename to code/modules/vore/eating/vorepanel.dm
index ae7da895a6..962fe54af7 100644
--- a/modular_citadel/code/modules/vore/eating/vorepanel_vr.dm
+++ b/code/modules/vore/eating/vorepanel.dm
@@ -21,10 +21,10 @@
picker_holder.popup = new(src, "insidePanel","Vore Panel", 450, 700, picker_holder)
picker_holder.popup.set_content(dat)
picker_holder.popup.open()
- src.openpanel = 1
+ src.openpanel = TRUE
/mob/living/proc/updateVRPanel() //Panel popup update call from belly events.
- if(src.openpanel == 1)
+ if(src.openpanel == TRUE)
var/datum/vore_look/picker_holder = new()
picker_holder.loop = picker_holder
picker_holder.selected = vore_selected
@@ -40,7 +40,7 @@
//
/datum/vore_look
var/obj/belly/selected
- var/show_interacts = 0
+ var/show_interacts = FALSE
var/datum/browser/popup
var/loop = null; // Magic self-reference to stop the handler from being GC'd before user takes action.
@@ -163,6 +163,9 @@
//Belly Type button
dat += "Is Fleshy: "
dat += "[selected.is_wet ? "Yes" : "No"]"
+ if(selected.is_wet)
+ dat += "Internal loop for prey?: "
+ dat += "[selected.wet_loop ? "Yes" : "No"]"
//Digest Mode Button
dat += "Belly Mode: "
@@ -241,21 +244,19 @@
dat += " "
switch(user.digestable)
if(TRUE)
- dat += "Toggle Digestable (Currently: ON) "
+ dat += "Toggle Digestable (Currently: ON) "
if(FALSE)
- dat += "Toggle Digestable (Currently: OFF) "
-
+ dat += "Toggle Digestable (Currently: OFF) "
switch(user.devourable)
if(TRUE)
- dat += "Toggle Devourable (Currently: ON) "
+ dat += "Toggle Devourable (Currently: ON) "
if(FALSE)
- dat += "Toggle Devourable (Currently: OFF) "
-
+ dat += "Toggle Devourable (Currently: OFF) "
switch(user.feeding)
if(TRUE)
- dat += "Toggle Feeding (Currently: ON) "
+ dat += "Toggle Feeding (Currently: ON) "
if(FALSE)
- dat += "Toggle Feeding (Currently: OFF) "
+ dat += "Toggle Feeding (Currently: OFF) "
//Returns the dat html to the vore_look
return dat
@@ -266,12 +267,12 @@
if(href_list["close"])
qdel(src) // Cleanup
- user.openpanel = 0
+ user.openpanel = FALSE
return
if(href_list["show_int"])
show_interacts = !show_interacts
- return 1 //Force update
+ return TRUE //Force update
if(href_list["int_help"])
alert("These control how your belly responds to someone using 'resist' while inside you. The percent chance to trigger each is listed below, \
@@ -279,13 +280,13 @@
These only function as long as interactions are turned on in general. Keep in mind, the 'belly mode' interactions (digest/absorb) \
will affect all prey in that belly, if one resists and triggers digestion/absorption. If multiple trigger at the same time, \
only the first in the order of 'Escape > Transfer > Absorb > Digest' will occur.","Interactions Help")
- return 0 //Force update
+ return FALSE //Force update
if(href_list["outsidepick"])
var/atom/movable/tgt = locate(href_list["outsidepick"])
var/obj/belly/OB = locate(href_list["outsidebelly"])
if(!(tgt in OB)) //Aren't here anymore, need to update menu.
- return 1
+ return TRUE
var/intent = "Examine"
if(istype(tgt,/mob/living))
@@ -298,7 +299,7 @@
if("Help Out") //Help the inside-mob out
if(user.stat || user.absorbed || M.absorbed)
to_chat(user,"You can't do that in your state! ")
- return 1
+ return TRUE
to_chat(user,"You begin to push [M] to freedom! ")
to_chat(M,"[usr] begins to push you to freedom!")
@@ -317,11 +318,11 @@
if("Devour") //Eat the inside mob
if(user.absorbed || user.stat)
to_chat(user,"You can't do that in your state! ")
- return 1
+ return TRUE
if(!user.vore_selected)
to_chat(user,"Pick a belly on yourself first! ")
- return 1
+ return TRUE
var/obj/belly/TB = user.vore_selected
to_chat(user,"You begin to [lowertext(TB.vore_verb)] [M] into your [lowertext(TB.name)]! ")
@@ -339,7 +340,7 @@
var/obj/item/T = tgt
if(!(tgt in OB))
//Doesn't exist anymore, update.
- return 1
+ return TRUE
intent = alert("What do you want to do to that?","Query","Examine","Use Hand")
switch(intent)
if("Examine")
@@ -348,7 +349,7 @@
if("Use Hand")
if(user.stat)
to_chat(user,"You can't do that in your state! ")
- return 1
+ return TRUE
user.ClickOn(T)
sleep(5) //Seems to exit too fast for the panel to update
@@ -361,23 +362,23 @@
intent = alert("Eject all, Move all?","Query","Eject all","Cancel","Move all")
switch(intent)
if("Cancel")
- return 0
+ return FALSE
if("Eject all")
if(user.stat)
to_chat(user,"You can't do that in your state! ")
- return 0
+ return FALSE
selected.release_all_contents()
if("Move all")
if(user.stat)
to_chat(user,"You can't do that in your state! ")
- return 0
+ return FALSE
var/obj/belly/choice = input("Move all where?","Select Belly") as null|anything in user.vore_organs
if(!choice)
- return 0
+ return FALSE
for(var/atom/movable/tgt in selected)
to_chat(tgt,"You're squished from [user]'s [lowertext(selected)] to their [lowertext(choice.name)]! ")
@@ -385,7 +386,7 @@
var/atom/movable/tgt = locate(href_list["insidepick"])
if(!(tgt in selected)) //Old menu, needs updating because they aren't really there.
- return 1 //Forces update
+ return TRUE //Forces update
intent = "Examine"
intent = alert("Examine, Eject, Move? Examine if you want to leave this box.","Query","Examine","Eject","Move")
switch(intent)
@@ -395,25 +396,25 @@
if("Eject")
if(user.stat)
to_chat(user,"You can't do that in your state! ")
- return 0
+ return FALSE
selected.release_specific_contents(tgt)
if("Move")
if(user.stat)
to_chat(user,"You can't do that in your state! ")
- return 0
+ return FALSE
var/obj/belly/choice = input("Move [tgt] where?","Select Belly") as null|anything in user.vore_organs
if(!choice || !(tgt in selected))
- return 0
+ return FALSE
to_chat(tgt,"You're squished from [user]'s [lowertext(selected.name)] to their [lowertext(choice.name)]! ")
selected.transfer_contents(tgt, choice)
if(href_list["newbelly"])
if(user.vore_organs.len >= BELLIES_MAX)
- return 0
+ return FALSE
var/new_name = html_encode(input(usr,"New belly's name:","New Belly") as text|null)
@@ -430,7 +431,7 @@
if(failure_msg) //Something went wrong.
alert(user,failure_msg,"Error!")
- return 0
+ return FALSE
var/obj/belly/NB = new(user)
NB.name = new_name
@@ -459,19 +460,22 @@
if(failure_msg) //Something went wrong.
alert(user,failure_msg,"Error!")
- return 0
+ return FALSE
selected.name = new_name
if(href_list["b_wetness"])
selected.is_wet = !selected.is_wet
+ if(href_list["b_wetloop"])
+ selected.wet_loop = !selected.wet_loop
+
if(href_list["b_mode"])
var/list/menu_list = selected.digest_modes
var/new_mode = input("Choose Mode (currently [selected.digest_mode])") as null|anything in menu_list
if(!new_mode)
- return 0
+ return FALSE
selected.digest_mode = new_mode
if(href_list["b_desc"])
@@ -539,12 +543,12 @@
if(length(new_verb) > BELLIES_NAME_MAX || length(new_verb) < BELLIES_NAME_MIN)
alert("Entered verb length invalid (must be longer than [BELLIES_NAME_MIN], no longer than [BELLIES_NAME_MAX]).","Error")
- return 0
+ return FALSE
selected.vore_verb = new_verb
if(href_list["b_release"])
- var/choice = input(user,"Currently set to [selected.release_sound]","Select Sound") as null|anything in GLOB.release_sounds
+ var/choice = input(user,"Currently set to [selected.release_sound]","Select Sound") as null|anything in GLOB.pred_release_sounds
if(!choice)
return
@@ -552,12 +556,12 @@
selected.release_sound = choice
if(href_list["b_releasesoundtest"])
- var/sound/releasetest = GLOB.release_sounds[selected.release_sound]
+ var/sound/releasetest = GLOB.prey_release_sounds[selected.release_sound]
if(releasetest)
SEND_SOUND(user, releasetest)
if(href_list["b_sound"])
- var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") as null|anything in GLOB.vore_sounds
+ var/choice = input(user,"Currently set to [selected.vore_sound]","Select Sound") as null|anything in GLOB.pred_vore_sounds
if(!choice)
return
@@ -565,7 +569,7 @@
selected.vore_sound = choice
if(href_list["b_soundtest"])
- var/sound/voretest = GLOB.vore_sounds[selected.vore_sound]
+ var/sound/voretest = GLOB.prey_vore_sounds[selected.vore_sound]
if(voretest)
SEND_SOUND(user, voretest)
@@ -586,17 +590,17 @@
selected.bulge_size = (new_bulge/100)
if(href_list["b_escapable"])
- if(selected.escapable == 0) //Possibly escapable and special interactions.
- selected.escapable = 1
+ if(selected.escapable == FALSE) //Possibly escapable and special interactions.
+ selected.escapable = TRUE
to_chat(usr,"Prey now have special interactions with your [lowertext(selected.name)] depending on your settings. ")
- else if(selected.escapable == 1) //Never escapable.
- selected.escapable = 0
+ else if(selected.escapable == TRUE) //Never escapable.
+ selected.escapable = FALSE
to_chat(usr,"Prey will not be able to have special interactions with your [lowertext(selected.name)]. ")
- show_interacts = 0 //Force the hiding of the panel
+ show_interacts = FALSE //Force the hiding of the panel
else
alert("Something went wrong. Your stomach will now not have special interactions. Press the button enable them again and tell a dev.","Error") //If they somehow have a varable that's not 0 or 1
- selected.escapable = 0
- show_interacts = 0 //Force the hiding of the panel
+ selected.escapable = FALSE
+ show_interacts = FALSE //Force the hiding of the panel
if(href_list["b_escapechance"])
var/escape_chance_input = input(user, "Set prey escape chance on resist (as %)", "Prey Escape Chance") as num|null
@@ -617,7 +621,7 @@
var/obj/belly/choice = input("Where do you want your [lowertext(selected.name)] to lead if prey resists?","Select Belly") as null|anything in (user.vore_organs + "None - Remove" - selected)
if(!choice) //They cancelled, no changes
- return 0
+ return FALSE
else if(choice == "None - Remove")
selected.transferlocation = null
else
@@ -636,7 +640,7 @@
if(href_list["b_del"])
var/alert = alert("Are you sure you want to delete your [lowertext(selected.name)]?","Confirmation","Delete","Cancel")
if(!alert == "Delete")
- return 0
+ return FALSE
var/failure_msg = ""
@@ -657,7 +661,7 @@
if(failure_msg)
alert(user,failure_msg,"Error!")
- return 0
+ return FALSE
qdel(selected)
selected = user.vore_organs[1]
@@ -674,7 +678,7 @@
if(href_list["applyprefs"])
var/alert = alert("Are you sure you want to reload character slot preferences? This will remove your current vore organs and eject their contents.","Confirmation","Reload","Cancel")
if(!alert == "Reload")
- return 0
+ return FALSE
if(!user.apply_vore_prefs())
alert("ERROR: Vore preferences failed to apply!","Error")
else
@@ -683,19 +687,19 @@
if(href_list["setflavor"])
var/new_flavor = html_encode(input(usr,"What your character tastes like (40ch limit). This text will be printed to the pred after 'X tastes of...' so just put something like 'strawberries and cream':","Character Flavor",user.vore_taste) as text|null)
if(!new_flavor)
- return 0
+ return FALSE
new_flavor = readd_quotes(new_flavor)
if(length(new_flavor) > FLAVOR_MAX)
alert("Entered flavor/taste text too long. [FLAVOR_MAX] character limit.","Error!")
- return 0
+ return FALSE
user.vore_taste = new_flavor
if(href_list["toggledg"])
var/choice = alert(user, "This button is for those who don't like being digested. It can make you undigestable to all mobs. Digesting you is currently: [user.digestable ? "Allowed" : "Prevented"]", "", "Allow Digestion", "Cancel", "Prevent Digestion")
switch(choice)
if("Cancel")
- return 0
+ return FALSE
if("Allow Digestion")
user.digestable = TRUE
if("Prevent Digestion")
@@ -708,7 +712,7 @@
var/choice = alert(user, "This button is for those who don't like vore at all. Devouring you is currently: [user.devourable ? "Allowed" : "Prevented"]", "", "Allow Devourment", "Cancel", "Prevent Devourment")
switch(choice)
if("Cancel")
- return 0
+ return FALSE
if("Allow Devourment")
user.devourable = TRUE
if("Prevent Devourment")
@@ -721,7 +725,7 @@
var/choice = alert(user, "This button is to toggle your ability to be fed to others. Feeding predators is currently: [user.feeding ? "Allowed" : "Prevented"]", "", "Allow Feeding", "Cancel", "Prevent Feeding")
switch(choice)
if("Cancel")
- return 0
+ return FALSE
if("Allow Feeding")
user.feeding = TRUE
if("Prevent Feeding")
@@ -731,4 +735,4 @@
user.client.prefs_vr.feeding = user.feeding
//Refresh when interacted with, returning 1 makes vore_look.Topic update
- return 1
\ No newline at end of file
+ return TRUE
\ No newline at end of file
diff --git a/modular_citadel/code/modules/vore/hook-defs_vr.dm b/code/modules/vore/hook-defs.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/hook-defs_vr.dm
rename to code/modules/vore/hook-defs.dm
diff --git a/modular_citadel/code/modules/vore/persistence.dm b/code/modules/vore/persistence.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/persistence.dm
rename to code/modules/vore/persistence.dm
diff --git a/modular_citadel/code/modules/vore/resizing/grav_pull_vr.dm b/code/modules/vore/resizing/grav_pull_vr.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/resizing/grav_pull_vr.dm
rename to code/modules/vore/resizing/grav_pull_vr.dm
diff --git a/modular_citadel/code/modules/vore/resizing/holder_micro_vr.dm b/code/modules/vore/resizing/holder_micro_vr.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/resizing/holder_micro_vr.dm
rename to code/modules/vore/resizing/holder_micro_vr.dm
diff --git a/modular_citadel/code/modules/vore/resizing/resize_vr.dm b/code/modules/vore/resizing/resize_vr.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/resizing/resize_vr.dm
rename to code/modules/vore/resizing/resize_vr.dm
diff --git a/modular_citadel/code/modules/vore/resizing/sizechemicals.dm b/code/modules/vore/resizing/sizechemicals.dm
similarity index 98%
rename from modular_citadel/code/modules/vore/resizing/sizechemicals.dm
rename to code/modules/vore/resizing/sizechemicals.dm
index 1164bf65d6..f83ba2ce76 100644
--- a/modular_citadel/code/modules/vore/resizing/sizechemicals.dm
+++ b/code/modules/vore/resizing/sizechemicals.dm
@@ -84,7 +84,7 @@
return
/datum/reagent/medicine/sizeoxadone/overdose_process(mob/living/M)
- M.adjustBrainLoss(1)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
M.adjustToxLoss(1)
..()
. = 1
diff --git a/modular_citadel/code/modules/vore/resizing/sizegun_vr.dm b/code/modules/vore/resizing/sizegun_vr.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/resizing/sizegun_vr.dm
rename to code/modules/vore/resizing/sizegun_vr.dm
diff --git a/modular_citadel/code/modules/vore/trycatch_vr.dm b/code/modules/vore/trycatch.dm
similarity index 100%
rename from modular_citadel/code/modules/vore/trycatch_vr.dm
rename to code/modules/vore/trycatch.dm
diff --git a/code/modules/zombie/items.dm b/code/modules/zombie/items.dm
index ae53f29a55..0f6ef14cd1 100644
--- a/code/modules/zombie/items.dm
+++ b/code/modules/zombie/items.dm
@@ -73,5 +73,5 @@
user.adjustFireLoss(-hp_gained, 0)
user.adjustCloneLoss(-hp_gained, 0)
user.updatehealth()
- user.adjustBrainLoss(-hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!"
+ user.adjustOrganLoss(ORGAN_SLOT_BRAIN, -hp_gained) // Zom Bee gibbers "BRAAAAISNSs!1!"
user.nutrition = min(user.nutrition + hp_gained, NUTRITION_LEVEL_FULL)
diff --git a/config/config.txt b/config/config.txt
index a01f5424da..0501d1fd2f 100644
--- a/config/config.txt
+++ b/config/config.txt
@@ -146,6 +146,9 @@ LOG_MANIFEST
## Enable logging pictures
# LOG_PICTURES
+## log virus and actions
+LOG_VIRUS
+
##Log camera pictures - Must have picture logging enabled
PICTURE_LOGGING_CAMERA
@@ -230,22 +233,22 @@ CHECK_RANDOMIZER
# SERVER ss13.example.com:2506
## forum address
-# FORUMURL http://tgstation13.org/phpBB/index.php
+# FORUMURL https://citadel-station.net/forum/
## Wiki address
-# WIKIURL http://www.tgstation13.org/wiki
+# WIKIURL https://katlin.dog/citadel-wiki
## Rules address
-# RULESURL http://www.tgstation13.org/wiki/Rules
+# RULESURL https://katlin.dog/citadel-rules/main
## Github address
-# GITHUBURL https://www.github.com/tgstation/tgstation
+# GITHUBURL https://github.com/Citadel-Station-13/Citadel-Station-13
## Round specific stats address
## Link to round specific parsed logs; IE statbus. It is appended with the RoundID automatically by ticker/Reboot()
## This will take priority over the game logs address during reboot.
## Example: https://atlantaned.space/statbus/round.php?round=
-# ROUNDSTATSURL
+# ROUNDSTATSURL http://citadel-station.net/slimbus/
## Game Logs address
## Incase you don't have a fancy parsing system, but still want players to be able to find where you keep your server's logs.
@@ -255,10 +258,10 @@ CHECK_RANDOMIZER
## Github repo id
##This can be found by going to https://api.github.com/users//repos
##Or https://api.github.com/orgs//repos if the repo owner is an organization
-# GITHUBREPOID 3234987
+# GITHUBREPOID 62485194
## Ban appeals URL - usually for a forum or wherever people should go to contact your admins.
-# BANAPPEALS http://justanotherday.example.com
+# BANAPPEALS https://citadel-station.net/forum/viewforum.php?f=8&sid=a0ce5331d5594ef6d49661609c6f4ff9
## System command that invokes youtube-dl, used by Play Internet Sound.
## You can install youtube-dl with
diff --git a/config/game_options.txt b/config/game_options.txt
index 2e346ce0ac..c06845cde3 100644
--- a/config/game_options.txt
+++ b/config/game_options.txt
@@ -255,6 +255,147 @@ EVENTS_MIN_TIME_MUL 1
EVENTS_MIN_PLAYERS_MUL 1
+
+### DYNAMIC MODE ###
+
+## Injection delays: how long (in minutes) will pass before a midround or latejoin antag is injected.
+DYNAMIC_MIDROUND_DELAY_MIN 15
+DYNAMIC_MIDROUND_DELAY_MAX 35
+DYNAMIC_LATEJOIN_DELAY_MIN 5
+DYNAMIC_LATEJOIN_DELAY_MAX 25
+
+## How many roundstart players required for high population override to take effect.
+DYNAMIC_HIGH_POP_LIMIT 55
+
+## Pop range per requirement.
+## If the value is five the range is:
+## 0-4, 5-9, 10-14, 15-19, 20-24, 25-29, 30-34, 35-39, 40-54, 45+
+## If it is six the range is:
+## 0-5, 6-11, 12-17, 18-23, 24-29, 30-35, 36-41, 42-47, 48-53, 54+
+## If it is seven the range is:
+## 0-6, 7-13, 14-20, 21-27, 28-34, 35-41, 42-48, 49-55, 56-62, 63+
+## Options outside this range can be used, of course.
+DYNAMIC_POP_PER_REQUIREMENT 6
+
+## 1 -> 9, probability for this rule to be picked against other rules.
+## Note that requirements must also be met, and some requirements are impossible to meet.
+DYNAMIC_WEIGHT TRAITOR 5
+DYNAMIC_WEIGHT TRAITORBRO 4
+DYNAMIC_WEIGHT CHANGELING 3
+DYNAMIC_WEIGHT WIZARD 1
+DYNAMIC_WEIGHT CULT 3
+DYNAMIC_WEIGHT NUCLEAR 3
+DYNAMIC_WEIGHT REVOLUTION 2
+# All below are impossible-by-default
+DYNAMIC_WEIGHT EXTENDED 3
+DYNAMIC_WEIGHT CLOCKWORK_CULT 3
+DYNAMIC_WEIGHT CLOWNOPS 3
+DYNAMIC_WEIGHT DEVIL 3
+DYNAMIC_WEIGHT MONKEY 3
+DYNAMIC_WEIGHT METEOR 3
+
+## Midround antags
+DYNAMIC_WEIGHT MIDROUND_TRAITOR 7
+DYNAMIC_WEIGHT MALF_AI 3
+DYNAMIC_WEIGHT MIDROUND_WIZARD 1
+DYNAMIC_WEIGHT MIDROUND_NUCLEAR 5
+DYNAMIC_WEIGHT BLOB 4
+DYNAMIC_WEIGHT XENOS 3
+DYNAMIC_WEIGHT NIGHTMARE 3
+
+## Latejoin antags
+DYNAMIC_WEIGHT LATEJOIN_TRAITOR 7
+DYNAMIC_WEIGHT LATEJOIN_REVOLUTION 2
+
+## Threat cost. This is decreased from the mode's threat when the rule is executed.
+DYNAMIC_COST TRAITOR 10
+DYNAMIC_COST TRAITORBRO 10
+DYNAMIC_COST CHANGELING 30
+DYNAMIC_COST WIZARD 30
+DYNAMIC_COST CULT 30
+DYNAMIC_COST NUCLEAR 40
+DYNAMIC_COST REVOLUTION 35
+# All below are impossible-by-default
+DYNAMIC_COST EXTENDED 0
+DYNAMIC_COST CLOCKWORK_CULT 0
+DYNAMIC_COST CLOWNOPS 40
+DYNAMIC_COST DEVIL 0
+DYNAMIC_COST MONKEY 0
+DYNAMIC_COST METEOR 0
+
+## Midround antags
+DYNAMIC_COST MIDROUND_TRAITOR 10
+DYNAMIC_COST MALF_AI 35
+DYNAMIC_COST MIDROUND_WIZARD 20
+DYNAMIC_COST MIDROUND_NUCLEAR 35
+DYNAMIC_COST BLOB 10
+DYNAMIC_COST XENOS 10
+DYNAMIC_COST NIGHTMARE 10
+
+## Latejoin antags
+DYNAMIC_COST LATEJOIN_TRAITOR 5
+DYNAMIC_COST LATEJOIN_REVOLUTION 20
+
+## Rule will not be generated with threat levels below requirement at a pop value. Pop values are determined by dynamic's pop-per-requirement.
+## By default it's 0-5, 6-11, 12-17, 18-23, 24-29, 30-35, 36-41, 42-47, 48-53, 54+.
+## This means that 40 30 30 20 20 20 15 15 15 10 will not generate below 40 at 0-5, 30 at 6-11 etc.
+DYNAMIC_REQUIREMENTS TRAITOR 10 10 10 10 10 10 10 10 10 10
+DYNAMIC_REQUIREMENTS TRAITORBRO 40 30 30 20 20 15 15 15 10 10
+DYNAMIC_REQUIREMENTS CHANGELING 80 70 60 50 40 20 20 10 10 10
+DYNAMIC_REQUIREMENTS WIZARD 90 90 70 40 30 20 10 10 10 10
+DYNAMIC_REQUIREMENTS CULT 100 90 80 60 40 30 10 10 10 10
+DYNAMIC_REQUIREMENTS NUCLEAR 90 90 90 80 60 40 30 20 10 10
+DYNAMIC_REQUIREMENTS REVOLUTION 101 101 70 40 30 20 10 10 10 10
+# All below are impossible-by-default
+DYNAMIC_REQUIREMENTS EXTENDED 101 101 101 101 101 101 101 101 101 101
+DYNAMIC_REQUIREMENTS CLOCKWORK_CULT 101 101 101 101 101 101 101 101 101 101
+DYNAMIC_REQUIREMENTS CLOWNOPS 101 101 101 101 101 101 101 101 101 101
+DYNAMIC_REQUIREMENTS DEVIL 101 101 101 101 101 101 101 101 101 101
+DYNAMIC_REQUIREMENTS MONKEY 101 101 101 101 101 101 101 101 101 101
+DYNAMIC_REQUIREMENTS METEOR 101 101 101 101 101 101 101 101 101 101
+
+## Midround antags
+DYNAMIC_REQUIREMENTS MIDROUND_TRAITOR 50 40 30 20 10 10 10 10 10 10
+DYNAMIC_REQUIREMENTS MALF_AI 101 101 80 70 60 60 50 50 40 40
+DYNAMIC_REQUIREMENTS MIDROUND_WIZARD 90 90 70 40 30 20 10 10 10 10
+DYNAMIC_REQUIREMENTS MIDROUND_NUCLEAR 90 90 90 80 60 40 30 20 10 10
+DYNAMIC_REQUIREMENTS BLOB 101 101 101 80 60 50 30 20 10 10
+DYNAMIC_REQUIREMENTS XENOS 101 101 101 70 50 40 20 15 10 10
+DYNAMIC_REQUIREMENTS NIGHTMARE 101 101 101 70 50 40 20 15 10 10
+
+## Latejoin antags
+DYNAMIC_REQUIREMENTS LATEJOIN_TRAITOR 40 30 20 10 10 10 10 10 10 10
+DYNAMIC_REQUIREMENTS LATEJOIN_REVOLUTION 101 101 70 40 30 20 20 20 20 20
+
+## An alternative, static requirement used instead when pop is over mode's high_pop_limit.
+DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITOR 10
+DYNAMIC_HIGH_POPULATION_REQUIREMENT TRAITORBRO 15
+DYNAMIC_HIGH_POPULATION_REQUIREMENT CHANGELING 10
+DYNAMIC_HIGH_POPULATION_REQUIREMENT WIZARD 10
+DYNAMIC_HIGH_POPULATION_REQUIREMENT CULT 10
+DYNAMIC_HIGH_POPULATION_REQUIREMENT NUCLEAR 10
+DYNAMIC_HIGH_POPULATION_REQUIREMENT REVOLUTION 10
+# All below are impossible-by-default
+DYNAMIC_HIGH_POPULATION_REQUIREMENT EXTENDED 101
+DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOCKWORK_CULT 101
+DYNAMIC_HIGH_POPULATION_REQUIREMENT CLOWNOPS 101
+DYNAMIC_HIGH_POPULATION_REQUIREMENT DEVIL 101
+DYNAMIC_HIGH_POPULATION_REQUIREMENT MONKEY 101
+DYNAMIC_HIGH_POPULATION_REQUIREMENT METEOR 101
+
+## Midround antags
+DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_TRAITOR 10
+DYNAMIC_HIGH_POPULATION_REQUIREMENT MALF_AI 35
+DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_WIZARD 50
+DYNAMIC_HIGH_POPULATION_REQUIREMENT MIDROUND_NUCLEAR 10
+DYNAMIC_HIGH_POPULATION_REQUIREMENT BLOB 50
+DYNAMIC_HIGH_POPULATION_REQUIREMENT XENOS 50
+DYNAMIC_HIGH_POPULATION_REQUIREMENT NIGHTMARE 50
+
+## Latejoin antags
+DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_TRAITOR 10
+DYNAMIC_HIGH_POPULATION_REQUIREMENT LATEJOIN_REVOLUTION 50
+
## AI ###
## Allow the AI job to be picked.
@@ -263,10 +404,21 @@ ALLOW_AI
## Allow the AI Multicamera feature to be used by AI players
ALLOW_AI_MULTICAM
+## CYBORG ##
+## Uncomment to disable the ability for cyborg flashes to knock down carbon targets
+#DISABLE_BORG_FLASH_KNOCKDOWN
+
## Secborg ###
+## Uncomment to bring secborgs and K-9s back in line with the rest of the modules available. This is strongly recommended if you have secborgs configured to be available at all times.
+#WEAKEN_SECBORG
+
## Uncomment to prevent the security cyborg module from being chosen
#DISABLE_SECBORG
+## Determines the minimum alert level for the security cyborg model to be chosen
+## 0: Green, 1:Blue, 2:Amber, 3:Red, 4:Delta
+MINIMUM_SECBORG_ALERT 3
+
## Peacekeeper Borg ###
## Uncomment to prevent the peacekeeper cyborg module from being chosen
#DISABLE_PEACEBORG
diff --git a/config/maps.txt b/config/maps.txt
index 99a4543853..87e86a0800 100644
--- a/config/maps.txt
+++ b/config/maps.txt
@@ -10,6 +10,8 @@ Format:
maxplayers [number] (0 or less disables this requirement)
default (The last map with this defined will get all votes of players who have not explicitly voted for a map)
voteweight [number] (How much to count each player vote as, defaults to 1, setting to 0.5 counts each vote as half a vote, 2 as double, etc, Setting to 0 disables the map but allows players to still pick it)
+ max_round_search_span [number] (If this is nonzero, then if this map has been played more than a specified amount of times within this number of rounds, the map won't show up in votes. Max for this value determined by a define in persistence.dm)
+ max_rounds_played [number] (This determines how many times a map can be played within the above number of rounds before it's forbidden from votes.)
disabled (disables the map)
endmap
diff --git a/config/spaceRuinBlacklist.txt b/config/spaceRuinBlacklist.txt
index deafa47969..4ea7611937 100644
--- a/config/spaceRuinBlacklist.txt
+++ b/config/spaceRuinBlacklist.txt
@@ -27,6 +27,7 @@
#_maps/RandomRuins/SpaceRuins/emptyshell.dmm
#_maps/RandomRuins/SpaceRuins/gasthelizards.dmm
#_maps/RandomRuins/SpaceRuins/gondolaasteroid.dmm
+#_maps/RandomRuins/SpaceRuins/hilbertshoteltestingsite.dmm
#_maps/RandomRuins/SpaceRuins/intactemptyship.dmm
#_maps/RandomRuins/SpaceRuins/listeningstation.dmm
#_maps/RandomRuins/SpaceRuins/mechtransport.dmm
diff --git a/goon/browserassets/css/browserOutput.css b/goon/browserassets/css/browserOutput.css
deleted file mode 100644
index 58129ac1cb..0000000000
--- a/goon/browserassets/css/browserOutput.css
+++ /dev/null
@@ -1,876 +0,0 @@
-/*****************************************
-*
-* GLOBAL STYLES
-*
-******************************************/
-html, body {
- padding: 0;
- margin: 0;
- height: 100%;
- color: #000000;
-}
-body {
- background: #E0E0E0; /*CIT CHANGE - darkens chatbox a lil*/
- font-family: Verdana, sans-serif;
- font-size: 9pt;
- line-height: 1.2;
- overflow-x: hidden;
- overflow-y: scroll;
- word-wrap: break-word;
-}
-
-em {
- font-style: normal;
- font-weight: bold;
-}
-
-img {
- margin: 0;
- padding: 0;
- line-height: 1;
- -ms-interpolation-mode: nearest-neighbor;
- image-rendering: pixelated;
-}
-img.icon {
- height: 1em;
- min-height: 16px;
- width: auto;
- vertical-align: bottom;
-}
-
-
-.r:before { /* "repeated" badge class for combined messages */
- content: 'x';
-}
-.r {
- display: inline-block;
- min-width: 0.5em;
- font-size: 0.7em;
- padding: 0.2em 0.3em;
- line-height: 1;
- color: white;
- text-align: center;
- white-space: nowrap;
- vertical-align: middle;
- background-color: crimson;
- border-radius: 10px;
-}
-
-a {color: #0000ff;}
-a.visited {color: #ff00ff;}
-a:visited {color: #ff00ff;}
-a.popt {text-decoration: none;}
-
-/*****************************************
-*
-* OUTPUT NOT RELATED TO ACTUAL MESSAGES
-*
-******************************************/
-#loading {
- position: fixed;
- width: 300px;
- height: 150px;
- text-align: center;
- left: 50%;
- top: 50%;
- margin: -75px 0 0 -150px;
-}
-#loading i {display: block; padding-bottom: 3px;}
-
-#messages {
- font-size: 13px;
- padding: 3px;
- margin: 0;
- word-wrap: break-word;
-}
-#newMessages {
- position: fixed;
- display: block;
- bottom: 0;
- right: 0;
- padding: 8px;
- background: #ddd;
- text-decoration: none;
- font-variant: small-caps;
- font-size: 1.1em;
- font-weight: bold;
- color: #333;
-}
-#newMessages:hover {background: #ccc;}
-#newMessages i {vertical-align: middle; padding-left: 3px;}
-#ping {
- position: fixed;
- top: 0;
- right: 80px;
- width: 45px;
- background: #ddd;
- height: 30px;
- padding: 8px 0 2px 0;
-}
-#ping i {display: block; text-align: center;}
-#ping .ms {
- display: block;
- text-align: center;
- font-size: 8pt;
- padding-top: 2px;
-}
-#userBar {
- position: fixed;
- top: 0;
- right: 0;
-}
-#userBar .subCell {
- background: #ddd;
- height: 30px;
- padding: 5px 0;
- display: block;
- color: #333;
- text-decoration: none;
- line-height: 28px;
- border-top: 1px solid #b4b4b4;
-}
-#userBar .subCell:hover {background: #ccc;}
-#userBar .toggle {
- width: 40px;
- background: #ccc;
- border-top: 0;
- float: right;
- text-align: center;
-}
-#userBar .sub {clear: both; display: none; width: 160px;}
-#userBar .sub.scroll {overflow-y: scroll;}
-#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;}
-#userBar .sub span {
- display: block;
- line-height: 30px;
- float: left;
-}
-#userBar .sub i {
- display: block;
- padding: 0 5px;
- font-size: 1.1em;
- width: 22px;
- text-align: center;
- line-height: 30px;
- float: right;
-}
-#userBar .sub input {
- position: absolute;
- padding: 7px 5px;
- width: 121px;
- line-height: 30px;
- float: left;
-}
-#userBar .topCell {border-top: 0;}
-
-/* POPUPS */
-.popup {
- position: fixed;
- top: 50%;
- left: 50%;
- background: #ddd;
-}
-.popup .close {
- position: absolute;
- background: #aaa;
- top: 0;
- right: 0;
- color: #333;
- text-decoration: none;
- z-index: 2;
- padding: 0 10px;
- height: 30px;
- line-height: 30px;
-}
-.popup .close:hover {background: #999;}
-.popup .head {
- background: #999;
- color: #ddd;
- padding: 0 10px;
- height: 30px;
- line-height: 30px;
- text-transform: uppercase;
- font-size: 0.9em;
- font-weight: bold;
- border-bottom: 2px solid green;
-}
-.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;}
-.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;}
-.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;}
-.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;}
-
-.changeFont {padding: 10px;}
-.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;}
-.changeFont a:hover {background: #ccc;}
-
-.highlightPopup {padding: 10px; text-align: center;}
-.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;}
-.highlightPopup input.highlightColor {background-color: #FFFF00;}
-.highlightPopup input.highlightTermSubmit {margin-top: 5px;}
-
-/* ADMIN CONTEXT MENU */
-.contextMenu {
- background-color: #ddd;
- position: fixed;
- margin: 2px;
- width: 150px;
-}
-.contextMenu a {
- display: block;
- padding: 2px 5px;
- text-decoration: none;
- color: #333;
-}
-
-.contextMenu a:hover {
- background-color: #ccc;
-}
-
-/* ADMIN FILTER MESSAGES MENU */
-.filterMessages {padding: 5px;}
-.filterMessages div {padding: 2px 0;}
-.filterMessages input {}
-.filterMessages label {}
-
-.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;}
-
-
-/*****************************************
-*
-* OUTPUT ACTUALLY RELATED TO MESSAGES
-*
-******************************************/
-
-/* MOTD */
-.motd {color: #638500; font-family: Verdana, sans-serif;}
-.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;}
-.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;}
-
-/* ADD HERE FOR BOLD */
-.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;}
-
-/* ADD HERE FOR ITALIC */
-.italic, .italics, .emote {font-style: italic;}
-
-/* OUTPUT COLORS */
-.highlight {background: yellow;}
-
-h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;}
-h1.alert, h2.alert {color: #000000;}
-
-em {font-style: normal; font-weight: bold;}
-
-.ooc { font-weight: bold;}
-.adminobserverooc {color: #0099cc; font-weight: bold;}
-.adminooc {color: #700038; font-weight: bold;}
-
-.adminobserver {color: #996600; font-weight: bold;}
-.admin {color: #386aff; font-weight: bold;}
-
-.name { font-weight: bold;}
-
-.say {}
-.deadsay {color: #5c00e6;}
-.binarysay {color: #20c20e; background-color: #000000; display: block;}
-.binarysay a {color: #00ff00;}
-.binarysay a:active, .binarysay a:visited {color: #88ff88;}
-.radio {color: #008000;}
-.sciradio {color: #993399;}
-.comradio {color: #948f02;}
-.secradio {color: #a30000;}
-.medradio {color: #337296;}
-.engradio {color: #fb5613;}
-.suppradio {color: #a8732b;}
-.servradio {color: #6eaa2c;}
-.syndradio {color: #6d3f40;}
-.centcomradio {color: #686868;}
-.aiprivradio {color: #ff00ff;}
-.redteamradio {color: #ff0000;}
-.blueteamradio {color: #0000ff;}
-
-.yell { font-weight: bold;}
-
-.alert {color: #ff0000;}
-h1.alert, h2.alert {color: #000000;}
-
-.emote { font-style: italic;}
-.selecteddna {color: #ffffff; background-color: #001B1B}
-
-.attack {color: #ff0000;}
-.disarm {color: #990000;}
-.passive {color: #660000;}
-
-.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;}
-.danger {color: #ff0000;}
-.warning {color: #ff0000; font-style: italic;}
-.boldwarning {color: #ff0000; font-style: italic; font-weight: bold}
-.announce {color: #228b22; font-weight: bold;}
-.boldannounce {color: #ff0000; font-weight: bold;}
-.greenannounce {color: #00ff00; font-weight: bold;}
-.rose {color: #ff5050;}
-.info {color: #0000CC;}
-.notice {color: #000099;}
-.boldnotice {color: #000099; font-weight: bold;}
-.adminnotice {color: #0000ff;}
-.adminhelp {color: #ff0000; font-weight: bold;}
-.unconscious {color: #0000ff; font-weight: bold;}
-.suicide {color: #ff5050; font-style: italic;}
-.green {color: #03ff39;}
-.nicegreen {color: #14a833;}
-.shadowling {color: #3b2769;}
-.cult {color: #960000;}
-
-.cultitalic {color: #960000; font-style: italic;}
-.cultbold {color: #960000; font-style: italic; font-weight: bold;}
-.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;}
-
-.cultlarge {color: #960000; font-weight: bold; font-size: 24px;}
-.narsie {color: #960000; font-weight: bold; font-size: 120px;}
-.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;}
-.colossus {color: #7F282A; font-size: 40px;}
-.hierophant {color: #660099; font-weight: bold; font-style: italic;}
-.hierophant_warning {color: #660099; font-style: italic;}
-.purple {color: #5e2d79;}
-.holoparasite {color: #35333a;}
-
-.revennotice {color: #1d2953;}
-.revenboldnotice {color: #1d2953; font-weight: bold;}
-.revenbignotice {color: #1d2953; font-weight: bold; font-size: 24px;}
-.revenminor {color: #823abb}
-.revenwarning {color: #760fbb; font-style: italic;}
-.revendanger {color: #760fbb; font-weight: bold; font-size: 24px;}
-.umbra {color: #5000A0;}
-.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;}
-.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;}
-
-.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;}
-
-.brass {color: #BE8700;}
-.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;}
-.large_brass {color: #BE8700; font-size: 24px;}
-.big_brass {color: #BE8700; font-size: 24px; font-weight: bold; font-style: italic;}
-.ratvar {color: #BE8700; font-size: 48px; font-weight: bold; font-style: italic;}
-.alloy {color: #42474D;}
-.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;}
-.nezbere_large {color: #42474D; font-size: 24px; font-weight: bold; font-style: italic;}
-.nezbere {color: #42474D; font-weight: bold; font-style: italic;}
-.nezbere_small {color: #42474D;}
-.sevtug_large {color: #AF0AAF; font-size: 24px; font-weight: bold; font-style: italic;}
-.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;}
-.sevtug_small {color: #AF0AAF;}
-.inathneq_large {color: #1E8CE1; font-size: 24px; font-weight: bold; font-style: italic;}
-.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;}
-.inathneq_small {color: #1E8CE1;}
-.nzcrentr_large {color: #DAAA18; font-size: 24px; font-weight: bold; font-style: italic;}
-.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;}
-.nzcrentr_small {color: #DAAA18;}
-.neovgre_large {color: #6E001A; font-size: 24px; font-weight: bold; font-style: italic;}
-.neovgre {color: #6E001A; font-weight: bold; font-style: italic;}
-.neovgre_small {color: #6E001A;}
-
-.newscaster {color: #800000;}
-.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;}
-
-.alien {color: #543354;}
-.noticealien {color: #00c000;}
-.alertalien {color: #00c000; font-weight: bold;}
-.changeling {color: #800080; font-style: italic;}
-
-.spider {color: #4d004d;}
-
-.interface {color: #330033;}
-
-.sans {font-family: "Comic Sans MS", cursive, sans-serif;}
-.papyrus {font-family: "Papyrus", cursive, sans-serif;}
-.robot {font-family: "Courier New", cursive, sans-serif;}
-
-.command_headset {font-weight: bold; font-size: 24px;}
-.small {font-size: 8px;}
-.big {font-size: 24px;}
-.reallybig {font-size: 32px;}
-.extremelybig {font-size: 40px;}
-.greentext {color: #00FF00; font-size: 24px;}
-.redtext {color: #FF0000; font-size: 24px;}
-.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
-.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
-.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;}
-@keyframes velvet {
- 0% { color: #400020; }
- 40% { color: #FF0000; }
- 50% { color: #FF8888; }
- 60% { color: #FF0000; }
- 100% { color: #400020; }
-}
-
-.hypnophrase {color: #202020; font-weight: bold; animation: hypnocolor 1500ms infinite;}
-@keyframes hypnocolor {
- 0% { color: #202020; }
- 25% { color: #4b02ac; }
- 50% { color: #9f41f1; }
- 75% { color: #541c9c; }
- 100% { color: #7adbf3; }
-}
-
-.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;}
-@keyframes phobia {
- 0% { color: #f75a5a; }
- 50% { color: #dd0000; }
- 100% { color: #f75a5a; }
-}
-
-.icon {height: 1em; width: auto;}
-
-.memo {color: #638500; text-align: center;}
-.memoedit {text-align: center; font-size: 16px;}
-.abductor {color: #800080; font-style: italic;}
-.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;}
-.slime {color: #00CED1;}
-.drone {color: #848482;}
-.monkey {color: #975032;}
-.swarmer {color: #2C75FF;}
-.resonate {color: #298F85;}
-
-.monkeyhive {color: #774704;}
-.monkeylead {color: #774704; font-size: 2;}
-
-.connectionClosed, .fatalError {background: red; color: white; padding: 5px;}
-.connectionClosed.restored {background: green;}
-.internal.boldnshit {color: blue; font-weight: bold;}
-
-/* HELPER CLASSES */
-.text-normal {font-weight: normal; font-style: normal;}
-.hidden {display: none; visibility: hidden;}/*****************************************
-*
-* GLOBAL STYLES
-*
-******************************************/
-html, body {
- padding: 0;
- margin: 0;
- height: 100%;
- color: #000000;
-}
-body {
- background: #E0E0E0; /*CIT CHANGE - darkens chatbox a lil*/
- font-family: Verdana, sans-serif;
- font-size: 9pt;
- line-height: 1.2;
- overflow-x: hidden;
- overflow-y: scroll;
- word-wrap: break-word;
-}
-
-em {
- font-style: normal;
- font-weight: bold;
-}
-
-img {
- margin: 0;
- padding: 0;
- line-height: 1;
- -ms-interpolation-mode: nearest-neighbor;
- image-rendering: pixelated;
-}
-img.icon {
- height: 1em;
- min-height: 16px;
- width: auto;
- vertical-align: bottom;
-}
-
-
-.r:before { /* "repeated" badge class for combined messages */
- content: 'x';
-}
-.r {
- display: inline-block;
- min-width: 0.5em;
- font-size: 0.7em;
- padding: 0.2em 0.3em;
- line-height: 1;
- color: white;
- text-align: center;
- white-space: nowrap;
- vertical-align: middle;
- background-color: crimson;
- border-radius: 10px;
-}
-
-a {color: #0000ff;}
-a.visited {color: #ff00ff;}
-a:visited {color: #ff00ff;}
-a.popt {text-decoration: none;}
-
-/*****************************************
-*
-* OUTPUT NOT RELATED TO ACTUAL MESSAGES
-*
-******************************************/
-#loading {
- position: fixed;
- width: 300px;
- height: 150px;
- text-align: center;
- left: 50%;
- top: 50%;
- margin: -75px 0 0 -150px;
-}
-#loading i {display: block; padding-bottom: 3px;}
-
-#messages {
- font-size: 13px;
- padding: 3px;
- margin: 0;
- word-wrap: break-word;
-}
-#newMessages {
- position: fixed;
- display: block;
- bottom: 0;
- right: 0;
- padding: 8px;
- background: #ddd;
- text-decoration: none;
- font-variant: small-caps;
- font-size: 1.1em;
- font-weight: bold;
- color: #333;
-}
-#newMessages:hover {background: #ccc;}
-#newMessages i {vertical-align: middle; padding-left: 3px;}
-#ping {
- position: fixed;
- top: 0;
- right: 80px;
- width: 45px;
- background: #ddd;
- height: 30px;
- padding: 8px 0 2px 0;
-}
-#ping i {display: block; text-align: center;}
-#ping .ms {
- display: block;
- text-align: center;
- font-size: 8pt;
- padding-top: 2px;
-}
-#userBar {
- position: fixed;
- top: 0;
- right: 0;
-}
-#userBar .subCell {
- background: #ddd;
- height: 30px;
- padding: 5px 0;
- display: block;
- color: #333;
- text-decoration: none;
- line-height: 28px;
- border-top: 1px solid #b4b4b4;
-}
-#userBar .subCell:hover {background: #ccc;}
-#userBar .toggle {
- width: 40px;
- background: #ccc;
- border-top: 0;
- float: right;
- text-align: center;
-}
-#userBar .sub {clear: both; display: none; width: 160px;}
-#userBar .sub.scroll {overflow-y: scroll;}
-#userBar .sub.subCell {padding: 3px 0 3px 8px; line-height: 30px; font-size: 0.9em; clear: both;}
-#userBar .sub span {
- display: block;
- line-height: 30px;
- float: left;
-}
-#userBar .sub i {
- display: block;
- padding: 0 5px;
- font-size: 1.1em;
- width: 22px;
- text-align: center;
- line-height: 30px;
- float: right;
-}
-#userBar .sub input {
- position: absolute;
- padding: 7px 5px;
- width: 121px;
- line-height: 30px;
- float: left;
-}
-#userBar .topCell {border-top: 0;}
-
-/* POPUPS */
-.popup {
- position: fixed;
- top: 50%;
- left: 50%;
- background: #ddd;
-}
-.popup .close {
- position: absolute;
- background: #aaa;
- top: 0;
- right: 0;
- color: #333;
- text-decoration: none;
- z-index: 2;
- padding: 0 10px;
- height: 30px;
- line-height: 30px;
-}
-.popup .close:hover {background: #999;}
-.popup .head {
- background: #999;
- color: #ddd;
- padding: 0 10px;
- height: 30px;
- line-height: 30px;
- text-transform: uppercase;
- font-size: 0.9em;
- font-weight: bold;
- border-bottom: 2px solid green;
-}
-.popup input {border: 1px solid #999; background: #fff; margin: 0; padding: 5px; outline: none; color: #333;}
-.popup input[type=text]:hover, .popup input[type=text]:active, .popup input[type=text]:focus {border-color: green;}
-.popup input[type=submit] {padding: 5px 10px; background: #999; color: #ddd; text-transform: uppercase; font-size: 0.9em; font-weight: bold;}
-.popup input[type=submit]:hover, .popup input[type=submit]:focus, .popup input[type=submit]:active {background: #aaa; cursor: pointer;}
-
-.changeFont {padding: 10px;}
-.changeFont a {display: block; text-decoration: none; padding: 3px; color: #333;}
-.changeFont a:hover {background: #ccc;}
-
-.highlightPopup {padding: 10px; text-align: center;}
-.highlightPopup input[type=text] {display: block; width: 215px; text-align: left; margin-top: 5px;}
-.highlightPopup input.highlightColor {background-color: #FFFF00;}
-.highlightPopup input.highlightTermSubmit {margin-top: 5px;}
-
-/* ADMIN CONTEXT MENU */
-.contextMenu {
- background-color: #ddd;
- position: fixed;
- margin: 2px;
- width: 150px;
-}
-.contextMenu a {
- display: block;
- padding: 2px 5px;
- text-decoration: none;
- color: #333;
-}
-
-.contextMenu a:hover {
- background-color: #ccc;
-}
-
-/* ADMIN FILTER MESSAGES MENU */
-.filterMessages {padding: 5px;}
-.filterMessages div {padding: 2px 0;}
-.filterMessages input {}
-.filterMessages label {}
-
-.icon-stack {height: 1em; line-height: 1em; width: 1em; vertical-align: middle; margin-top: -2px;}
-
-
-/*****************************************
-*
-* OUTPUT ACTUALLY RELATED TO MESSAGES
-*
-******************************************/
-
-/* MOTD */
-.motd {color: #638500; font-family: Verdana, sans-serif;}
-.motd h1, .motd h2, .motd h3, .motd h4, .motd h5, .motd h6 {color: #638500; text-decoration: underline;}
-.motd a, .motd a:link, .motd a:visited, .motd a:active, .motd a:hover {color: #638500;}
-
-/* ADD HERE FOR BOLD */
-.bold, .name, .prefix, .ooc, .looc, .adminooc, .admin, .medal, .yell {font-weight: bold;}
-
-/* ADD HERE FOR ITALIC */
-.italic, .italics, .emote {font-style: italic;}
-
-/* OUTPUT COLORS */
-.highlight {background: yellow;}
-
-h1, h2, h3, h4, h5, h6 {color: #0000ff;font-family: Georgia, Verdana, sans-serif;}
-h1.alert, h2.alert {color: #000000;}
-
-em {font-style: normal; font-weight: bold;}
-
-.ooc { font-weight: bold;}
-.adminobserverooc {color: #0099cc; font-weight: bold;}
-.adminooc {color: #700038; font-weight: bold;}
-
-.adminsay {color: #FF4500; font-weight: bold;}
-.admin {color: #386aff; font-weight: bold;}
-
-.name { font-weight: bold;}
-
-.say {}
-.deadsay {color: #5c00e6;}
-.binarysay {color: #20c20e; background-color: #000000; display: block;}
-.binarysay a {color: #00ff00;}
-.binarysay a:active, .binarysay a:visited {color: #88ff88;}
-.radio {color: #008000;}
-.sciradio {color: #993399;}
-.comradio {color: #948f02;}
-.secradio {color: #a30000;}
-.medradio {color: #337296;}
-.engradio {color: #fb5613;}
-.suppradio {color: #a8732b;}
-.servradio {color: #6eaa2c;}
-.syndradio {color: #6d3f40;}
-.centcomradio {color: #686868;}
-.aiprivradio {color: #ff00ff;}
-.redteamradio {color: #ff0000;}
-.blueteamradio {color: #0000ff;}
-
-.yell { font-weight: bold;}
-
-.alert {color: #ff0000;}
-h1.alert, h2.alert {color: #000000;}
-
-.emote { font-style: italic;}
-.selecteddna {color: #ffffff; background-color: #001B1B}
-
-.attack {color: #ff0000;}
-.disarm {color: #990000;}
-.passive {color: #660000;}
-
-.userdanger {color: #ff0000; font-weight: bold; font-size: 24px;}
-.danger {color: #ff0000;}
-.warning {color: #ff0000; font-style: italic;}
-.boldwarning {color: #ff0000; font-style: italic; font-weight: bold}
-.announce {color: #228b22; font-weight: bold;}
-.boldannounce {color: #ff0000; font-weight: bold;}
-.greenannounce {color: #00ff00; font-weight: bold;}
-.rose {color: #ff5050;}
-.info {color: #0000CC;}
-.notice {color: #000099;}
-.boldnotice {color: #000099; font-weight: bold;}
-.adminnotice {color: #0000ff;}
-.adminhelp {color: #ff0000; font-weight: bold;}
-.unconscious {color: #0000ff; font-weight: bold;}
-.suicide {color: #ff5050; font-style: italic;}
-.green {color: #03ff39;}
-.nicegreen {color: #14a833;}
-.userlove {color: #FF1493; font-style: italic; font-weight: bold; text-shadow: 0 0 6px #ff6dbc;}
-.love {color: #ff006a; font-style: italic; text-shadow: 0 0 6px #ff6d6d;}
-.shadowling {color: #3b2769;}
-.cult {color: #960000;}
-
-.cultitalic {color: #960000; font-style: italic;}
-.cultbold {color: #960000; font-style: italic; font-weight: bold;}
-.cultboldtalic {color: #960000; font-weight: bold; font-size: 24px;}
-
-.cultlarge {color: #960000; font-weight: bold; font-size: 24px;}
-.narsie {color: #960000; font-weight: bold; font-size: 120px;}
-.narsiesmall {color: #960000; font-weight: bold; font-size: 48px;}
-.colossus {color: #7F282A; font-size: 40px;}
-.hierophant {color: #660099; font-weight: bold; font-style: italic;}
-.hierophant_warning {color: #660099; font-style: italic;}
-.purple {color: #5e2d79;}
-.holoparasite {color: #35333a;}
-
-.revennotice {color: #1d2953;}
-.revenboldnotice {color: #1d2953; font-weight: bold;}
-.revenbignotice {color: #1d2953; font-weight: bold; font-size: 24px;}
-.revenminor {color: #823abb}
-.revenwarning {color: #760fbb; font-style: italic;}
-.revendanger {color: #760fbb; font-weight: bold; font-size: 24px;}
-.umbra {color: #5000A0;}
-.umbra_emphasis {color: #5000A0; font-weight: bold; font-style: italic;}
-.umbra_large {color: #5000A0; font-size: 24px; font-weight: bold; font-style: italic;}
-
-.deconversion_message {color: #5000A0; font-size: 24px; font-style: italic;}
-
-.brass {color: #BE8700;}
-.heavy_brass {color: #BE8700; font-weight: bold; font-style: italic;}
-.large_brass {color: #BE8700; font-size: 24px;}
-.big_brass {color: #BE8700; font-size: 24px; font-weight: bold; font-style: italic;}
-.ratvar {color: #BE8700; font-size: 48px; font-weight: bold; font-style: italic;}
-.alloy {color: #42474D;}
-.heavy_alloy {color: #42474D; font-weight: bold; font-style: italic;}
-.nezbere_large {color: #42474D; font-size: 24px; font-weight: bold; font-style: italic;}
-.nezbere {color: #42474D; font-weight: bold; font-style: italic;}
-.nezbere_small {color: #42474D;}
-.sevtug_large {color: #AF0AAF; font-size: 24px; font-weight: bold; font-style: italic;}
-.sevtug {color: #AF0AAF; font-weight: bold; font-style: italic;}
-.sevtug_small {color: #AF0AAF;}
-.inathneq_large {color: #1E8CE1; font-size: 24px; font-weight: bold; font-style: italic;}
-.inathneq {color: #1E8CE1; font-weight: bold; font-style: italic;}
-.inathneq_small {color: #1E8CE1;}
-.nzcrentr_large {color: #DAAA18; font-size: 24px; font-weight: bold; font-style: italic;}
-.nzcrentr {color: #DAAA18; font-weight: bold; font-style: italic;}
-.nzcrentr_small {color: #DAAA18;}
-.neovgre_large {color: #6E001A; font-size: 24px; font-weight: bold; font-style: italic;}
-.neovgre {color: #6E001A; font-weight: bold; font-style: italic;}
-.neovgre_small {color: #6E001A;}
-
-.newscaster {color: #800000;}
-.ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;}
-
-.alien {color: #543354;}
-.noticealien {color: #00c000;}
-.alertalien {color: #00c000; font-weight: bold;}
-.changeling {color: #800080; font-style: italic;}
-
-.spider {color: #4d004d;}
-
-.interface {color: #330033;}
-
-.sans {font-family: "Comic Sans MS", cursive, sans-serif;}
-.papyrus {font-family: "Papyrus", cursive, sans-serif;}
-.robot {font-family: "Courier New", cursive, sans-serif;}
-
-.command_headset {font-weight: bold; font-size: 24px;}
-.small {font-size: 8px;}
-.big {font-size: 24px;}
-.reallybig {font-size: 32px;}
-.extremelybig {font-size: 40px;}
-.greentext {color: #00FF00; font-size: 24px;}
-.redtext {color: #FF0000; font-size: 24px;}
-.clown {color: #FF69Bf; font-size: 24px; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
-.hypnophrase {color: #202020; font-weight: bold; animation: hypnocolor 1500ms infinite;}
-@keyframes hypnocolor {
- 0% { color: #202020; }
- 25% { color: #4b02ac; }
- 50% { color: #9f41f1; }
- 75% { color: #541c9c; }
- 100% { color: #7adbf3; }
-}
-
-.phobia {color: #dd0000; font-weight: bold; animation: phobia 750ms infinite;}
-@keyframes phobia {
- 0% { color: #f75a5a; }
- 50% { color: #dd0000; }
- 100% { color: #f75a5a; }
-}
-.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
-
-.icon {height: 1em; width: auto;}
-
-.memo {color: #638500; text-align: center;}
-.memoedit {text-align: center; font-size: 16px;}
-.abductor {color: #800080; font-style: italic;}
-.mind_control {color: #A00D6F; font-size: 3; font-weight: bold; font-style: italic;}
-.slime {color: #00CED1;}
-.drone {color: #848482;}
-.monkey {color: #975032;}
-.swarmer {color: #2C75FF;}
-.resonate {color: #298F85;}
-
-.monkeyhive {color: #774704;}
-.monkeylead {color: #774704; font-size: 2;}
-
-.connectionClosed, .fatalError {background: red; color: white; padding: 5px;}
-.connectionClosed.restored {background: green;}
-.internal.boldnshit {color: blue; font-weight: bold;}
-
-/* HELPER CLASSES */
-.text-normal {font-weight: normal; font-style: normal;}
-.hidden {display: none; visibility: hidden;}
diff --git a/html/changelog.html b/html/changelog.html
index 31935bd1c1..61bc43a99b 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -35,15 +35,15 @@
- Current Project Maintainers: deathride58, LetterJay, kevinz000
+ Current Project Maintainers: deathride58, LetterJay, kevinz000, BlackMajor, Izzy
Currently Active GitHub contributor list: -Click Here-
- Coders: Poojawa, deathride58, kevinz000, Trilbyspaceclone, nik707, as well as the /tg/ crew.
+ Coders: Fermis, Poojawa, deathride58, kevinz000, Trilbyspaceclone, nik707, Ghommie as well as the /tg/ crew.
Spriters: Michiyamenotehifunana, CameronWoof, and the folks who contributed to /tg/ station project.
Sounds: /tg/ Sound crew.
Main Testers: You poor saps, our player base.
Thanks to: /tg/station, Baystation 12, /vg/station, NTstation, CDK Station devs, FacepunchStation, GoonStation devs, the original SpaceStation developers and Invisty for the title image. Also a thanks to anybody who has contributed who is not listed here :( Ask to be added here on irc.
Have a bug to report? Visit our Issue Tracker .
- Please ensure that the bug has not already been reported upstream and use the template provided here! .
+ Please ensure that the bug has not already been reported upstream and use the template provided here! .
@@ -56,1487 +56,2065 @@
-->
-
27 September 2018
-
Alexch2 updated:
+
04 November 2019
+
4dplanner, MMiracles updated:
- Fixes tons of typos related to integrated circuits.
- Re-writes the descriptions of a few parts of integrated circuits.
+ Wizard shapeshift now converts damage taken while transformed
+ transform spell transfers damage correctly instead of healing most of the time
+ 0% simplemob health maps to 0 carbon health, 100% simplemob to 100% carbon
+ transforming to a form with brute resistance no longer heals you
+ transforming back to a species with brute resistance no longer heals you
-
Armhulen code, Keekenox sprites and S_____ as the ideas guy :roll_eyes: updated:
+
AdmiralPancakes1 updated:
- New drinks: Peppermint Patty and the Candyland Extract!!
+ Cryo cell shortcuts: alt-click toggles the doors, ctrl-click toggles the power
-
Astatineguy12 updated:
+
Alonefromhell updated:
- The experimentor is less likely to produce food when it transforms an item
- The experimentor no longer breaks when the toxic waste malfunction occurs multiple times and isn't cleaned up
- The experimentor irridiate function actually chooses what item to make properly rather than picking from the start of the list
- The mime blockade spell now shows up under the right tab
+ Ported Oracle UI, a framework for self-updating and neat UI's
+ Paper now uses OUI
+ Bins now use OUI
+ fixes tootip offset
-
Beachsprites updated:
+
AnalWerewolf updated:
- added directional beach sprites
+ Fritz plushie
+ Donor item
-
Big Tobacco updated:
+
Anonymous updated:
- Cheap lighters now come in four different shapes and Zippos can have one of four different designs, collect them all and improve our sales!
- All existing lighter sprites have been given a face-lift and the flames are now subtly animated.
- Cheap lighters now use a fixed list of 16 colors to pick from instead of using totally randomized colors.
- Cigar cases have been tweaked to be a bit smaller and to have a modified design.
- Cohiba Robusto and Havanan cigars now use separate case sprites from the generic premium cigar cases.
+ More crusader armor variants to pick from armament: Teutonic and Hospitaller.
+
+
Arturlang updated:
+
+ You can now use CTRL and ALT click on pumps and filters to toggle them on and off and max their output respectively
+ You can now use RPDs on windows and grilles.
+ The RD can now suplex a immovable rod. Good fucking luck.
+ Fixes high alert ERT suit sprites. You can see them now!
+ Traitor codewords are now highlighted for traitors.
+ You can now examine pumps filters and mixers to see if you can use CTRL and Alt click on them.
+ Fixes brain damage/trauma healing nanites so they actually work while there are only traumas.
+ Advanced toxin filtration nanites now heal slimes
+
+
Bhijn updated:
+
+ It's now possible to forcefully eject the occupants of a dogborg's sleeper by using a crowbar on them. This action is instant.
+ Resist values for dogborg sleepers have been adjusted. The baseline has been decreased from 30 seconds to 15 seconds. Medihound sleepers have a resist timer of 3 seconds. Sechound sleepers retain a resist timer of 30 seconds.
+ It now takes 10 full seconds to insert people into your sleeper. This should hopefully give people some more room to breathe and react to a dogborg attempting to sleeper someone either for no reason or in a way that violates law 2.
+ Warp whistles no longer grant permanent invulnerability and invisibility
+ You can now actually use the resist hotkey to resist out of handcuffs. Woah, revolutionary
+ the `!tgs poly` command now actually works
+ Poly now has a 0.01% chance per squawk to speak through the TGS relay.
+ The point production mode of radiation collectors has been reverted to the original behavior of using all of the stored power every process cycle instead of just 4% of it
+ Radiation collectors now display the amount of power/research points they're producing per minute rather than per process cycle, which should hopefully clear up a lot of confusion.
+ Radiation collectors also display what's happening to the gas within them, which should make it a lot more obvious as to how you get tritium.
+ Security borgs and K9s are now only available during red alert or higher.
+ Headmins or other folks with access to the server's config can choose the minimum alert level for secborgs to be chosen via the MINIMUM_SECBORG_ALERT config option. See the default game_options.txt for more info.
+ The server no longer attempts to check if the CID matches the IP of any bans, or if the IP matches any CIDs of any active bans, during client analyzation
+ Vampires can now only ventcrawl in bat form if their blood level is below the bad blood volume (224 blood total)
+ Vampires now only take 5 burn per mob life cycle while within chapel areas, down from the original 20 burn per life cycle.
+ K9 pounces have received a minor rework. It now has an effective cooldown of 2.5 seconds, can now only deal up to 120 staminaloss, deals a maximum of 80 stamloss on hit, has a spoolup of half a second, and now has telegraphing in the form of a quiet noise.
+ K9s now only have 80 health
+ Secborgs (but not k9s) now have a hybrid taser. This can be toggled via server config.
+ The disabler cooler upgrade now applies to all energy-based firearms for borgs
+ Dogborg jaws are now capable of incapacitating targets if using help intent. This deals a hard stun depending on how much staminaloss the target has, and whether or not they're resting. This behavior can be toggled via server config.
+ K9 jaws now have 15 force, up from their nerfed 10 force.
+ Borg flashes regained their ability to cause knockdown. This can be toggled via server config.
+ The WEAKEN_SECBORG config option will disable the new dogborg jaws mechanic and make secborgs spawn with a standard disabler.
+ The DISABLE_BORG_FLASH_KNOCKDOWN will disable the ability for borg flashes to knockdown.
+ Jukeboxes now have 6 audio channels available to them, up from the previous accidental 2 and previously intended 5 channels.
+ Jukeboxes now work again on clients running versions higher than 512.1459.
+ People will no longer have their ears consumed by an eldritch god if multiple jukeboxes are active and the first jukebox in the jukebox list stops playing, then tries to play again
+ Instead of the debug text for invalid jukebox behavior being printed to world, the debug text is now restricted to the runtime panel.
+
+
BurgerB updated:
+
+ Tweaked the UI of the loadout to be less cluttered due to an issue with formatting.
+
+
BurgerBB updated:
+
+ Adds the bonermeter; a device that measures arousal based statistics.
+ Added a new input to the electrostimulator that controls the strength of the shock. It accepts negative inputs which reduce arousal. Added a new output to the electrostimulator that displays the amount of arousal gained.
+ Rebalanced the electro-stimulator to be less spammy by giving it a 2.5 second enforced cooldown per circuit contraption. Increased the complexity of electro stimulator from 10 to 15.
+ Reworked the Vent Clog event to spray smoke instead of foam, also made it shoot smoke over time instead through each vent instead of all at once.
+ Increased the spawn area of the City of Cogs (Reebe). This does not affect the area in which builders can build.
+ Significantly tweaks the Wizard race transformation event to be less unreasonably troublesome.
+ Adds a new 0 cost trait that makes you immune* to Crocin and Hexacrocin
+ Tweaks how slurring works so it's more of a gradual change into slurring instead of immediate.
+ Slurring is now directly proportional to your drunkenness, with other sources of slur being added on top of it.
+ Bras are now separate from underwear, meaning you can mix and match bras if you're into that.
+ Men can wear female accessory clothing, and females can wear men accessory clothing. It's not a fetish, mom, it's PROGRESSIVE.
+ Reorganized accessories into their own files to prevent a massive 1000 line file.
+ i'm 10% sure that merging this PR will cause preference corruption sooooooooooo I just need to hear from @deathride58 or perhaps someone else on how much damage this could possibly do.
+ Tweaked penis.
+ Rebalanced penis.
+ Added the following reagents to the common list of vent clog reagents: ~~Cooking Oil~~, ~~Frost Oil~~, Sodium Chloride, Corn Oil, Uranium, Carpet, Firefighting Foam, semen, femcum, tear juice, strange reagent, ~~spraytan~~.
+ Vent Clog smoke emits the same transparent smoke as a smoke machine, including how much it transfers. Vent Clogs also do not trigger in areas deemed "Safe" in code, such as in the dorms or trusted areas where dangerous things shouldn't occur.
+ Adds additional random brain damage text
+ Adds penis enlargement pills.
+ Adds Stun Circuit and Pneumatic Cannon Integrated Circuits
+ Fixed extinguisher and smoke circuits not accepting any reagents.
+ Adds a few important clockcult tips.
+ Added Mech Sensors, a brass-created trap that activates when a mech not controlled by a cultist crosses it.
+ Added power nullifiers, an emp trap that emps everything in a 3x3 area, with the center suffering a heavy EMP.
+ Brass Skewers now deal 50 damage to mechs.
+ Ass slapping only works if you're actually behind the target. Ass slapping now respects disarm blocking. You can no longer face/ass slap someone on an intent other than help, unless they are also face/ass slapping.
+ Fixed ass and face slapping grammar.
+ Adds meh effects for ass and face slapping.
+ "Unwillingly" eating food now sends a warning message instead of a notice. Unable to stuff food down your throat sends a danger message instead of a warning message.
+ Adds clockwork reflectors, a fragile anti-laser reflection shield object that can be constructed for 10 brass sheets. Upon firing on the object in the direction where it is shielded, it ricochets the bullet off of it relative to the shooting angle.
+ Renames some windows in the build menu for consistency.
+ Clockwork Cult walls can no longer be deconstructed by RCDs when heated.
+ Adds several new toy loot to the arcade machine.
+ Rebalanced the arcade machine loot. Battlemachines now have a 0.5 second delay instead of a second delay between actions.
+ Fixed a bug that would not allow the one in a million pulse rifle to spawn.
+ Adds a new trait "Buns of Steel" that makes you immune to the effects of ass slapping, and temporarily makes the user's arm useless like a stun baton hit. It costs 0 points.
+ Ass slapping blowback from the Buns of Steel perk now deals 20 stamina damage instead of 50, and no brute damage.
+ Gamemode voting results are displayed at the end-round screen.
+ Cloning no longer gives you positive mutations, but a chance for a negative one. Cloning has a chance to "scramble" your visual DNA.
+ Chestbursters no longer give and remove your brain. They just disembowel and kill you now.
+ Fixes WarOps miscalculating players.
+ Activating the nuclear device during war-ops informs the crew of the nuke's position.
+ The alert level is displayed at the job selection screen.
+ Central Command informs you when a Meteor Storm is about to hit 5 to 10 minutes before it happens.
+
+
BurgerLUA updated:
+
+ Added a new framework for reagents. Reagents can now have a bool that determines if it can be detected by handheld medical analyzers. Currently only the changeling sting chemical does this.
+ Made changeling transformation string last between 10-15 minutes. Lowered the dna cost of changeling sting from 3 dna to 2 dna. Lowered the chemical cost from 50 to 10. Lowered the loudness from 2 to 1. Changeling sting transformation can be removed via high doses of calomel.
+ Fixed most reagents having a placeholder color.
+ Fixed autolathe wires not correctly shocking you when pulsed.
+ Rebalanced special jetpacks.
+
+
CalamaBanana updated:
+
+ Added Deer taur
+ Added Elf ears to mammals
CameronWoof updated:
- Quartermaster added to the list of changeling and traitor restricted jobs
+ Medihounds now have rollerbeds for non-vore patient transport
+ The closed O2 crate now uses the same color scheme as the open one
+ air alarms are green now instead of blue when the atmosphere is ideal
+ Hexacrocin overdose no longer causes climaxes
+ Altered the icons for inventory backplates. Sleek! Stylish! New!
+ Attaching a beaker that contains water to an IV stand no longer causes a visual glitch
+ Fluid-producing sexual organs no longer start full
+ Sexual organ fluid capacity decreased from 50 to 15
+ Sexual organ production rate decreased from 5u to 0.035u per two seconds.
+ Sexual fluid decals no longer contain reagents
+ Sexual fluids cannot by synthesized (e.g., by the Odysseus)
-
CitadelStationBot updated:
+
CdrCross updated:
- The faint echoes of maracas grows louder, as if a past spirit once forgotten has come back with a vengeance...
- Removing an ID card from a wallet now properly removes its visual and accesses.
- You may now take unlimited neutral and negative quirks
- the walls on the crashed abductor ship ruin in lavaland can now be broken down
- Pipe icons in the RPD now show properly in older versions of IE.
- Removing an ID from a PDA in a backpack no longer hides the ID until something else updates.
- Opening and closing airlocks repeatedly no longer stacks queued autocloses.
- Mindswapping with someone else no longer forces ambient occlusion on.
- Admin AI interaction now works properly on firelocks.
- IRV polls now use the same version of jQuery as everything else.
- You can now view your last round end report window with the "Your last round" verb in the OOC tab
- Hydroponics trays can no longer be deconstructed with their panels closed or unanchored while irrigated.
- Frames for machines which do not require being anchored can now be un/anchored after the circuit has been added.
- Fix "Your the wormhole jaunter" when a wormhole jaunter saves you from a chasm.
- Analyzers can now scan all kinds of atmospheric machinery - unary, binary, ternary, quaternary, you name it. This means stuff like gas pumps, gas mixers, vents and so forth can be analyzed.
- Analyzers now show temperature in kelvin as well as celsius.
- Analyzers now show total mole count, volume, and mole count of all gases.
- Analyzers show everything at slightly higher degrees of precision.
- Any anomaly core can now be deconstructed for a one time boost of 10k points in the deconstructive analyzer.
- Chasms no longer drop mobs buckled to undroppable mobs or objects.
- Digital valves are once again operable by silicons.
- Field generators are once again operable by adjacent cyborgs.
- Entertainment monitors now view the real Thunderdome rather than the template.
- Flipping and then rotating trinary pipe fittings no longer causes their icon to mismatch what they will become when wrenched.
- RPD tooltips for flippable trinary components have been corrected.
- The green overlay indicating where a map template will be placed is no longer invisible on space turfs.
- Frost spiders now correctly inject frost oil on bite.
- Inserting materials into protolathes with telekinesis is now possible.
- Telekinesis no longer teleports items removed from deep fryers, constructed sandbags, and leftover materials not inserted into lathes.
- Telekinetic sparkles now appear in the correct place when clicking on a turf and when clicking in the fog of war in widescreen.
- Telekinetically adjusting power tools no longer causes them to exit the universe.
- Examining a telekinetic grab in-hand will now examine the grabbed object.
- Non-harmfully placing someone who is resting on a table no longer makes them get up.
- The disco machine no longer lags the chat by spamming "You are now resting!" messages.
- Clicking on the viewport to focus it no longer leaves the input bar red.
- Running diagonally into space now properly continues the diagonal movement in zero-gravity.
- Moving diagonally past delivery chutes, transit tube pods, &c. no longer causes your camera to be stuck on them.
- The limit of monkey's spawned via monkey cubes is now configurable
- Fixes cyborgs not being able to use two-handed modules while other modules are equipped.
- Pubby's auxiliary mining base now works again.
- The overlay effects of cult flooring are now on the floor plane, fixing their odd ambient occlusion appearance.
- Cloning no longer breaks a character's connection to their family heirloom.
- Beam rifle tracers no longer fall into chasms.
- Vomiting on the same tile a second time no deletes the vomited reagents.
- fixed the clockwork helmet not dropping to ground when used by non-clock cultists
- The base machinery type is now anchored by default.
- PDA style now gets loaded correctly.
- Switching mobs into/out of a mech (by VR, ghosting, or mindswap) no longer improperly applies the mech's cursor.
- roboticists have access to R&D windoors
- switched the type of the space suit on the syndicate shuttle
- fixed hydroponics tray weed light staying on when removing weeds with integrated circuits
- Atom initialization and icon smoothing no longer race, causing late-loading mineral turfs to have no icon.
- Faceless persons no longer "melt their face off" in energy gun suicides.
- The Lightning Bolt spell now works again.
- Vehicle speed changes now happen immediately instead of on the next movement cycle
- Picture-in-picture objects now are no longer overlapped by other certain objects
- A pAI dying while in holoform no longer deletes the card, instead merely emptying it.
- The thermal sight benefits of lantern wisps no longer disappear if you change glasses.
- sandstone wall sprite for indestructible object
- Stabilized gold extracts now respawn the familiar properly.
- Stabilized gold familiars retain the proper languages even after respawning.
- Stabilized gold familiars can be renamed and have their positions reset at will.
- Pulling objects diagonally no longer causes them to flail about when changing directions.
- Riders are no longer left behind if you move while pulling something that has since been anchored.
- Fire alarms now redden all the room's lights, and emit light themselves, rather than applying an area-wide overlay.
- Fire alarms no longer visually conflict with radiation storms.
- Plasmamen now receive their suit and internals when entering VR.
- Deaf people can no longer hear cyborg system error alarms.
- Lockboxes are now actually locked again.
- Legion cores and admin revives now heal confusion.
- checks to see if bullets are deleted if they are the ammo type and the bullet chambered.
- Capitalization, propriety, and plurality on turfs have been improved.
- Unbreakable ladders are now left behind when shuttles move.
- Players who edited a circuit assembly can scan it as a ghost.
- It is no longer possible to pull the mirages images at space transitions, and some other abstract effects.
- Moving large amounts of items with bluespace launchpads no longer creates a laggy amount of sparks.
- The escape pod hallways on MetaStation and DeltaStation now have air again.
- It is no longer possible to repair cyborg headlamps even when their panel is closed.
- Item fortification scrolls no longer add multiple prefixes when applied to the same item.
- The blob core (and only the blob core) now respawns randomly on the station when the core is taken off z-level
- Prevents the round from going into an unending state
- Added a variable to the stationloving component for objects that can be destroyed but not moved off z-level
- After years of protests NT decided to update the fire security standards by adding 3 (three) advanced fire extinguishers to all the new stations.
- Hyperspace ripples now remain visible until the shuttle arrives, even during extreme lag.
- Ripples now correctly take the shape of the shuttle, rather than always being a rectangle.
- Non-secure windoors now properly support the "One Required" access mode of airlock electronics.
- The gulag shuttle no longer moves instantly when returned via the claim console.
- It is now possible to use the ".p" (Asay) and ".d" (Dsay) prefixes while an admin ghost.
- Speaking in deadchat now shows your rank instead of ADMIN
- Added a pink scarf to vendomats
- Players can now ctrl-click the PDA to remove the item in its pen slot
- added a clamp so you can't set a negative multiplier to create materials and create more than 50 items.
- anomaly cores no longer tend to dust
- Plant disks with potency genes clarify the percent is for potency scaling and not relative to max volume on examine.
- Blast cannons have been fixed and are now available for purchase by traitorous scientists for a low low price of 14TC.
- Blast cannons take the explosive power of a TTV bomb and ejects a linear projectile that will apply what the bomb would do to a certain tile at that distance to that tile. However, this will not cause breaches, or gib mobs, unless the gods (admins) so will it. experimental: Blast cannons do not respect maxcap. (Unless the admins so will it.)
- Cyborgs now drop keys on deconstruction/detonation
- The "Save Logs" option in the chat now actually works (IE 10+ only).
- Fixed cyborgs not getting their names at round start
- Fixed cyborgs and A.I.s being able to bypass appearance bans
- fixes cult shuttle message repeating
- Hardsuit helmets now protect the wearer from pepperspray
- It is once again possible for Cargo to export mechs.
- tourettes doesnt stack on itself anymore
- AI static now uses visual contents and should perform better in theory.
- Bucket helmets cannot have reagents transferred into them until after they are removed
- R&D deconstructors can now destroy things regardless of if there's a point value or material
- You should now receive your destroy AI objectives properly during IAA
- Deconstructable TEG now propertly connects to pipes.
- Fix of inverted TEG sprite of slow turbine turning. add:Now you can flip circulator and make TEG of your dream. add:Add TEG and circulator to "Advanced Power Manipulation" techweb node.
- New icon for plastic flaps that actually looks airtight.
- Update to plastic flaps code to use tool procs rather than attackby and removed two pointless states.
- Printing the TEG and circulator boards no longer prints the completed machinery instead.
- Medical HUDs will now show an icon if the body has died recently enough to be defibbed
+ Adds the ability for cloning consoles to read and write record lists to the circuit board, and provides a template for giving other machines local circuit board memory.
-
Cobby updated:
+
Cebutris updated:
- Decals are the exception to the recent removal of effects in Chameleon Projectors.
- Removed Advanced Mining Scanner from roundstart voucher kits.
- Removed Explorer Webbing from all voucher kits besides the shelter capsule pack.
- Paper doesn't give illegal tech anymore
+ Hugs of the North Star! Get them from the arcades (if you're lucky) and hug your friends at INCREDIBLE hihg speeds!
+ Tea Aspera now properly contains tea powder
+ Breasts no longer lactate by default, lactation is now a preference
-
Cruix updated:
+
Chayse updated:
- AIs now have an experimental multi-camera mode that allows them to view up to six map areas at the same time, accessible through two new buttons on their HUD.
+ Changed the Warden's compact combat shotgun to instead be a regular combat shotgun with a foldable stock and penalties for being folded.
+ Assorted space-worthy helmets can now act as masks for internals.
+ Internals code can now check any item with the ALLOWSINTERNALS flag through the GET_INTERNAL_SLOTS define. For now this only checks head and mask slots, since those are the most realistically speaking usable ones.
+ Medbay doors can now be opened by anyone from the inside without having to press the exit button.
+ Borgs now have the necessary dexterity to unbuckle people from themselves and from bucklable objects.
+ Fixes the Trek Uniform/Suit worn icons
+ AIs can now once more talk through holopads successfully
-
Dax Dupont updated:
+
Code-Cygnet updated:
- Fixes the wrong tiles in Syndicate VR trainer and uses different tiny fans.
- Access didn't append to VR IDs
- Fixes missing curator hud icon.
- Cult items will no longer be a long ride on the vomit coaster if picked up by a non cultist.
- Cult space bases are kill again.
- Cult floors now pass gas.
- Fixed a few things deconning into the wrong circuit.
- You can no longer do infinite bioware surgery.
- Foam no longer gives infinite metal
- Mulligan didn't work on lizards and other mutants. Now it does.
- The BoH dialog now has Abort instead of Proceed as an default option.
- Fixes accidental empty ahelp replies.
- More chemicals can be found when vents get clogged.
- Experimentor no longer shits out primed TB nades.
- Fixed rpeds throwing stock part rating related runtimes.
- Fixes a sentience related exploit by blacklisting it in restricted uplinks.
- Botany trays don't magically refill anymore with a rped.
- It's now easier to become fat. Don't eat so much.
- Fixed missing grilles under brig windows of the pubby shuttle.
- For the pubby shuttle, added some food in the fridge, mostly pie slices. Also added a sleeper to the minimedbay.
- Reworded pubby shuttle description to be more inline with the new train shuttle.
- Syndicate and Centcom messages have been squashed together.
- You can now send both Syndicate and Centcom headset messages. Be mindful that the button was changed to HM in the playerpanel
- Fixes missing cream pies in the cream pie fridge.
- Chem synths overlays aren't all kinds of fucked anymore.
- Unfucked all of the remaining chem synth code.
- Reagents no longer have an unused var that's always set to true. Who did this?
- Makes the xeno nest ruin harder to cheese.
- Fixes the bathroom being airless in the Space Ninja anime jail.
- Create antags now checks for people being on station before applying.
- Malf AI machine overloads now are logged/admin messaged.
+ Added new things - Mind trait, alcohol reagent, chemical reagent, drink sprite and recipe.
+ added commander_and_chief sprite to drinks.dmi
-
Denton updated:
+
Coolgat3 updated:
- APC/air alarm/airlock/fire alarm/firelock electronics are now available once Industrial Engineering is researched..
- Engi-Vend machines now contain fire alarm and firelock electronics!
- Loose tech storage circuit boards have been replaced with spawners.
- Added /syndicate subtypes for air alarms and APCs.
- Added missing stock parts to the syndicate lavaland base.
- Added kitchen related circuit boards to the syndie lavaland base.
- There are rumors of the Tiger Cooperative adding a "special little something" to some of their bioterror kits.
- Loose silver/gold/solar panel crates have been replaced with "proper" crates.
- Skewium is much less likely to appear during the Clogged Vents event.
- Navbeacon access requirements have been fixed: Now you need either Engineering or Robotics access, but not both at the same time.
- Pubbystation: Added a dual-port vent pump to the toxins burn chamber.
- Removed most airlock_controller/incinerator related varedits and replaced them with defines/subtypes.
- The Deltastation toxins lab has its portable scrubber, air pump and intercom back.
- Swarmers can no longer attack field generators and turret covers.
- Arcades have been stocked with preloaded tactical snack rigs.
- The Pubbystation maint bar Booze-O-Mat now shows its contents correctly.
- Added a warning to the shuttle purchase menu.
- Pirates and Syndicate salvage workers have been beefed up around the caravan ambush ruin.
- NanoTours is proud to announce that the Lavaland beach club has been outfitted with a dance machine, state of the art bar equipment and more.
- Did you know that honey has antibiotic properties?
- Improved supply shuttle messages and firefighting foam descs.
- Supply shuttles will no longer spill containers on docking.
+ Changed player number checks to 20 from 24 for cult and clockcult, also made nukeops 28 required players instead of 30.
+ Changed enemy minimum age from 14 to 7
+ Added the code for the semen donut and made it craftable
+ Added the donut sprites
+ Made the sec and warden berret offer as much protection like the helmet
+ Added berets for all the heads.
+ Added sprites for the berets.
+ Coded the berets to spawn in appropiate lockers.
+ Raised the ripley's movement speed and lights range by 1, also lowered its armor to compensate.
+ Added combat gloves sprite
+ Added said sprite
+ added combat boots sprite
-
Dimmadunk updated:
+
Coolgat3 / Avunia updated:
- There's a new type of reagent added to the booze dispenser: Fernet. With it you can make a couple of new digestif drinks that will help you reduce excess fat!
+ Made kindle put the target into stamcrit, which makes it an actually working, useful stun.
+ Added a stamina loss modifier to the vanguard spell which makes the user's stamina drain at a way slower rate. This doesn't make them immune to tasers, but it takes a few hits to actually get them to fall down.
+ Made it so that clock culties don't start with a chameleon suit. Instead they start with an engineer suit which is pretty much the same sprite and looks. If this is not perfect, then I am willing to make a slightly more brass-colored version of the engineer suit sprite and call it a ratvarian engineer jumpsuit.
+ Increased the cost of vanguard, as it is now a spell that works somewhat like adrenals, minus the move speed, making your stamina drain really slow and making you unable to get knocked onto the ground by just a single taser shot.
+ Lowered the charge time of kindle, reason being that you can usually have only one active spell on you, or two at max if you decide to run two slabs, but the fact that kindle silences people for such a small amount of time makes up for it, in my opinion.
+ Figured out that the consoles and their warp function actually work with the current code. The thing that makes them not work is when the gamemode is ran on debug mode, without the required players to actually support it. It also breaks the ark timer which is stuck on -1 seconds until activation. Whenever the gamemode starts properly, like any other gamemode, with player checks and all, everything seems to work just fine.
-
ElPresidentePoole updated:
+
CydiaButt13 updated:
- SFX for seppuku (on all katanas)
- suicide message for energy katanas ("cyber-seppuku")
- suicide message for replica katanas ("seppuku")
+ Lamp Plushie to loadout
+ added plushie_lamp to plush icons
+ added Lamp Plush to loadout and icons and items
-
Flatty updated:
+
EgoSumStultus updated:
- The blurry eye overlay has been replaced with an actual blur.
- The vending machine UI is now prettier.
+ Fixed blood chiller's inhand
+ FIXED SHIELF
+ fixed magpistol magazine sprites
+ Added the Femur Breaker
+ Adds male AI vox.
-
Garen updated:
+
EmeraldSundisk updated:
- Thrower and Gun circuits put messages in chat when they're used.
- Only the gun assembly can throw/shoot while in hand
- Adds inhands for the gun assembly
- grabber inventories update when a thrower takes from them
+ Adds a gun range to Box Station
+ Provides some extra power grid connections
+ Sunglasses and Earmuffs removed from the Warden's Office - they can be found at the range instead
+ Rearranges a few objects within the prison as to accommodate the new gun range
+ Adds a mass driver to Delta Station's chapel
+ Adds a second means of entry into the chapel
+ Slightly expands the chapel to make room for the driver, slight adjustment to air systems
+ Clears a path in the station exterior for the mass driver to work properly
+ Nearby maintenance loot has been relocated to accommodate the chapel expansion, surrounding area has been "cleaned up" somewhat
+ CentCom has noticed the lack of coffins in Delta Station's chapel and provided some, but in exchange for reducing the chapel morgue's capacity.
+ Fixed a maintenance door the chaplain should have been able to open.
+ Fixes space areas outside the driver removal: CentCom Defense Analysts have ordered the maintenance hatch to the Mass Driver room be removed citing "security concerns".
+ Increases the number of plots to 9 (from 5)
+ Additional lighting placed directly outside the garden
+ Cleans up the area to reflect use. Moves the seed extractor to a more central location
+ Relocates the seed packs on botany's counter to the garden removal: Removes wooden barricades outside the garden
+ Renames "Abandoned Garden" area designation to "Maintenance Garden", but does not replace the icon in Dream Maker
+ Expands the chapel mass driver room to make it easier to use
+ Rearranges the chapel backroom so there are now six coffins and burial garments roundstart
+ Cleans up the Janitor's office
+ Readjusts the station exterior so mass-driven coffins (hopefully) have less friction
+ Adds a fan to the chapel driver
+ The Janitor missed a few spots around the newly renovated Maintenance Garden
+ Readjusts positioning of Delta's QM keycard device
+ Cleaned up a few spots I missed in #9356, particularly around the janitor's office
+ Adds some potted plants around Box Station
+ The tile mentioned in #9409 should now be radiation-free.
+
+
Fermi updated:
+
+ Fixes tiny runaway decimals in reagents system.
+ SDGF: Fixes infinite clones.
+ fixed an angery PR
+
+
Fermis updated:
+
+ Added a panda simplemob
+ fixes empathy exploit.
+ Added the secbat, a box to hold it and the ability to dispense it from the SecTech vendor.
+ Adds 3 new music tracks.
+ tweaked Neurotoxin
+ added more depth to Neurotoxin
+ fixed the inability to create Neurotoxin
+ fixes fermichem reactions for tiny volumes work
+ makes quantisation level for chemistry finer
+ re-enables femichem explosions in grenades.
+ adds nuance to the SDGF and hatmium explosions.
+ Fixes analyse function on ChemMasters to correctly display purity.
+ Fixes the custom transfer for buffer to beaker button.
+ Debug option: Generate Wikichems
+ graft synthtissue surgery, new reagent synthtissue
+ neurine fixes brain objs merge: combines fermichem's lung damage with tg's
+ on_mob_dead(), bitflags and CHECK_MULTIPLE_BITFIELDS
+ refactored fermichem vars, moved impure chems into their own reagents subtype
+ Fixes small residues of chems that won't go away!
+ tweaked beaker health and allows use of syringes/droppers on chem_heaters
+ added a sound for when beakers take temperature damage.
+ added some icons for melting beakers
+ refactored how beakers take damage
+ fixes how beakers would only take one instance of damage on pH damage
+ fixes Janitor grenades.
+ fixes reaction mechanics at low volumes
+ stops reactions constantly bubbling on the edge of reaction temperature
+ stops small amount reactions from occurring, and prevents disappearing tiny numbers
+ Reduced minimum reaction volume from 1 to 0.01
+ cleaned up Fermichem
+ Adds Jacqueline the Pumpqueen and her familiar Bartholomew for the spooky season
+ Adds a giggle
+ Adds cauldron, Jacq and Jacq o lanterns, and a costume for halloween! mapedit: adds a new landmark so Bartholomew can spawn somewhere sensible.
+ fixes food reactions and explosion runtimes,
+ fixes the too much yes problem
+ Heart, Tongue and stomach regen.
+ lung damage threshholds.
+ Graft synthtissue
+ Skeleton's burning for no reason
+ Organ freezing handling.
+ Fixes chemistry books to point to the right wiki, and keeps tg's just in case
+ Changes top right wiki button location to go to both wikis
+ fixed Jacq's fondness for the AI
+
+
Ghom updated:
+
+ minor clean up on hydroponics reagent containers.
+ fixes the perpetual lack of moisture that has affected genitalia descriptions since, like, forever.
+ implements the arousal state for mammary glands.
+
+
Ghommie updated:
+
+ Fixes many possible situations of null icons for cit races' bodyparts.
+ Removes duplicate slimepeople' sprites.
+ Purges that draw_citadel_parts().
+ Fixes ISINRANGE_EX using the wrong relational operator.
+ The kindle status effect stun duration now properly proportional to the owner's remaining health.
+ Clockwork cult's kindle now affects silicons.
+ Cyborg mounted disablers/tasers/lasers now slowly self-recharge off the cyborg user's power cell instead of draining from it directly.
+ Borg rechargers now properly recharge the borg module's energy guns.
+ Prevents a couple more special/mounted guns from being preserved on cryo
+ Halved borg energy guns self-recharge delay and increased their cell capacity by 3/4
+ Fixes chemical patches always checking the suit slot even if the targetted limb was the head.
+ Skeleton, nightmare and golem races are once again available to get chemical patches applied onto.
+ Adds two cartons of space milk to the space skellie pirates cutter's fridge.
+ Refactored implants to not be located inside mobs codewise, akin to organs.
+ Fixed gps tracking implants.
+ Fixed item not being dumped out of storage implants onto the owner's turf upon removal.
+ Fixes cult potentially stalling if the target is erased from existence without being sacced.
+ Nukes the stunprod's 3 seconds delay.
+ Fixes teleprods.
+ Stops pulls of resting mobs breaking off whenever you swap turfs with someone else because of crawling delays.
+ fixes IAA.
+ EMPs now flick off stunbatons, they can be turned back on immediately by the user anyway.
+ Stunbatons now very slowly consume charge whilst kept on, at a rate of 4/1000th of a standard batoning charge cost per tick.
+ Softened up the charge cost checks to stop the above update from practically reducing the maximum uses of a stun baton by one. Now, should the remaining charge be lower than the hit cost, the resulting stun will be be proportional to the remaining charge divided by the hitcost, within a limit under which the stun batoning just won't happen.
+ Buffs condensed capsaicin, a yet another feature previously dunked by stam combat.
+ speeds up pepper spray puffs.
+ Buffed krav maga leg sweep stun and stamina damage. On the other hand, it's now unable to be used on already lying targets.
+ fixes eyestabbing people with cutlery while being a pacifist.
+ Reduces goonchat lag from being blasted by pellets and bullets repeatedly whilst wearing armor by properly removing the armor protection texts this times.
+ also reduced the size of armor protection messages in general. they clog up the chat box.
+ Fixes stunbatons icon not properly updating on cell removal and insertion.
+ Allows lower charge cells to be used with stun batons, and thus single use crapshots batons.
+ Adds in a 7 seconds delay to the jackhammer dismantling a superheated clockwork wall.
+ escape pods emergency suits storage can now be busted open by emags or excessive damage.
+ Fixes alt click bypassing the escape pods' suits storage lock.
+ Fixes emags wasting charges on un-emaggable & co stuff.
+ Ported some radials code updates.
+ Ported the RCL wiring menu and a comfier RCD interface.
+ A milder combat stance message will show up if the user switch combat mode on while on help intent.
+ Properly rewords the extinguisher's instructions on how to empty it on the floor since it was changed to be a screwdriver action instead of Alt Click a while ago.
+ Reskinnable PDAs. A related game preference.
+ Refactoring the pda, pda painter, obj reskinning and chameleon pda a bit to support this feature.
+ more PDA sprites and ported reskins.
+ turned virtual reality into a component datum, which is then applied to spawned virtual mobs. This fixes mob transformations (such as wabbajack and monkeyizing) breaking the previously hardcoded behaviour and trapping you in VR, also enabling a more concrete virtual reality inception experience.
+ Fixes power cells being unable to be rigged. Also prevents them from starting processing on init if they don't self recharge.
+ Fixes many, little or otherwise, issues with the stunbaton status refactor.
+ The sacrificial target icon will now display onto the cult objective ui alert once again.
+ Stopping borgs from sprinting into negative cell charge.
+ The default amount of z-levels reserved specifically for space ruin generation has been increased from 1 to 2
+ Moving some tablecrafting recipes to the appropriate categories: Kitty ears and lizard cloche hats to "clothing"; Hot dogs to "Sandwichs"; Cuban carb, fish and chips and fish fingers to "Fish".
+ Fixes the not-a-sandwich recipe being M.I.A.
+ Adding in peanuts, peanut butter, peanut butter toasts and sandwiches, and the PB&J sandwich. The peanuts contain a little bit of extractable cooking oil (similarly to soy beans) and can be microwaved or dried in a drying rack to make roasted peanuts, which can be mixed in a all-in-one-grinder for peanut butter, required to make those sandwiches.
+ Buffed wizard and artificier's Magic Missile, wizard and xeno queen's Repulse and juggernaut's Gauntlet Echo.
+ Fixes flashlights being unable to be used for rudimentary eyes and mouth exams.
+ Adds in a grey jumpsuit to the loadout choices, restricted to Assistants.
+ Fixes CWC construct shells being visible as ghost role to latejoiners.
+ new sprites for the flechette gun, its magazines and the toy ray gun
+ Merges the end-of-shift and its shuttle autocall announcements into one.
+ Prevents the end-of-shift shuttle from being recalled (even if to no avail).
+ Fixes being able to teleport papers to your location with TK.
+ Fixed some monkey-code shenanigeans making items sometimes disappear from pickpocketing.
+ New sprites for the some pda cartridges.
+ The crew monitor's entry for the Quartermaster will now appear bolded, while HoP's will be of the same color of the service/unknown/other jobs.
+ emergency pods' storage will now properly work.
+ The PDA skin preference will now properly save up.
+ Changed the default PDA icon var to match the default PDA skin preference.
+ Fixing the `(pointless) badassary` category appearing between the `dangerous and conspicious` and `stealthy and inconspicious` categories.
+ Combat gloves plus now properly use the combat gloves sprite.
+ Fixes the space ninja's energy netting.
+ Adding one pAI to the wizard shuttle and ERT prep room
+ Fixes the rocket launcher being unreloadable.
+ Buffed its accuracy a bit.
+ Replaced the grenade launcher emagged minesweeper loot with the rocket launcher like it was originally supposed to be.
+ Tweaked the :b: emoji.
+ Rubber Toolboxes.
+ Porting in two bar signs: Cyber Sylph's and Meow Mix.
+ Fixing stamina damage melee weaponry being unusable by pacifists, and still damaging objects and triggering electrified grilles when thrown.
+ refactored underwears to allow custom color preferences, instead of manually colored sprites.
+ The aforementioned manually colored pieces. Some of your char preferences may have been resetted as result.
+ More underwear choices, including: Bowling shirts, long johns, a tank top, fishnets, more bee socks, bee t-shirt and bee boxers (original PR for the latter three by nemvar from /tg/station).
+ random bodies will now have random underwear again.
+ Dressers will now properly change undergarment again.
+ Toned down many species' female chest sprites to fit the smaller cups.
+ Fixed some body parts sprites inconsistencies, such as the W/E female and male chest sprites being the same in some species, and jellypeople's legs being one tile off on W/E
+ Fixing baklava pies a bit.
+ Sweaters now cover groins too.
+ Improved the zelus flask to be more viable for bottle smashing than the average barman's selection.
+ Very slight bottle smashing code clean up, stupid const vars.
+ Fixes krav maga gloves, wizard spells knockdowns.
+ Added in an alert pop up to the cult convertees, on top of the older "click here to become a blood cultist" chat message.
+ The convertee's screen will now flash red to fit in the aforementioned message's fluff.
+ Made said message less verbose.
+ Towels. Crafted with 3 sheets of cloth, they can be worn on head, suit and belt slots even without uniform, or laid flat on the floor. Sprites from Baystation and Aurora Station.
+ You can combat mode right click people while wielding rags and towels to pat out their flames (to no use for rags) or otherwise drying them out.
+ toned down the stamina costs of some of the bulkier weapons.
+ repathed hypereutactic blades to be a subtype of dual sabers. Way less copypasta.
+ Fixing CX Shredder guns not accepting standard flechette mags.
+ Fixing missing magpistol magazines icon states.
+ sort of overhauled darkmode/lightmode to /vg/station's, also reincluding the pre-existing black'n'white theme.
+ Fixed LOOC color, fixed .userlove and .love span classes being a bit too blurry on dark mode.
+ The syndicate base's bathroom is now fitted with a shower, and a special towel.
+ Fixed many issues with towels.
+ The dry people off with rags/towels action can only be done if the object is NOT moist with reagents now. Also cleans banana creaming.
+ Towels deal more damage while soaked with reagents.
+ You can now squeeze rags/towels with Alt-Click.
+ deleted an old and crappier towel sprite that got in the way.
+ Fixes Pubby's disposal conveyor belts and lack of a second lawyer spawner.
+ Cleaned up the absolute state of the arousal module.
+ refactored exhibitionism into a quirk.
+ arousal states won't persist after death.
+ Fixes testicles size adjective thing.
+ undergarments toggling now works instead of just making underwear disappear and not come back.
+ The "Always visible" genitals setting will now display them above clothes.
+ combat pushes will now properly stop targets from using firearms, and will disarm the firearm if performed a second time, and also slow down people by 15%, and won't push people on tables blocked by shutters or other dense object anymore.
+ Fixes CHECK_BITFIELD macro.
+ Fixes hypovials being unable to transfer out liquids or be refilled by large dispensers like water tanks.
+ Fixes chem-masters machineries not dispensing newly made pills inside loaded in pill bottles.
+ Stunswords now fit in the captain's sabre sheat.
+ reworked ninja's stealth mode. Increased invisibility, but engaging in combat, attacking or throwing things, bumping people will temporarily lower it.
+ Ninja shoes are even stealthier.
+ cleaned up some 2014 tier processing code horror.
+ the oxyloss fullscreen overlays now also take in consideration 1/5 of the user stamina loss.
+ When you're jogging, you will only slip on water if you have more than 20% staminaloss, for real this time.
+ Different cuffs now come with different worn overlays instead of a generic one.
+ High luminosity eyes can now be properly deactivated and won't illuminate your surroundings again until turned back on.
+ Fixes freshly cloned people starting with undershirts. Fixes random characters possibly rolling with undergarments of the opposite gender (Doesn't affect preferences' freedom of choice).
+ MRE menu 3 has cuban nachos instead of a chili now.
+ Removed the illustration overlay from MREs, looks pretty weird otherwise.
+ MRE menu 4, vegetarian.
+ fixes a few bad touchs on combat mode pushing.
+ Fixes clock cult Abscond scripture not dragging pulled mobs into Reebe. Also fixes blood cult tele runes teleporting you from the source turf to the source turf.
+ fixes clock cult mass recall.
+ Fixes underwear colors a bit.
+ Fixes Blood Cult conversion prompts
+ Removes an obnoxious temporary overlay var.
+ colorable socks can be colored again.
+ Fixed undergarments color preferences resetting each round.
+ Fixed a few dozen suits' body coverage inconsistencies. These changes shouldn't affect armor and utility vests for most.
+ Fixed clown shoes and work boots.
+ Fixed some overlay bug that happens when legcuffed and then handcuffed.
+ Slowed down police baton and tele baton speed by 75%, should be still be faster than the legacy speed (2 seconds) by 0.6 seconds. Telescopic batons' stamina cost per swing is now on par with police batons, ergo more expensive.
+ Fixed undershirts n socks colors prefs.
+ You can now alt-click to rotate machinery such as the tachyon-droppler array or emitters again.
+ Sofas can't be wielded and transformed back into plain chairs anymore.
+ Enables emojis for PDA messages.
+ Removes revenant blight's shabby toxin damage in favor of mood maluses, and a dangerous necropolis curse if not cured in time. Remember
+ Blood cult altar, forge and archives now use radial menus.
+ Fixed some machineries' UIs.
+ blood and clock cultists messages from metabolizing
+ Fixed advanced medical scanners borg upgrades.
+ Fixes certain borg upgrades being unapplicable on dogborg counterparts of the target cyborg type.
+ Fixed people being shovable hrough windows, windoors and the such.
+ You can now shove people into disposal bins.
+ refactored altdisarm(), ergo the "shoving people around" proc.
+ war ops is now lowpop friendly and doesn't require roughly 54 starting players anymore.
+ Singularity beacons now also moderately increases the odds meteor waves, while lowering their estimeed arrival countdown.
+ non-alphanumeric graffiti decals will no longer display as "letter".
+ Nerfs cyborg disabler and its internal power cell to hold 25 disabler beam shots rather than 43/44, just like a normal disabler.
+ Adds some missing species_traits for cloth, clockwork and cult golems.
+ Added towel linen bins, found in dormitory restrooms. Also enhanced the bedsheet bins found in some stations' dormitories
+ Resprited bedsheet bins in 3/4 perspective
+ Made SDGF ghost poll message less verbose, made the experimental cloner's complaint with the former, and added ghost poll ignore options for both.
+ fixing some related onmob sprites issues with the above accessory.
+ Teleprods work on non-carbons mobs now.
+ Fixed tracking implant teleport issues.
+ Increased stunbatons power cell depletion rate when left on by 50%.
+ Gorlex Marauders are pleased to announce non-slip grooves were given to their .50 sniper rifles, and thus shouldn't accidentally flop on the floor like pocket spaghettis whenever taken out of a bag anymore.
+ Silicons can now operate teleporter, medical and security records console from a distance again.
+ Fixed custom say emotes conflict with drunk memes.
+ Fixes identity transfer (envy knife, changeling transformation, making a vr avatar) not copying digitigrade legs.
+ Fixes temporary transformation sting triggering heart attacks on heartless humans.
+ Fixed mobs folded inside bluespace bodybags getting their clothing and items deleted when passing through a recycler.
+ The alien-bursting-from-your-thorax and the xeno "hud" embryo stage images will now properly delete them once the embryo egg lifecycle is complete.
+ Fixed artificier lesser magic missile.
+ Phantom thief masks will now fancy your combat mode yet again.
+ Fixed gulag teleporter stripping the user of stuff it really shouldn't (like storage implant bags).
+ fixing cydonian armor a bit.
+ Resprited wooden and critter crates.
+ Improved the Cyber Sylph' good yet cumbersome bar sign a little.
+ Cyborgs can now use camera consoles on the edge of their widescreen. These consoles are also TK friendly now.
+ Updated gang dominator sprites.
+ Miner borgs can again have installed PKA mods.
+ Fixed invisible blackberry n strawberry chocolate cake slices.
+ Nuke ops / adminbus combat mechs will no longer spawn with tracking beacons.
+ Arcade machine directional sprites.
+ lowered the arcade's random plush / other prizes ratio from 1 : 2.5 circa to 1 : 5. Dehydratated carps and the awakened plush can not be achieved this way anymore.
+ Added armrests overlays to sofas and tweaked their sprites a little.
+ Fixed dogborg sleepers. Just don't tell me what is exactly fixed, cause I don't want to find out.
+ Buffed the deep space familiar gorilla against runtimes.
+ Updated ratvarian computer sprites.
+ Fixed storage implant transplant.
+ Refactored how Jacqueen teleportation destination is selected, preventing them from teleporting on off-station holopads.
+
+
Ghommie && Kevinz000 updated:
+
+ Lichdom and necromantic stone skeletons are now of the spaceproof kind too.
+ skeletons now also like dairy products.
+ Halloween roundstart skeletons and zombies are no more spaceproof.
+ You can choose to set your species to zombie or skeleton through the pride mirror yet again, Alas they are not of the spaceproof kind either.
+
+
Ghommie (Credits to Kmc2000 for the original PR) updated:
+
+ Porting in MRE boxes from Yogstation. But be careful, eating possibly expired MREs found in maintenance comes with an unrealistically large (actually small) chance of food poisoning. Otherwise just bail out and order actually safe-to-eat MREs from cargo for 2000 credits.
+
+
Ghommie (Original PR by Dennok) updated:
+
+ Now areas_in_z get areas spawned by templates and blueprints.
+
+
Ghommie (Original PR by Dreamweaver) updated:
+
+ Nanotrasen has received word of a high-tech research facility that may contain advancements in bluespace-based research. Any crew members who become aware of its whereabouts are to report it to CentCom immediately and are restricted from sharing said info.
+ The turf reservation system now dynamically creates new z levels if the current reserved levels are full.
+
+
Ghommie (Original PR by JJRcop) updated:
+
+ Ports in more emojis, including : flushed :
+
+
Ghommie (Original PR by LaKiller8) updated:
+
+ Goonchat options should now save properly.
+
+
Ghommie (Original PR by Vile Beggar) updated:
+
+ Warden now has an added drill hat in his locker. You can change the loudness setting of it by using a screwdriver on it. Use wirecutters on it for a surprise.
+
+
Ghommie (Original PR by coiax) updated:
+
+ atom/var/container_type has been moved into datum/reagents/var/reagents_holder_flags. There should be no visible changes to effects.
+
+
Ghommie (Original PR by nemvar) updated:
+
+ Botanists can now get beeplushies (or cultivator and bucket) as an heirloom.
+ Clowns and mimes will now properly pick either a can of paint or their brand as heirloom now.
+
+
Ghommie (Original PR by tralezab) updated:
+
+ Fixes an issue with spontaneous appendicitis picking incompatible mob biotypes.
+
+
Ghommie (Original PRs by Tortellini Tony and BuffEngineering) updated:
+
+ E-cigs will continue to display their setting after being emagged.
+ Vapes now come out of the mouth. fix Fixes an E-cig initialize() runtime.
+
+
Ghommie (Original PRs by nemvar and Rowell) updated:
+
+ Added beekini bras and panties, thigh-high and knee-high bee socks.
+
+
Ghommie (by Arkatos) updated:
+
+ Fixed an issue with a Lizardwine drink crafting, where a final product would contain unwated 100u of Ethanol.
+
+
Ghommie (by Floyd / Qustinnus, Arathian) updated:
+
+ The robotocist now has robe to show his love for toasters
+
+
Ghommie (by nemvar) updated:
+
+ Dwarfs are now more robust.
+
+
Ghommie (original PR by 4dplanner) updated:
+
+ thrown objects (but not mobs) no longer hit the thrower
+ mirror shield rebound no longer depends on the original thrower's momentum
+
+
Ghommie (original PR by 81Denton, kriskog and nemvar) updated:
+
+ Sleepers now show a message if players try to unscrew the maintenance hatch while they're occupied or open. Fixed typos in sleeper/organ harvester messages.
+ Sleepers and dna scanners can now be pried open with crowbars.
+ You can open and close sleepers and dna scanners by alt-clicking them.
+ The scanner's hatch now must be closed (on top of being unoccupied), just like sleepers, before being screwdriverable. This fixes a tricky door stuck issue with the machine.
+
+
Ghommie (original PR by AffectedArc07 and Shazbot) updated:
+
+ Added 8 new sock styles
+
+
Ghommie (original PR by AffectedArc07) updated:
+
+ Religion is now a globalvar instead of being a subsystem for some reason
+
+
Ghommie (original PR by AnturK) updated:
+
+ Supermatter now melt walls if it finds itself in one.
+
+
Ghommie (original PR by Anturk) updated:
+
+ Recipe for fabled secret sauce can now be found in the deepest reaches of space.
+
+
Ghommie (original PR by Barhandar updated:
+
+ Pumpkin meteors on Halloween now replace catastrophic meteor waves, instead of ALL OF THEM.
+
+
Ghommie (original PR by CrazyClown12) updated:
+
+ The chloral hydrate inside of the sleepy pen is no longer slower acting than chloral hydrate made in chemistry.
+ The chloral hydrate inside of cookies synthesised by emagged borgs is no longer slower acting than chloral hydrate made in chemistry.
+ Slight tirizene buff.
+ Delayed chloral hydrate
+
+
Ghommie (original PR by Denton) updated:
+
+ Nanotrasen has started shipping more types of bedsheets to its stations.
+ Added in Runtime, Pirate and Gondola bedsheets. The second one can also be found in some pirate ships, while the last can be crafted from gondola hides.
+ You can no longer reveal the 'illegal tech' research node by deconstructing .357 speedloaders, riot dart boxes, syndicate cigarettes, syndicate playing cards or syndicate balloons.
+
+
Ghommie (original PR by Mickyan) updated:
+
+ Fixed being unable to smother people using the damp rag
+
+
Ghommie (original PR by MrDoomBringer) updated:
+
+ morgues have had their proton packs removed and as such no longer suck in ghosts on closing.
+
+
Ghommie (original PR by MrDoomBringer, AnturK and YPOQ) updated:
+
+ Explosions will no longer damage wizards in rod form, the supermatter monitoring radio and megafauna GPS.
+ Supplypods no longer detonate their contents.
+ Fixed silicon items (e.g. cyborg modules) being destroyed by explosion epicenters.
+
+
Ghommie (original PR by Naksu) updated:
+
+ get_area() is now a define rather than a proc.
+
+
Ghommie (original PR by Nicjh) updated:
+
+ Abductor console's select disguise option now uses a radial
+
+
Ghommie (original PR by ShizCalev) updated:
+
+ Pineapple haters/lovers will get/no longer get pineapple pizzas respectively from infinite pizza boxes.
+ As a non-human mob, hovering your cursor over an inventory slot while holding an object in your active hand shouldn't runtime now.
+
+
Ghommie (original PR by Skoglol) updated:
+
+ New helper proc for alt-click turf listing, bypasses any interaction overrides.
+ Ghosts and revenants now use the new proc.
+ Ghosts can no longer toggleopen sleepers, adjust skateboard speed or close laptops
+ Revenant can now alt-click turf to list contents.
+ Revenant now slightly less nosy, use shift click to examine.
+ Alt-clicking the same turf again no longer closes the turf listing tab.
+ Reduced ventcrawl lag greatly.
+ Mining bags will no longer drop ore into backpack.
+ Mining bags in backpack no longer interferes with other mining bags.
+ Fixes some storage size circumventions.
+ Moved machine and computer frames below objects, parts are now always on top.
+ Moved structures (chairs, closets, windows, cult altars etc etc) below objects.
+ Moves mineral doors to airlock layers
+ morgue/crematorium trays' layers shouldn't overlap bodybags' anymore.
+
+
Ghommie (original PR by SpaceManiac) updated:
+
+ Disassembling a chem dispenser for the first time will no longer always yield a fully-charged cell.
+
+
Ghommie (original PR by Swindly) updated:
+
+ Arm-mounted implants that contain more than one item use a radial menu instead of a list menu.
+
+
Ghommie (original PR by Tlaltecuhtli) updated:
+
+ Other people's clothes burning no longer spam you
+
+
Ghommie (original PR by XDTM) updated:
+
+ Reagents now stop their passive effects (for example, stun immunity) if the liver stops working while they're active.
+
+
Ghommie (original PR by YPOQ) updated:
+
+ Fixing roffle waffle, mushroom halluginogen and some invalid reagents.
+ Fixes clockwork armor not actually having armor.
+
+
Ghommie (original PR by cacogen) updated:
+
+ The font size of all text in the chat window now scales
+ High volume (megaphone/head of staff headset) is a slightly smaller
+ Admins have slightly larger OOC text
+
+
Ghommie (original PR by coiax) updated:
+
+ Randomly coloured gloves and randomly coloured glowsticks now have slightly different typepaths, but otherwise function the same.
+ The Squeak subsystem has been renamed to Minor Mapping.
+
+
Ghommie (original PR by duckay) updated:
+
+ Added better names and descriptions for blueshirt officer gear.
+ Added the above gear to the premium selection of the sectech
+
+
Ghommie (original PR by harmonyn) updated:
+
+ Resisting out of bucklecuffs takes more/less time depending on the handcuffs you used, i.e., fake handcuffs will not bucklecuff someone for ages.
+ fake handcuffs shouldn't no longer demoralize restrained criminals scums.
+
+
Ghommie (original PR by monster860) updated:
+
+ fixes advanced proccall
+
+
Ghommie (original PR by mrhugo13 on tgstation13) updated:
+
+ The Syndicate has decided to equip their Syndicate leaders operative (Aswell as their clown counterparts) with the new Combat Glove Plus! The new Combat Glove Plus does everything the old boring Combat Gloves does but with the added extra of learning Krav Maga upon wearing them, any other Syndicate operative who wants to get in on the action will have to pay 5tc.
+
+
Ghommie (original PR by nemvar) updated:
+
+ Some drinks have new icons or slightly altered icons. In particular Wizz Fizz, Bug Spray, Jack Rose, Champagne and Applejack.
+
+
Ghommie (original PR by ninjanomnom) updated:
+
+ Orbiting is a little more aggressive about staying in orbit. The wisp as a result now correctly follows you over shuttle moves.
+ Gaps between sounds in some looping sound effects should no longer happen as much under heavy server lag.
+
+
Ghommie (original PR by variableundefined) updated:
+
+ Cancel button to assault pod destination selector.
+
+
Ghommie (original PR by wesoda25) updated:
+
+ disembowelment no longer works on mobs that aren't dead or in critical condition
+
+
Ghommie (original PRs by Akrilla, Arkatos and Denton) updated:
+
+ Sprays cans have a cap on how dark you can make objects. Art is uneffected.
+ Fixed a bug where you could get cyborg spraycans via pyrite extracts.
+ Added an infinite spraycan for admins to spawn.
+
+
Ghommie (original PRs by Denton and Skoglol) updated:
+
+ Reorganized the syndicate uplinks. Items are now mostly alphabetical, some misplaced items moved to more fitting categories. Bundles, random item and TC have been moved into a new category called "Bundles and Telecrystals". Gloves of the North Star and Box of Throwing Weapons have been moved to Conspicuous and Dangerous Weapons. Combat Gloves Plus have been moved to Stealthy and Inconspicuous Weapons. Moved all implants into the Implants category.
+ Added a new category to the uplink: Grenades and Explosives.
+
+
Ghommie (original PRs by Floyd/Qustinnus, optimumtact, Denton and coiax) updated:
+
+ You can now select what your pills will look like when making pills from the Chem Master
+ Red pills can make you think.
+
+
Ghommie (original PRs by Jujumatic and PKPenguin321, respectively) updated:
+
+ Minesweeper Arcade machines. The higher the difficulty setting, the better the prizes will be.
+ Also keep your eye out for another new (and rare) arcade game!
+
+
Ghommie (original PRs by Kmc2000 and actioninja) updated:
+
+ Added darkmode! You can opt-in to this by clicking the new toggle darkmode button just beside the settings one.
+ Byond members will now have a new setting for their Antag OOC color, instead of using their OOC one. (Antag OOC still locked under admin discretion though)
+ Default black'n'white windows style.
+
+
Ghommie (original PRs by Mickyan, Anturk, ShizCalev, nemvar and Naksu) updated:
+
+ After rigorous mandatory art training for the crew, many new graffiti styles are now available
+ Cleaned up some crayon and spraycan code for futureproofing.
+ Spraypainting blast doors no longer makes them see-through.
+ Paint remover now works on blast doors and the like.
+ Most objects can now be colored using a spray can.
+ Added visible message to spraying objects and windows.
+ Colored lights now shine in different colours.
+ Removed individual buttons text in crayon/spraycan UI, speeding it up.
+ Text mode buffer is actually visible in the UI.
+ Last letter of a text mode buffer no longer rotates out to be replaced with "a", allowing the text mode to be used for individual symbols.
+
+
Ghommie (original PRs by Naksu and XDTM) updated:
+
+ Transferring quirks now properly removes the roundstart trait from the person losing the quirk.
+ Roundstart traits no longer block the removal of other sources of that trait.
+ status traits are now a datum var, the accessors are now defines rather than functions.
+
+
Ghommie (original PRs by Naksu and coiax, loser) updated:
+
+ Cleaned up saycode
+ Taking mutadone while having the communication disorder brain trauma will no longer spam your chat with messages.
+ IPCs now come with a subtype of robotic tongue without the omnilingual ability, instead of innately having robotic voice spans.
+
+
Ghommie (original PRs by Nichlas0010 and ShizCalev) updated:
+
+ AI core display screen can now be set in character preferences.
+ AI core display screen will now be restore when revived.
+ Corrected some inconsistent capitalization in the player preferences screen.
+ Readded some forgotten AI sprites.
+ Fixed Hades AI death animation not playing.
+ the AI icon-selection menu now uses a radial.
+ Added in the death icon_states for the "TechDemon" AI screen.
+
+
Ghommie (original PRs by ShizCalev and bobbahbrown) updated:
+
+ Headsets now dynamically show in their description how to speak on any channels they can use when held or worn.
+ Radio channels names and keys now use defines.
+ The head arrival announcement will now be broadcast to the supply for the quartermaster.
+
+
Ghommie (original PRs by ShizCalev) updated:
+
+ Fixed a bug that allowed you to teleport an ID in your possession to a PDA anywhere ingame.
+ Fixed an exploit allowing you to steal ID's/pens from PDA's not in your possession.
+ Fixed an exploit allowing you unlimited control of a PDA's interface even if it wasn't near you/in your possession.
+ Fixed Pride Mirror exploits.
+ Corgi collars can now be removed!
+ Updated the corgi & parrot inventory panels to use the same formatting as other mobs
+ Fixed corgi inventory panels not closing properly.
+ Fixed the parrot inventory panel not closing properly if you're not able to interact with it.
+
+
Ghommie (original PRs by ShizCalev, MrDoombringer, AnturK, bgobandit, 81Denton and actioninja) updated:
+
+ Failsafe codes for uplinks are now available for purchase.
+ Nuke Ops now have the ability to purchase a usable RPG, the PML-9, as well as a couple different types of rockets for it. you can also suicide rocket jump with them!
+ Improved Uplink item descriptions and formatting.
+
+
Ghommie (original PRs by ShizCalev, coiax and Tlaltecuhtli) updated:
+
+ Caks will no longer override the bonus reagents provided in a donut when frosting them.
+ Caks can no longer create frosted frosted jelly donuts.
+ Jelly donuts will no longer lose their vitamins when they're frosted.
+ Fixed chaos donuts potentially doubling the amount of reagents added when microwaved with something else.
+ Donuts now always contain 1 sprinkles as was stated on the wiki. Frosted donuts have a chance at adding an extra sprinkle.
+ Improved the code for ensuring that security members enjoy donuts and security-themed alcoholic drinks.
+ neurotoxin doesnt insta stun but gives you limb paralysis overtime and heart attacks if it stays in for too long and it is also alcholic
+ beepsky smash now summons imaginary beepskys that deal stamina damage instead of outright stunning
+
+
Ghommie (original PRs by Time-Green and Qustinnus) updated:
+
+ loot crates can't explode after unlocking anymore
+ jumping into loot crates no longers causes them to go boom
+ You can now deconstruct abandoned crates with a welder without making them go boom. After unlocking them, of course.
+
+
Ghommie (original PRs by Tlaltecuhtli and nicbn) updated:
+
+ alt click to eject beakers from chem masters + chem dispensers + grinders + chem heaters
+ hit chem master + chem dispenser + chem heaters with a beaker and if its loaded with another it swaps em
+ All-In-One Blender UI uses a radial menu now. You can see the contents and reagents by examining.
+
+
Ghommie (original PRs by XDTM, 4dplanner, nemvar and, yes, myself) updated:
+
+ Merged tinfoil hat kind of protection into the anti_magic component.
+ Tinfoil hats can also be warped up from excessive dampening of mindray/though control/psicotronic anomalies, or by simply being microwaved in an oven, and become useless.
+ Immortality Talisman and Paranormal Hardsuit helmets now come with tinfoil protection too (minus the paranoia and limited charges).
+ Genetics/Slime/Alien Telepathy and Slime Link are now stopped by tinfoil protection.
+
+
Ghommie (original PRs by XDTM, optimumtact, Nichlas0010 and monster860) updated:
+
+ Added Quantum Keycards, devices that can link to a quantum pad, and can be used on any other quantum pad to teleport to its linked pad. spellchecking: Renamed "Bluespace Teleportation Tech" tech node to "Bluespace Travel".
+ Moved roasting sticks from the "Bluespace Travel" to "Practical Bluespace".
+ Spraying holy water on tiles will now prevent cult-based teleportation from using them as a destination point.
+ Quantum, wormhole and magic teleportation is no longer disrupted by bags of holding.
+ You are now also blocked from teleporting IN to no-teleport areas, not just out of them.
+ Quantum teleportation now makes pretty rainbow sparks instead of the normal ones.
+ Non-bluespace teleportation (spells etc.) no longer makes sparks.
+ Fixed teleportation deleting mob spawners like golem shells and ashwalker eggs.
+
+
Ghommie (original PRs by carshalash, GranpaWalton, BebeYoshi & Hexmaniacosanna, Fire Chance, Ordonis, Krysonism and OnlineGirlfriend) updated:
+
+ Reduced booze power of Mead, Red Mead, and Irish Cream.
+ Increased booze power of Grappa.
+ Added a new premium drink to the soda machine called "Grey Bull" which gives temporary shock resistance
+ A new drink called Blank Paper was added to the bar menu, it was made by a mime and it represents a new start.
+ Adds a variety of fine alcoholic beverages for discerning patrons of the bar: Wizz Fizz, Bug Spray, Champagne, Applejack, Jack Rose, Turbo, Old Timer, Rubberneck, Duplex, Trappist Beer, Blazaam and Planet Cracker!
+ Also more nonalcoholic drinks: Cream Soda, Lemonade and Red Queen.
+ Packs of a novel artificial sweetener have been added to the kitchen vendor.
+ Bottles of trappist beer and champagne are now available in the premium seection of the booze-o-mat.
+ Juicing parsnips now yields parsnip juice.
+ Maintenance peaches.
+ Grape soda now cools you down like other sodas.
+ tweaked the Arnold Palmer recipe, it now uses lemonade.
+ Added new drink, bottle, vomit and peach can sprites.
+
+
Ghommie (original PRs by grandpawalton and Mickyan) updated:
+
+ the contents on the smartfridge icon now change depending on how many items it contains
+ opening the maintenance panel of smartfridges now correctly updates the icon
+ Screwing a disk compartmentalizer no longer makes it look like a smartfridge.
+
+
Ghommie (original PRs by nicbn and coiax) updated:
+
+ Microwave UI uses a radial menu now. You can see the contents by examining.
+ Microwaves have a single wire accessible when open, the activation wire. When cut, the microwave will no longer function, when pulsed, the microwave will turn on.
+ Stabilized dark purple extracts now cook items in your hands, rather than dropping the cooked item on the floor.
+
+
Ghommie (original PRs by ninjanomnom and nemvar) updated:
+
+ Trays now scatter their contents when used for attacks, like they are supposed to.
+
+
Ghommie (original PRs by ninjanomnom, coiax, yoyobatty) updated:
+
+ Fixed slaughter demons not getting a speed boost when exiting a pool of blood. Fixed slaughter demon giblets not being visible.
+
+
Ghommie (original PRs by subject217, AarontheIdiot, pireamaineach, Gousaid67 and SouDescolado) updated:
+
+ Removed plasmamen species speedmod in favor of a slowdown for envirosuits.
+ Nanotrasen has began deploying departementalized enviro plasmasuits to the station! plasmamens can now benefit from some of the bonuses aswell as the color pattern of their job, while allowing others to easily determine their profession!
+ Benevolent Nanotrasen makes gulag available for everyone! (Plasmamen retain their equipment and don't die.)
+ Removes code that theoretically limits plasmamen from being clowns and mimes, but actually doesn't.
+
+
Ghommie (original PRs by zeroisthebiggay, AnturK, MrDoomBringer, Cobby, ATHATH, optimumtact, GranpaWalton, Skoglol) updated:
+
+ Blob overminds, sentient diseases, etc. can no longer dump out boxes. Sorry gamers.
+ Sentient Disease now has almost all symptoms at its disposal.
+ Adding single-symptom disease abilities is super easy now.
+ Sentient Disease can now hear (not sure if this was a bug or intentional).
+ Sentient Disease is a linguist and knows all languages. Still cannot speak.
+ Gives Sentient Diseases a medical hud to observe their victims further with.
+ Fixes and moves around some on_stage_change() and Start()-related things for virus symptoms and (sentient) diseases.
+ The inorganic biology symptom should work properly now when bought by a sentient disease.
+ Oxyloss icon no-longer shows up when someone has the self respiration symptom
+ The self respiration now makes you not contract diseases through the air and not breathe in smoke
+ Sentient diseases can no longer pick two cures that react and disappear when eaten.
+ Sentient disease cures are now consistently harder, will only pick cures from tier 6 and up.
+ Disease cures should now stay the same for all infected mobs.
+ The regenerative coma symptom has a new resistance 4 threshold effect! Said threshold effect will give hosts of the symptom's virus the TRAIT_STABLECRIT trait if its threshold is met.
+ An obscure, probably never reported before bug that may or may not exist involving sentient diseases and the self-respiration symptom should be fixed now (if it even existed in the first place).
+ The cooldown time between each removal or addition of a symptom for sentient diseases has been brought down from an agonizingly long 2 minutes to a more reasonable 1 minute.
+
+
Ghommie (original pr by Dennok on tgstation) updated:
+
+ Now you don't lose your pulled thing on the z level edge.
GrayRachnid updated:
- Adds private rooms to the ninja holding center
- Along with a few things to make it more tolerable, but fear not. There is now a suicide chamber for those who want the easy way out.
-
-
GuyonBroadway updated:
-
- Adds gloves of the north star to the traitor uplink. Wearing these gloves lets you punch people five times faster than normal.
- Sprites for the gloves courtesy of Notamaniac
+ Added windoors to all the flaps on delta.
+ rebalanced k9dogborgs
Hatterhat updated:
- The plasma formerly present in some execution syringes was replaced with amatoxin.
+ Magnetic pistols now fit in boot pockets - jackboots, workboots, etc.
+ literally every pistol subtype fits in shoes now. go wild.
-
Hyacinth updated:
+
Hippie Circuit Port updated:
- Grenadine is now available in the bar!
- Tequila sunrises now require grenadine to make!
+ Added all Atmospheric Circuits
+ Added the ability to color data disks
+ Added Selection and Storage Examiner Circuits
+ Added Smoke, Extinguisher, and Beaker Connector Circuits
+ Added Inserter, Renamer, Redescriber, and Repaint Circuits
+ Added MMI Tank and pAI Connector Circuits (The possibilities are endless!)
-
Iamgoofball updated:
+
Improving and Balancing Cyborgs updated:
- Lipolicide now only does damage if you're starving.
+ Added Crew Pinpointer to Security Borg
+ Added Crew Monitor to Medical Borg
+ Added Crew Pinpointer to MediHound Borg
+ Made the Disabler_Cooler compatible with both Security Borg and K9 Borg
+ Changed the Warning Text upon selecting Security or K9 module
-
Improvedgay updated:
+
ItzGabby updated:
- Naming immerions
+ Bat Species parts for more leeway for character customization.
+ Alphabetized decor wing selection window in character creator for simplicity.
-
Improvedname updated:
+
JTGSZ updated:
- Adds rubbershot secrifle shots
+ Added one more gang boss slot bringing total to 4 from 3
+ Fixed Gang Boss being able to be deconverted
+ Gave Qualifies_for_Rank Check back its checks in job controller.
+ Optional species based clothing restrictions
+ Gang Dominator excessive wall check tweaked to 25 open turfs
+ Gang Dominator no longer functions off-station.
+ Adds more control over species based offsets.
+ qualifies_for_rank now checks latejoin menu
+ Added Halloween Dwarves, for Halloween... Yep.
+ Can flip pipes once more.
+ barricade girder walls use PlaceOnTop instead of new
-
JStheguy updated:
+
Linzolle updated:
- Added the data card reader circuit, a circuit that is able to read data cards, as well as write to them.
- Data cards are now longer inexplicably called data disks despite clearly being cards, and can be printed from the "tools" section of the integrated circuit printer.
- Data cards no longer have a special "label card" verb and instead can have their names and descriptions changed with a pen.
- Also, some aesthetically different variants of the data cards, because why not.
- Data cards have new sprites, with support for coloring them via the assembly detailer.
+ ability to quickly max sensors
+ atmos helmet visual bug
+ supply display are now properly on the wall
+ consistency in hop and cap berets
+ slime people now enjoy eating toxic food and it will not disgust them
+ hos trenchcloak now properly has a sprite on digi characters
+ duplicate definition of hos and sec skirts
+ Krav Maga leg sweep now works properly.
+ shoes can have a different icon used for their item and mob icons
+ combat gloves plus having no mob icon
+ inhands sprite for rainbow knife
+ colour of highlight on the regular knife when held in the right hand
+ mining shuttle console can now be printed after computer consoles have been researched
+ can now carry people on your back by aggressive grabbing them while they are laying down and then dragging their sprite onto yours.
+ dragging people who are prone is now much slower, and carrying them will allow you to move faster at the cost of taking 5 seconds to lift them up onto your back.
+ pacifists can now aggressive grab (cannot table slam people though)
+ blood on your body floating a bit to your right if you're a taur
+ some suits having no icon on tauric characters
+ front facing CMO hardsuit icon for naga taurs
+ colour of medical cross on CMO hardsuit for taurs
+ taur body and jumpsuit showing through mining suits
+ all chaplain suits can hold the same items in suit storage
+ improvement to organisation for chaplain suits
+ blood halberd not going back to 17 force after unwielding
+ unnecessary 's at the end of blood rites healing
+ QoL to blood rites, examine the ritual aura to view how many blood charges are left
+ surgery cleanup
+ dissection available round-start
+ better dissection surgeries from RnD, gives more points
+ abductors can now see what glands do
+ antagonist abductors now have a surgeon trait that teaches them every surgery rather than having it just check if they're an abductor
+ muscled veins surgery
+ having one of your hands used up if you fireman carry but the person being carried dismounts any way other than you dropping them
+ Four colour variants of ankle coverings. Select them on the loadout screen.
+ ankle coverings
+ allows for shoes that don't cover your feet to be taken into account for footstep sound effects and glass shards
+ Tend Wounds surgery. Heal in the field, with better healing the more damage the patient has.
+ Reconstruction replaced by Tend Wounds
+ made Revival more accessible, more viable alternative to cloning.
+ advanced surgery tools can't perform lobectomy or coronary bypass
+ Decorative and insect wings can now be coloured individually, similar to horns.
+ people getting assigned wings if their savefile is old.
+ wings that take the hair colour. Unnecessary if you can just set the colour.
+ Cannot make horns pure black. Trying to do so will set it to a default value.
+ decorative angel wings being invisible
+ abductors now actually work
+ abductor scientist has their own greet message now
+ unable to read paper on airlocks
+ ai can see paper (still just shows stars)
+ Target head and throw a hat at someone to toss it onto their head, knocking whatever they're wearing off if they are wearing a hat. Some headgear can't be knocked off this way.
-
Jay updated:
+
MediHound updated:
- Bans CMO, RD, CE, and HoP from antag/ling
+ Made Cyborgs be affected by Ion Storm Law Changes like AIs
-
Jegub updated:
+
MrJWhit updated:
- Glowcaps now have their own sprite.
+ rebalance melee stamloss
-
Kor updated:
+
Multicam Config updated:
- The Quartermaster and HoP can now access the vault so they can use the bank machine.
- Engineering can now create anomaly neutralizer devices, capable of instantly neutralizing the short lived anomalies created by the supermatter engine.
- Bubblegum has regained his original (deadlier) move set.
-
-
LetterN updated:
-
- Fixes shock collars, they now fit on the neck slot
- you can't put them on pockets anymore
-
-
MacHac updated:
-
- Bedsheets once again properly influence the dreams of those who sleep under them.
-
-
Mickyan updated:
-
- Drinking too much Gargle Blaster, Nuka Cola or Neurotoxin no longer breaks time and space.
- Pacifists can now use harm intent for actions that require it (but still can't harm!)
- fixed typo in bronze girder construction
- New trait: Drunken Resilience. You may be a drunken wreck but at least you're healthy. If alcohol poisoning doesn't get you, that is!
- Fixed pacifists being able to harm using bottles/screwdrivers
-
-
MrDoomBringer updated:
-
- the VR sleeper action button has a sprite now
- Central Command can now smite misbehaving crewmembers with supply pods (filled with whatever their hearts desire!)
- CentCom Supplypods now stun their target before landing, and won't damage the station as much
+ removed whether or not the stuff for multicam was checking the useless var and instead now checks the CONFIG_GET flag.
+ Admins now have a verb in the Server tab to turn AI multicam on and off.
Naksu updated:
- clothing-specific flags are now defined in /obj/item/clothing.clothing_flags
- More flags have been moved to their appropriate places
- HEALS_EARS_2 is removed in favor of the earhealing component
- wearertargeting component is available to subtype for components that want to target the wearer of an item rather than the item itself
- changed the shockedby list on doors to be only initialized when needed.
- Chameleon projector can no longer scan (often temporary) visual effects like projectiles, flashes and the masked appearance of another chameleon projector user
- Drones can no longer see a static overlay over invisible revenants
- adjusted default antag rep points to grant every job the same amount of points per round, except for assistant which gets 30% less
- Nuclear explosive-shaped beerkegs found on metastation can now be triggered with the nuclear disk and the syndicate's legacy nuclear code for a foamy surprise
- comms consoles now work in transit again, and no longer work in centcom
- removed unnecessary getFlatIcons from holocalls
- Screwdrivers and other items with overlays now show the proper appearance of the item when attacking something with them, or when put on a tray.
- moved /datum.isprocessing into datum flags
- Removed unused effect object that could be used to spawn a list of humans
- The ladders in the tear in the fabric of reality no longer spawn their endpoints when the area is loaded, but only when the tear is made accessible via a BoH bomb.
- CentCom is no longer accessible via the space ladder in the tear.
- The lavaland endpoint can no longer spawn completely surrounded by lava, unless it spawns on an island
- ChangeTurf can now conditionally inherit the air of the turf it is replacing, via the CHANGETURF_INHERIT_AIR flag.
- when ladder endpoints are created, the binary turfs that are created inherit the air of the turfs they are replacing. This means the lavaland ladder endpoint will have the lavaland airmix, instead of a vacuum.
- navigation beacons are now properly deregistered from their Z-level list and re-registered on the correct one if moved across Z-levels by an effect such as teleportation or a BoH-induced chasm.
- constructed directional windows no longer leak atmos across them
- setting the value of anchored for objects should be done via the setAnchored proc to properly handle things like atmos updates in one place
+ default radiation insulation is now handled by atom vars rather than a component, components can still be used.
+ squeezed a little bit more perf out of atmos
-
Nicc updated:
+
Nero1024 updated:
- toxins lab boii
+ Bare feet will now make the correct footstep sounds.
+ Other mobs will make the correct footstep sounds.
+ Crawling/dragging sounds for downed/incapacitated mobs
-
Nichlas0010 updated:
+
Onule & Nemvar (ported by Ghommie) updated:
- Reseach Director Traitors can no longer receive an objective to steal the Hand Teleporter
- Comms consoles won't update while viewing messages
- you now feel nauseated instead of nauseous
- You can no longer use a soapstone infinitely
- You now can't get multiple download objectives!
- RDs, Scientists and Roboticists can no longer get download objectives!
+ New Revenant icons
+
+
Original by Citinited, port by Sishen1542 updated:
+
+ You can now use an airlock electronics on a locker to add a lock, and can screwdriver an unlocked locker to remove its lock.
+ You can now remove the locks on broken or emagged lockers.
+ Removing the lock from a personal locker now wipes that locker's ID details.
+ Broken lockers have had their appearance changed.
+
+
Owai-Seek updated:
+
+ custodial cruiser cargo crate
+ removed light replacer from power designs and moved to misc designs
+ added pimpin ride to custodial locator
+ added additional items to janibelt whitelist
+ made plant DNA manipulator unwrenchable
+ reduced janitor premium supply costs
+ fixed them strawberries
+ false codpiece
+ crocin/camphor bottles
+ updated kinkmate item list
+
+
PersianXerxes updated:
+
+ Adds the clockwork_warp_allowed flag to the Captain's Office area, set to FALSE the same way it is for the chapel and armory.
+ Relocates cult catwalks outside the Reebe dressing room.
Poojawa updated:
- Admin IC issue is no longer TG i ded passive aggressive.
- Added *insult, for when you just can't think of anything more clever
- Makes vore specific prefs call Rust_g else uses normal stuff.
- Citadel Toggles should save properly now
- fixed clothing vendor fedoras having Detective Fedora grade armor
- Fixes missing icons on mag weapons for techmemes
- Fixes APCs being replaced in maint from counting Maint as their wall turff
- Added Vore based moodlets, primitive and ain't gunna adapt for not belly things but w/e
+ Digitigrade legs are now able to wear shoes and look fancy, Uniforms to come.
+ Xenos are only digitigrade now, mammals and aquatics have the option.
+ Fire Alarms are visible in low light situations
+ fixed vore prefs saving inconsistently, new characters might have a previous slot's prefs tacked on.
+ fixed mammals not having the option for digilegs. Sprites are fucky until body-part related sprites are done.
+ improved vore sound responsiveness to preference choices.
+ removed morphine from Medihound sleeper chemical list
+ fixed preference setting being broken
+ Medihound sleepers are Initialized properly, and icons update correctly now on eject
+ Air alarm All clear color changed from green to blue
+ APCs are harder to destroy.
+ Added Digitigrade versions of everything appliciable in suit.dmi
+ Snowflake Icons weren't modified, and were given NO_MUTANTRACE_VARIATION
+ naga and quad Taurs literally don't freeze their ass off in space anymore.
+ Digitigrade legs will toggle on/off properly on character menue
+ The misleading "normal" has been removed from species options
+ Added sanity checks to emag usage
+ fixed vtech, but it still doesn't work because of overriding jog/sprint mechanics from combat reworks.
+ Puppy jaws properly store if you're emagged, they are also toggle-able for stealth like the tongue.
+ Digitigrade legs should properly fucking update for the last fucking time. Fucking snowflake code. refractor: Got rid of snowflake sechound cuffs, gave them normal zipties like regular secborgs.
+ dogborg sleepers actually extinguish people who are on fire, in case you don't have time to lick them out.
+ Taur suits should fix themselves properly when worn by other people.
+ Added the Yogs/Oracle ported latejoin menu
+ All markings, tails, ears, and snouts for Citadel races are color matrixed!
+ all markings are on a per-limb basis, including Digitigrade legs!
+ a bunch of tails were blessed with tail wagging sprites, Fish, Sharks, Fennecs, Wahs, raccoons, and others.
+ Tiger markings + tail added, skunk tails improved via sprites from Virgo
+ tweaked some sprites to look better, but they absolutely could use a few extra passes for quality
+ HumanScissors in the Tools folder will permit anyone to contribute matrix'd markings to the sprite sheet, however Mam_markings is very, very full. Be careful.
+ Character preview was both optimized for taurs and bad-touched for better updating. I don't know if it'll be bad, but hey its better.
+ Added Dark Medihound and Pup Dozer from Virgo
+ Clone pods no longer announce the name of the clone
+ fixed flavor text appearing when your face is hidden but you're not an Unknown
+ Tauric suits now apply an (placeholder) blood overlay, as well as their shield overlay.
+ Ashwalkers now have lungs. They cannot breath station air without suffocation effects, but are completely fine on their homeworld.
+ Carbon mobs now have a maximum tolerance to oxygen of 50kPa.
+ Deluxe synthetic lungs have a very high bonus to O2 tolerance.
+ Digitigrade legs returned to normal, since digi leg markings overlay them anyway.
+ commented out lizard mam_snout entries, because too many abominations
+ Vore Panel restored to have various interactions available again. Semi-untested but should work as advertised.
+ Vore Panel has more feedback.
+ is_wet var to bellies, toggled in the panel, will remove flesh sounding struggles and the internal loop. JSON version updated.
+ Feeding var. You will need to enable feeding to recieve any feed vore actions, but you can now feed yourself to mobs that have this set. TODO, Dogborg sleeper feeding.
+ vore mode button now required to be enabled to perform vore actions. It's the mouth icon!
+ Ash Drake vore fixed for actual reals this time
+ Mobs shouldn't spam the released contents announcement anymore on qdel or death. Only if triggered
+ Hostile mob code now properly ignores targets in bellies
+ Your belly can quietly growl if you're starving now.
+ Normal blood splattering isn't offset due to tauric mode
+ Added plasma man suit icons for taurs
+ Added bee butt for insects to have stripes
+ adjusted random spawn sprite accessories, humans won't be demi by default and lizard/mammal spawns will randomly get digitigrade legs
+ sprite adjustments for tentacles, as well as a misspelling.
+ Humans once again use ears and tail_human, as intended. This is to prevent garish randomness
+ istype for species is actually correct and usable now, it'll be a factor for monkey form expansions.
+ Hair functions are de-gendered and more easily selectable now.
+ Slimes can *wag, select markings and snouts, and yes it works.
+ Slimepeople extra parts now respect their hair_alpha in terms of being somewhat see-through. it shouldn't stand out as badly now!
+ Hunger noises are now toggled per character
+ Ashwalker den is habitable by ashwalkers again
+ Medical belts now have overlays! Now you can see if a belt is useful or just flatout empty.
+ fixed hypo MK IIs not being able to be put on medical belts
+ fixed Navy officer uniforms that failed to spawn
+ Loadout items will be forcefully added to backpacks or at your feet instead of left behind at title screen
+ hypospray kits hold 12 now, but only vials and sprays themselves
+ labcoats can carry MK II hyposprays on them now.
+ Vore Mobs are a thing now, not just ash drakes
+ Removed hunger sound stuff. never taking requests from Coolgat3 ever again. refractor: Simple Mobs use the same system regular human mobs do, itjustworks.png
+ Character Window settings unsnowflaked and normalized. I have no fucking clue how to make them work with taurs still tho, sorry.
+ added rotating background images for better clarity and contrast than just SOLID FUCKING BLACK. Images from Virgo/Polaris/Eris
+ Defib users automatically stop pulling when they attempt to perform a defib shock
+ added muzzled varients of space helmets and full masks
+ added knight_grey to taur suits, all paranormal ERT now have tauric versions enabled
+ Lava knights have digitigrade and tauric versions now
+ Added a glass version of the gas mask, because it was in the files and looked nice. does everything regular ones do except make you an unknown
+ Added custom species names! Examining people will now display their species name unless they're an Unknown or have their face hidden. like flavor text. Set it in your character window!
+ changed how health scanners print messages, wrapping it in msg for one to_chat instead of printing every line to_chat.
+ Discord bot will now report when a round ends and give the vague news ticker that a sister-station would have received for the game mode and result of the round.
+ fixed medical hardsuit overlay issue. I thought it was going to work well but fuck byond.
+ None body markings shouldn't give rgb hell, but it also should reset properly anyway. ree.
+ Sorted some sprites to better sooth my byond icon limit anxiety.
+ Box Cryopods expanded to 6 public. Permabrig cryo fixed.
+ Delta Cryopods expanded to 6 public. Permabrig cryo fixed.
+ MetaStation Crypods expanded to 6 public, relocated above sparring ring. Permabrig cryo fixed
+ PubbyStation gained one more cryopod, Permabrig's cryo fixed.
+ Omega given one more crypod as well.
+ Gulag was given a cryopod.
+ Box and Meta's cryo rooms are now a new room entirely.
+ Added erect states for all phallic bodyparts
+ YOUR DICK ACTUALLY STANDS UP NOW, YOU'RE WELCOME.
+ skintone locked genitals match the new skintone colorations.
+ added two new vaginal types and descriptions.
+ fixed borg defib runtimes
+ fixed heart attacks being nonlethal
+ Ported Oracle's cloning set up, you're now visible like cryo when being cloned, though it's a mystery until you have skin on your meat puppet existance
+ Recyclers are unable to destroy the indestructible any longer.
+ Kiara's toy sabre now actually is the correct item + icon states
+ Generic armor for taurs fixed, there isn't actually any sprites for 'em, so. Full sprites overlay over bodies, but I really can't be bothered to do all the offset fixes otherwise.
+ Large maps have had a patient room transformed into micro chemistry stations with nothing else in them. They've been labelled 'Apothecary' rooms and are accessible by doctors.
+ females now have female defined sprites
+ Slime legs have had their excess pixels adjusted
+ Mammal normal legs are more in line with human legs now
+ fixed species like abductors and golems getting the fat tiddy or pingas
+ Atmos and Station alerts should be more alerting.
+ Added visible and hidden testicles
+ Added multi-boob support. Now you can have two or three pairs of breasts.
+ fixed missing vagina and breast sprites
+ fixed prosthetic hands being invisible
+ male foxes exist again
+ female chest markings improved from being too dark in comparison to their other colors, blending better
+ Markings behave better on non-organic limbs.
+ tweaked the name of Sublter to distinguish its use
+ Gave a hint for vore posting.
+ Readded Ninja speech modifications with their mask
+ Pacifists can eat people for heal belly or noisy. Digestive modes are auto-swapped to noisy
+ Added an underwear toggle button under 'Object' tab
+ Genitals now layer under underwear. Hide these if they're too obnoxious.
+ Added digitigrade socks of all known ones anyway.
+ tweaked the Genital character creation layout to look better
+ fixed having balls/womb when you don't have the linked organ at character creation
+ fixed being able to squeeze semen directly from your balls. Probably.
+ NT Newscasters have had repeated reports of gang activity and are now looking into it.
+ NT Psykers keep mumbling about last words of someone who died. Somehow they even have a newsletter for this...
+ Gangster greeting messages are a batch message rather than 5 laggy to_chats
+ RCL now show what color is currently in use
+ Added RGB blood effects, know whose blood this is by color!
+ Added Synthetics blood, and a machine that produces it. A universal donor for medical to heal people with. Make it via medical protolathe!
+ With hearts, slimepeople shouldn't die from the effects of not having a heart.
+ Plasma vessels from xenomorphs will restore blood if you're on resin.
+ Poly's speech now echos to the chat bot.
+ Added new wings to Insects and separated fluff from old ones, they're Insect's new body markings now without being per-limb (for now).
+ Horns are now available to mammals, and they have their own color.
+ Legs are no longer a binary hack code, but actually something that can be changed. Framework for tauric adaptations.
+ Purged Modular Citadel's sprite_accessories.
+ improved the quality of a number of sprites.
+ Moths are now all insects. Avians and Aquatics are all anthromorphics. Just as planned.
+ Anthromorphs can choose their preferred gibbing meat. I guess. Snowflakes are weird.
+ Additional Gentlemen names.
+ Medical huds are now calibrated for Radioactive wavelengths.
+ Engineering equipment, blue space, and common storage containers are radiation protected
+ fixed suit storage not cleaning radiation levels of everything stuffed into them.
+ QM is able to hire/fire people to their department now.
+ cryopod UI isn't complete shit anymore
+ Cryopods purge silicon gear more efficiently now. Same with ghosts.
+ Med Sprays are now more aligned with patch mechanics
+ Chemistry is encouraged to be more varied in their healing, as well as careful in its application
+ Active NPC priority set much higher priority for the MC, with the intent on making NPC combat more interesting
+ Clarified access descriptions of some jobs
+ fixed missing deco wing states
+ fixed a few things related to vore content
-
Pubby updated:
+
Putnam3145 updated:
- PubbyStation: Fixed disposals issue in security hallway
+ Bottles in PanD.E.M.I.C 2200 can now be replaced with an inhand bottle directly
+ Ejecting a bottle from the PanD.E.M.I.C 2200 puts it directly into the user's hand
+ Alt-clicking the PanD.E.M.I.C 2200 ejects the current bottle
+ neural nanites only work/drain if you have brain damage or traumas the nanites can fix
+ Pod people can no longer get fat from standing in the light
+ PanD.E.M.I.C 2200 now ejects onto itself instead of onto user if user's hands are full
+ Added configs for a bunch of Dynamic rule parameters.
+ Added defaults for all the configs (WIP).
+ Added dynamic midround/latejoin antag injection to the config.
+ Made starlight condensation not kill slime people.
+ Added not-killing-slime-people to the transmission threshold of plasma fixation and radioactive resonance.
+ Made the clone scanner lock while it's scanning.
-
Robustin with cat earrs updated:
+
R3dtail updated:
- Gun overlays should be way less laggy now. remove: Chameleon guns are completely removed since they crash the server, were already made unavailable, and are the worst shitcode I've ever seen in my life.
+ Added 16 saltprimaryobject items Added 4 saltsecondarysubject items
+ Added a new carpet. Red! Also added said carpet to the Premium Carpet crate from the cargo supply console. Trilby said she'd take care of the crafting recipe.
-
ShizCalev updated:
+
Raptorizer updated:
- Adminorazine will no longer kill ash lizards.
- Adminorazine will no longer remove quirks.
- Fixed mobs immune to radiation being killed by HIGH bursts of radiation.
- The book of mindswap will now properly mindswap it's users.
- Fixed a runtime with the gulag teleporter that could cause the process to fail if you removed the ID.
- Not setting the goal of a prisoner's ID when teleporting them will now set the ID's goal to the default value (200 points at the time of this change.)
- Fixed cigar cases & cigarette packets taking two inventory slots
- Fixed cigar cases showing the wrong icon for the cigars inside them.
- Fixed cigar cases & cigarette packets stating the wrong name of the cigar/cigarette when removed via altclick.
- Fixed items in pockets vanishing when a mob is monkeyized.
- Fixed items in pockets vanishing when a mob is gorillized.
- Fixed items in pockets vanishing when a mob is infected with a transformation disease.
- Fixed items in pockets not being properly deleted when a mob goes through a recycler
- Fixed items in pockets not being properly deleted when highlander mode is enabled.
- Fixed exploit allowing you to remove unremovable tanks from pockets.
- Fixed items in pockets dropping when a mob is equipped with a new outfit.
- Fixed items in pockets not being covered in blood when equipping the psycho outfit.
+ Doubled peach spawn rate
+ tweaked numbers/variables
+ rebalanced numbers/variables
+ removed unneeded code
-
SpaceManiac updated:
+
Seris02 updated:
- The destructive analyzer can once again be used to reveal nodes.
- Some references to "deconstructive analyzer" have been updated to "destructive".
+ Abductor Replication Lab ruin and advanced tools
+ Added looc hotkey
+ made the autoprocess button relevant
+ changes so that spooktober starts earlier
+ fixed the dark blue lum major effect
-
TGstation contributors updated:
+
Sirich96 and Dennok (ported by Ghommie) updated:
- Nukeop eshields are now buyable. tgstation/tgstation#39025
- Staff of storms now has admin logging. tgstation/tgstation#39011
- Fixed a couple of inconsistencies in the uplink descriptions of SMGs and SMG ammo. tgstation/tgstation#38980
- Fixed blob victory. tgstation/tgstation#38988
- You can now un-ignore notifications you've clicked "never this round" on, and more. tgstation/tgstation#38990
- Fixes a weird bug with timers. tgstation/tgstation#38994
- (tgstation/tgstation#40043) - Beam rifles no longer open lockers
- (tgstation/tgstation#40061) - Mobs can no longer get stuck at min/max body temperature
- (tgstation/tgstation#40041) - Pictures of asses are now properly sized
- (tgstation/tgstation#40084) - The lastattacker var now includes unarmed attacks
- (tgstation/tgstation#39968) - Plastic golems can no longer ventcrawl with items in their pockets
- (tgstation/tgstation#39885) - You can no longer crash the server by overcharging energy guns.
+ Added new Teleporter Station sprites
+ Added teleport station calibration animation.
-
Thunder12345 updated:
+
Sishen1542 updated:
- Added a colour picker component for use with circuits.
+ Pentetic Jelly, new chemical made through mixing 1:1 slime jelly and pentetic acid.
+ Anatomic panacea now gives pent jelly instead of pent acid. Medbeams now have TRUE tox healing to heal TOXINLOVER as well.
+ Changed bible heal proc, halving the healed damage and increasing brain damage 5x in exchange for a much wider array of items to protect you from it.
+ Moved around some chems from emag list into upgrades.
+ Added some fun chems to dispensers.
+ Gave dispensers old tg functionality.
+ Leather, cardboard, bronze & bone golems!
+ Bone hurting juice and interactions with plasmamen, skeletons & bone golems!
+ Ported addition of new CAS cards.
+ Ported a fix for CAS.
+ Added the ability to alter your genitalia as a slimeperson more than addition/removal.
+ fixed genitalia removal proc in alter form.
+ Ported the inability for non-station AI to interact with station z-level.
+ HoS mains can now peacefully sleep in their office.
+ Podpeople now have customization options.
+ Removed the human check for cult conversion of captain/chaplain minds.
+ Roundstart carbon jetpacks now have full_speed FALSE.
+ Adds plasteel to medical and security techfabs.
+ Added public autolathes to all maps.
+ density = 0
+ hugboxing mining loot
+ ling blade now has 40 armor pen
+ fun
+ bad stuff
+ mech bad
+ rebalances strained muscles
+ added in the assistant response team
+ fixed up access on the centcom hangar button
+ storage tweaks for belt briefcase
+ codersprite for belt briefcase
+ added pharaoh gear to chaplain vendor
+ fixed typos in pharaoh items
+ made laser minigun not shitcode and also craftable
+ added new fire sounds for the laser minigun
+ holy lasrifle, hypertool, divine lightblade, and blessed baseball bat. Four new holy weapons!
+ stamina and force tweaks for most holy weapons.
+ prayer beads no longer deconvert after a 10 second timer, now just inject holy water for delayed effect
+ cultist runes are now destroyed with a bible or a null rod
+ bo-staff now functions as a nerfed sleepy carp staff
+ fixed kevinz code to add in non-null rod child items as holy weapons
+ fixing chems for strained muscles
+ narsie no longer asks for consent
+ removed reflect from divine lightblade
+ teleporting a locker is bad
-
Time-Green updated:
+
Sishen1542, original by @Tlaltecuhtli updated:
- Soda is no longer intangible to the laws of physics
+ alt clicking the emitter now rotates it instead of only flipping
+
+
Sishen1542, original by @zxaber updated:
+
+ Utility mechs no longer automatically get beacons.
+ Tracking beacons no longer delete themselves when EMPing a mech, and instead have a ten-second cooldown in-between EMPs. They also now do heavy EMP damage rather than light.
+ Mechs that take EMP damage lose the use of their weapons and equipment temporarily. Movement and abilities are not effected.
+ Mechs taking EMP damage no longer roll for a random malfunction.
+
+
Sishen1542, original by Arkatos updated:
+
+ Action buttons can now be dragged onto each other to swap places
+
+
Sishen1542, original by NewSta updated:
+
+ updated the miasma canister sprites
+
+
Sishen1542, original by Skoglol updated:
+
+ Heaters/freezers now support ctrl clicking to turn on and alt clicking to min/max target temperature.
+
+
Sishen1542, original by XDTM updated:
+
+ Using the wrong surgery tool during surgery no longer attacks the patient, if on help or disarm intent.
+ Surgery steps are now shown in detail only to the surgeon and anyone standing adjacent to them; the patient and people watching from further away get a more vague/ambiguous description.
+
+
Skoglol updated:
+
+ You can now alt click storage (bags, boxes, etc) to open it.
+
+
Skully) updated:
+
+ Nudity Permit, a completely invisible uniform that still has pockets and such, to loadout options. It is more or less a direct port from the RP server.
+
+
SkullyRoberts updated:
+
+ Penis autosurgeon as rare maint loot.
+
+
TerraGS / Skoglol updated:
+
+ Adds toggleable light and blinking charge indicator to kinetic crusher
+ Kinetic crusher can now be one-hand carried. You'll still need two hand to use it.
+
+
Thalpy updated:
+
+ fixes message_admins in SDZF
+ Alkaline buffer recipe so people don't get grumpy and expanded the pH range
+ fixes buffers
+ fixes broken compiler because a var changed name
+ impure travis var anger
+ Added the ability to dispense smartdarts from the chemmaster.
+ Tweaks medolier amd chembags to allow quickpickups of smartdarts, lets the latter soak in beakers (on the floor)
+ fixed rounding errors with smartdart mixes.
+ added modified smartdartgun icon.
+ 1. Kev asked that there were no antag datums used, so that's been changed. 2. Tricks can no longer turn someone into a dullahan, instead you have to spend candies to get that. I felt it was too mean to turn people into that, I didn't realise you couldn't revert it. 3. Barth will no longer as for impossible items. 4. Barth will no longer as for the same item multiple times. 5. Barth will now accept broader things, rather than asking for something, when meaning something specific. 6. Jacq will now no longer poof off the z level. 7. Jacq will (hopefully) stop spooking the AI by teleporting into there 8. Jacq will now try to teleport to a location with someone nearby. 9. Barth will tell you where Jacq is currently when you speak to him. 10. You can trade 2 candies for a Jacq Tracq (tm) 11. Jacq should stop getting mad and cover the station in gas when killed. 12. Fixed Jacq not singing (the link died). 13. Slightly changed wording so that people will hopefully get to know her. 14. Jacq no longer disappears when you're getting to know her.
Toriate updated:
- It appears that ancient pieces of armor have wound up on the open market! These armors have degraded beyond usefulness. Grab one now in the loadout!
- added flak jacket and M1 Helmet sprites
- Gives the flak helmet a tiny storage compartment
- Made the flak helmet even weaker against acid and fire so it crumbles into dust easier
- Added the Corporate Uniform and the Silver Bike Horn
- added sprites for the Corporate Uniform and Silver Bike Horn
+ All regular crates are now 3/4ths ToriCrates iamgeadd: Unused plastic crate sprite added
+ Blood freezer crates now have unique sprites.
+ RPD now has inhands
+ New sprites for RCDs and RPDs, inhands included
+ Updated the sprites of all the regular crates
+
+
Trilbyspaceclone updated:
+
+ cakes!
+ Made some sprites! -Love them really came out well
+ new economics
+ cargo and robotics relationships
+ unbalanced something
+ fixed a maybe oversight
+ Fun
+ costs of suit voucher
+ Unblances miner vender
+ spare cheaper brute kit
+ harm from hentie
+ rebalanced goliaths stun to be less auto death
+ Armor to blob shields
+ block weaken state to 70% from 75%
+ restores the deathriplys missing armor
+ new lockable colalr
+ armor
+ missing hopes and dreams
+ orgized the weapon file to be more cat brain friendly
+ This means sprite right?
+ Many engi flags on non-engi things
+ changed some code to be organized at a glance
+ 25% < --- 50% For NPC blocking bullshit ided: Yes
+ mag gun uses cells
+ kev things their to op
+ syndicate phobia
+ other phobia's
+ laser carbine
+ makes collars only locked via key
+ charging
+ Combat inducers for COMBAT!
+ made it look nice
+ golden swag boxes
+ Crafting suitcases
+ more bountys
+ Nitryl bounty
+ better stocks
+ more evil blood fluff text
+ Added more mime names
+ replaces a sink with a autolathen
+ 2 -> 3
+ MASON SUIT!
+ adds the sec jetpack to sec hardsuit storge
+ Added a few jet packs to the space queens men
+ volume of jet packs
+ Bad Idea
+ bio mass meat
+ more box options
+ a lack of replaceable boxes
+ clothing needing a emag
+ 4 - > 5
+ 5->6
+ 4tc - > 2tc
+ mulligan costs 4 - > 3
+ Tuberculosis 12tc - > 8tc
+ 15 - >10
+ both bags have the same name
+ 5 - > 2
+ 3 -> 1
+ 2 < - 4
+ 1->2 and ultra
+ shield + crafting
+ hierophant movment and melee attack
+ More plushies
+ attack verbs and descs
+ bone satchles
+ rebalanced stunslugs
+ colored boxes, and more types
+ harm and such
+ item classes
+ resonators being so shitty
+ Game braking bug critical: bug fix
+ items to syndie surgery bags
+ SNOW CONES
+ carts buy-able cargo
+ selling/time to craft
+ crafting problems, and red stamp exsplote
+ gives paper work sprites that are nicer
+ origami
+ gang tower shield
+ costs of boots
+ organ box
+ Medical breifcaseses
+ New cargo crate for tech-slugs!
+ Ammo to each fitting crate
+ Cat-code
+ fixed a few typos - Again my bad
+ fixed airless place
+ baklava
+ makes uplink kits more usefull for the risk
+ Changes some files to be better
+ As all things are not
+ fixing cat code that dosnt work, my bad
+ Arcades stealing from noodles
+ rapier
+ speedy quirk
+ Ironic
+ A bunch of minor issues with xenobiology are no more!
+ I didn't code it right it in the first place
+ new nodes
+ points and node gear
+ stuff n things
+ gear harness and a conflict merg
+ Nudity permits
+ nothing
+ Donner item
+ Luna's Gauntlets
+ rebalanced lingy dingy powery gamey
+ melee and block harm
+ sprites*
+ holster doing holster things
+ Donor item
+ Joy, Happiness, Honk
+ small mix up in terms
+ Promiscuous Organs crate, pills to lewd crate and testicles to maints
+ Made unholy water healtoxinlover
+ Zelus Oil, brass flasks
+ Added new chairs
+ Bugtesting zone upgrades for easy bug/game testing
+ more cargo to cargo
+ More loadout gear
+ Poojawa power creep
+ Not my work not my credit
+ Emitter gun
+ suit storage nulling anti magic item protection
+ rebalanced steal goals restrictions
+ fixed a few misleading goals
+ ports a fix
+ oversight in benos
+ QM rooms not getting Key Aunths
+ new books/cooking
+ less bad wording in slime
+ strawbarries and such
+ amazing things like tea of catnip, catnip and plant
+ glue uplinks
+ RPDs to drones
+ Armor and such
+ flavor
+ maybe a runtime
+ chameloen clothing
+ tons of peach themed items
+ caje
+ New book - Unused
+ organized files
+ redid brass tools to look better*
+ /cursed from a item path
+ Almost all clothing and most weaponds can be sold for pocket change
+ Cargo costs of packets and selling
+ Lowered mat selling as well as most if not all bountys
+ Adds more files for easy finding/adding in packs
+ oops not being blacklisted
+ removes some cit-modular things
+ Missing sprites with bad ones
+ emag charge amount
+ Reebe QoL aka creep in gear
+ ???
+ HEY MADE THE REEBEEE WAY SMALLER - Making it less lagging hopefully
+ Surgerys and spays in bags
+ earthbloods stam regen
+ Red to Blue/Black crosses as questioned by Bhijn
+ clean bot not cleaning basic cleanables
+ new traitor bundle
+ trash
+ eye bleed :add: misstakes
+ Removed old things!
+ UI memes
+ Blue space blood bag
+ blood costs
+ Beebal and Honeybalm plants
+ Costs of crates and paperwork
+ Adds 2 more crates hacked only
+ Added two seed packets of cotten to ash walkers base
Tupinambis updated:
- Removes the tesla coils from engineering secure storage, and places them within the engine room, functional upon being wrenched down. (Arranged in the common method of three coils on the left and right sides.)
-Reduces the width of engineering secure storage and its blast door by one tile. The machinery within has been rearranged in order to make the most commonly used machinery the most accessible.
- Replaces the blood-red hardsuit in Deep Storage with a mining EVA hardsuit, and an included oxygen jetpack.
- Adds a replacement to the old lavaland xeno ruins in the form of lavaland_surface_alien_nest.dmm An image of which is shown below. (The area layer is disabled for visibility.)  
-This replacement is designed to act as a sort of raid, with the queen as the raid boss. The most notable loot includes the corpse of a drone, security bio armor, a bone axe, some basic syndicate equipment, and a syringe containing alien microbes. All references to the old lavaland xeno ruins have been replaced with references to the new map file.
- New corpse spawners for alien queens and drones.
- New syringe containing the alien microbe reagent.
- Removed the currently unused lavaland_surface_xeno_nest.dmm map file, and its references.
- Added an experimental hard suit to toxins bomb test room on Box.
- Increased the size of the toxins bomb test room, moved the telescreen, and added chairs on Box.
- Moved some pipes out of the way on Box and Meta.
- Two air pumps have been added to the toxins lab on Pubby and Meta.
-The following changes apply to Box, Meta, and Pubby:
- Unbolts the toxin burn chamber doors on round start.
- Unlocks the toxins lab air alarm on round start.
- When spawned as a nuclear operative, you keep your characters race instead of being changed into a human. Plasmamen are an exception to this change.
- By popular request, makes the Head of Security spawn with a telebaton instead of a stun baton.
+ Changes large parts of the nuclear operative base, including the addition of a new barracks where the ops spawn, a personal bedroom for the leader, the rearrangement of numerous rooms, some added fluff, a slightly more roomy bar, a larger hanger, a kitchen, and various other small changes to make the base feel just a bit more alive. This was achieved by completely redoing the base from scratch so there was room to work with, as a result potential bugs could crop, please do report them.
+ The drop pod chamber was airless. This seems like an oversight, and has been filled with air.
+ Cryo Sleepers have been added to Perma on all four maps in rotation. the bathroom windoor and window have switched places to accommodate this change.
+ You can now choose the pre-exisiting "loader" sprite as an appearance for your engineering borg.
+ A vast majority of references to humans within ion laws have been replaced with crew. AI modules have received similar treatment
+ Adds a syndicate themed emergency shuttle that costs 20000 credits, and can ONLY be purchased when the communications console is emagged. This shuttle features a fully stocked medbay with self serve sleepers, plenty of room that can fit highpop, a fully featured bridge, ballistic auto turrets, and an armory, EVA prep room, and bar, all of which are only accessible by either an agent ID or through hacking.
+-EVA prep features 2 syndicate hardsuits and 3 syndicate softsuits. -Armory features 5 stetchkins with spare ammo, and 2 riot c-20r's.
+
+ Lone operatives no longer spawn with a syndicate hardsuit and a bulldog. They instead spawn with a black and red EVA suit and an extra 15 TC (40 in total) 
+ The tesla engine has been replaced with a supermatter engine, and pubby engineering has been redesigned to accommodate this change.
+ The tesla engine has been completely removed along with any related components
+ RD and R&D vents are now actually connected to the air distribution.
+ New engineering hivebot. Has a bit more health but otherwise aesthetic.
+ Oldstation no longer has an excessive amounts of hivebots within it, however the bots that remain are individually a larger threat.
+ Hivebots are now more robust, with a higher melee damage output and health.
+ Remove this ruin from the blacklist or this PR is pointless.
+ the air injectors for the SM engine waste and for toxins waste should now receive power
+ Adds a mixed clothing closet to Deltastation Dorms.
+ Adds a bottle of unstable mutagen to Botany, on account of its distance from Chemistry.
+ Omegastation should no longer have any turf with missing textures, as those spots have been replaced with playing covered in a sandy turf decal.
+ Removed all living eggs from the xeno ruin because people self antag. Honk.
+ Adds a new security level between Blue and Red (Amber). The shuttle call time at this level is 8 minutes.
+ Blue security level now has a shuttle call time of 12 minutes.
+ The security level increase/decrease texts have been modified to accommodate the change.
+ Adds a code Amber sprite for the fire alarms
+ Removed the plushes from the toy crate, giving them their own.
+ Plushes are now less likely to spawn out of arcades
+ Removes a moth plush from the game.
+ added a small fire delay (3 ticks) to automatic shotguns
+ Reduced buckshot brute damage by 20%. (12.5 -> 10 brute per pellet) (75 -> 60 brute at close range)
+ Reduced rubbershot stamina damage by 40% (25 -> 15 stamina per pellet) (150 -> 90 stamina at close range)
+ Reduced beanbag stamina damage by 12.5% (80 -> 70 stamina per shot)
+ Engivend RCDs now vend upgraded RCDs
+ Beautified and stylized the cyborg HUD sprites, animated and cleaned up some of the old, modernized APC hacking and Doomsday sprites,
+ moved cyborg language select above the radio icon, instead of above the picture icon.
-
Werebear updated:
+
Twaticus & Poojawa updated:
- Seven new holochassis options for pAIs and two new display images for pAIs.
+ Added new carpets from TauCetiStation!
+ More Liquid carpet chemicals, mix carpet with certain reagents to get different colors!
+ Tablets have a better means of being assembled codewise. nothing's different on player end.
-
Wilchen updated:
+
UntoldTactics updated:
- Removed box of firing pins from rd's locker
+ Rewords the click here prompt given when an attempted conversion is done on an offer rune (for blood cult)
+
+
UristMcAstronaut updated:
+
+ allows a pai to activate its holoform while in a pai connector without getting derped.
+
+
Useroth updated:
+
+ the collars are now aware of their proper overlay sprites
+ The space hotel dorms are now properly boltable with the buttons inside.
+ Makes the booze-o-mat hacked by default. Alternative to https://github.com/Citadel-Station-13/Citadel-Station-13/pull/8350.
+ After the PR which raised the ammo capacity of said magazines, due to the code, they ended up with an invalid icon state. Fixed through changing the icon state name in the icon file.
+ Taeclowndo shoes which grant the four following abilities: - Conjuring a cream pie right into their hand. Every three seconds. - Making a banana peel appear out of thin air at the tile of the clown's choice. Every ten seconds. - Mega HoNk. A touch-ranged, very small AOE ability, with effect equal to being honked by a Honkerblast on a clown mech, with the effects halved for anyone who isn't its direct target. Every ten seconds. - Bluespace Banana Pie. You don't throw this one... not right away at least. This baby can fit an entire body inside. Good for disposal of evidence. 25 second-long action, 45 second cooldown. Also produces a "[victim's name] cream pie". The body drops out of the pie if you splat it somewhere or destroy the pie. If you eat it, it will chestburst out of you a'la monkey cube.
+It's a 14 TC item for traitor clowns and a 12 TC item for clown-ops.
+ The tentacle now directly puts the item in your hands, instead of toggling your throwing and tossing it at you. Tentacles suffer from ranged inaccuracies as if they were guns, I think it's enough of an inconvenience.
+ Makes the netting much less clunky. If there's only one target you can net while you press the button, it will just net that target instead of bringing up a list of mobs.
+ Energy nets now revive and fully heal capturees (even dead ones, after calculating points). If someone's got a scan and wants to get cloned, they can always kill themselves still.
+ Capture points are added on capture, rather than round-end, so it no longer matters whether your captures kill themselves in the holding facility or not.
+ Makes the nets a bit more sturdy. (previously it took mere two welder hits to break one)
+ Makes stungloves actually stun people (currently comparably with stunbatons, adjustable). Because electrocute_act(25, H) did fuck all, stunwise, and on top of that, people in insulated gloves were completely unaffected.
+ Reduced the stunglove electrocute_act value to 15 due to above. Could possibly be lowered further.
+
+
Weblure updated:
+
+ Added the relevant Beepsky animations from TG's aibots.dmi file to Cit's aibots.dmi file.
+
+
WhiteHusky updated:
+
+ Sleepers now show blood level and type.
+ Changed the styling of arousal messages to use pink-ish colors.
+ The orgasm moodlet message new-lines properly.
+ Flavor text with special characters will not get partially unescaped.
+ Canceling when setting flavor text does not clear it anymore.
+ Checking yourself shouldn't freeze the client anymore.
XDTM updated:
- Fixed anti-magic not working at all.
- Diseases now properly lose scan invisibility if their stealth drops below the required threshold.
- Coldproof mobs can now be cooled down, but are still immune to the negative effects of cold.
- This also fixes some edge cases (freezing beams) where mobs could be cooled down and damaged despite cold resistance.
- Androids are now immune to radiation.
-
-
Xhuis updated:
-
- Character traits are now called character quirks. Functionality remains unaffected.
-
-
Zxaber updated:
-
- Cyborgs can wear more hats now.
-
-
and Fel updated:
-
- New chairs are on most shuttles! Finally, you can relax in style while escaping a metal death trap.
-
-
armhulen updated:
-
- chameleon guns are disabled for breaking the server
-
-
cacogen updated:
-
- You can now see what other people are eating or drinking.
- Borg shaker can now synthesise milk, lemon juice, banana juice and coffee
- Renamed drinks no longer revert to their original name when their reagents change
-
-
cyclowns updated:
-
- Fires no longer flicker back and forth like crazy
- Fusion has been re-enabled! It works similarly to before, but with some slight modification.
- Fusion now requires huge amounts of plasma and tritium, as well as a very high thermal energy and temperature to start. There are several tiers of fusion that cause different benefits and effects.
- The fusion power of most gases has been tweaked to allow for more interesting interactions.
- BZ now takes N2O and plasma to create, rather than tritium and plasma.
- Fusion no longer delivers server-crashingly large amounts of radiation and stationwide EMPs.
-
-
deathride58 updated:
-
- (Only visible on 512) Stamina crit will now result in the mob's sprite subtly darkening around its edges.
- Added a tiny reference item to a year-old weeby game. If you're a traitor, you can find this item in the "badassery" section of the uplink. It's free, and you can order up to 4 of them! The effects of this item are only visible on 512.
- Added a component signal for toggling combat mode on/off.
- The cleaving saw now deals less staminaloss to its user while inactive.
- You can now make use of custom say verbs with the [say verb*message] format
- Yelling will now echo and penetrate walls
- Distant voices now have smaller text
- You can now see the amount of charges an emag has by examining it
- Emags now make a quiet noise when they're close to running out of charges.
- Emags are no longer irreversibly destroyed upon running out of charges.
- Traitors can now purchase emag recharge devices for 2 TC. They have five extra charges each, and can be found in the devices and tools section of the uplink.. There's no cap on the amount of charges a single emag can have, though do be aware that upstream spaghetti code makes it easy to waste charges.
- Small emag flavortext changes here and there
- The warden's particle defender now deals less staminaloss when in stun mode.
- "code [alert level]" has been changed to "[alert level] alert" on the hub entry.
- The hub entry now displays the current map.
- Lavaland is no longer fullbright. We have memory to spare.
- Adds the wheelofsalt command to TGS3. Spin the wheel of salt to find out what the Citadel Station 13 players are salting about today!
- You can now slam or slap your hands onto tables by right clicking them in combat mode.
- Non-admins can no longer use LOOC while dead, unconscious, in crit, or while ghosting.
- The syndicate mask available in the uplink will now inject you with a chem that cuts your click delay in half and increases your stamina regeneration, when you enter combat mode. The mask has a five minute cooldown between adrenaline injections.
- Dogborgs will now reduce firestacks when they use their tongue to lick someone's face.
- The repo compiles again
- The flag cape donor item should render properly now.
- The default amount of z-levels reserved specifically for space ruin generation has been reduced from 7 to 1
- Items now spawn on top of, rather than inside, closets and other storage structures
- Jukeboxes now have realtime directional audio, complete with occlusion when you're far away or behind a wall.
- More than one jukebox can play a song at a time now. Have up to 5 jukeboxes playing at once!
- Devs can now control the wet and dry channels of sounds played via playsound_local. The new envwet and envdry arguments will control the volume of the wet and dry track, respectively.
- Jukeboxes have been turned into a subsystem. Track initialization, audio playing, etc, are now handled via SSJukeboxes instead of via the jukebox object procs.
- Jukebox tracks now require an additional ID field at the end of their name. This will make it easier to add jukebox-style objects that are only capable of playing specific songs, without worrying about copyright issues.
- Added Raiq's boombox as a donor item
- You can now manipulate tails, ears, body markings, mutant colors, and taur types via DNA console!
- Reduced the exponent on gas tank ruptures. TTVs and suicide onetanks that were previously 20dev are now approximately 9.6dev. Let's see the actual toxins nerds adapt!
- When a custom say verb message is spoken without any actual words, the text will render without a `, ""` at the end of it.
- The combat rework's training wheels have been removed. Knockdowns no longer have any noticeable stun. This indirectly means stunbatons and tasers will always deal their full stamloss on hit.
- The stamloss required for boxing gloves to throw a knockout punch has been increased from 50 to 100.
- You can now prime the grenade on bombspears by using them in your hand. The wield hotkey is moved to combat mode rightclick while a spear has a grenade on it. This is explained in the examine text.
- Bombspears no longer instantly explode on impact when thrown. They now have to be primed to explode when thrown.
- Bombspears now have 90% embed chance.
- If an embedded item is normal sized or larger, you can take it out instantly by pressing resist.
- Embedded items are now much harder to pull out the smaller they are, rather than the other way around. It's much easier to rip out a sword from your chest than it is a shard of glass in your face.
- The message you get when you get bounced by the PB is now a little more clear about what you need to do to gain access to the server.
- The jukebox now falls off over a greater distance. You can now actually hear the jukebox while sitting in a far corner of the bar, or while passing through the main hallways.
- Added antag OOC. This is disabled by default, but you can access it with the "AOOC" verb as an antagonist when an administrator enables it.
- LOOC now supports emojis
- Deadchat and asay will now both render emojis! :snya:
- The disarm attack on EMP'd defibs now has an interruptible 1 second timer before it actually lands.
- The stamina buffer now only takes 1 second to start regenerating.
- Disablers have had their damage reduced from 36 stamloss to 24 stamloss, increasing their shots to stamcrit from 4 to 6.
- Tasers have had their damage increased from 55 stamloss total to 61 stamloss total. Shots required to stamcrit are unaffected.
- Introducing the Kitchen Gun (TM)! Say goodbye to daily stains and dirty surfaces with Kitchen Gun (TM)! Just five shots from Kitchen Gun (TM), and it'll sparkle like new! Includes two extra ammunition clips for the low, low price of just 10 TC! Laser sight and night vision accessories sold separately! Magazines can be purchased individually for 1 TC a pop!
- Active turf processing is now its own subsystem.
- Ports tgstation/tgstation#39287 - You can now configure how fast a mob fires, and how many shots they fire in a single burst
- When you spawn as a miner, you'll get text clarifying your job description. You might not think it's necessary, but believe me, it is.
- mushroom people are now roundstart on live
- The geargroupID var of loadout entries can now be a list rather than a string. GeargroupID changes are additive when multiple are defined in a single loadout entry.
-
-
deathride58 (Original PR by Basilman/Militaires) updated:
-
- Ported TGstation's Agent Stealth Box! You can the implanter in the syndicate uplink for 8 TC. Credit goes to Basilman/Militaires. This port includes minor adjustments, see the GitHub for details.
-
-
hatterhat after being yelled at by kevinz updated:
-
- deletes an entire line that might fix flash icons idk blame him if it gets worse
-
-
iksyp updated:
-
- stacking machines and their consoles no longer dissapear into the shadow realm when broken
- you can link the stacking machine and its console by using a multitool
- Ever since the great emotion purge of 2558, people were able to work at top efficiency, even while starving to death. This is no longer the case, Nanotrasen Scientists say.
- Hunger slowdown only applies if mood is disabled in the config.
-
-
imsxz updated:
-
- Using mayhem bottles and going under their effects is now logged.
-
-
izzyinbox updated:
-
- Added an integrated circuit part that interacts with the arousal system
- changes the admin-pm input box from single line to multi-line
- Tennis balls now equip and show up in the correct slots
- Adds option in the hide/expose genitals verb to hide genitals even without clothes
-
-
kevinz000 updated:
-
- Cameras now can take pictures up to 7x7. Alt click them to change their width/height from the default 3x3.
- Photos are now logged to disk, assuming the host enabled the configuration option
- If the above is enabled, albums/frames can now have their persistence IDs set in variables to allow for PHOTO PERSISTENCE
- Every head of staff gets a unique album with its own ID in their locker. Let your successors know about your accomplishments, screwups, and everything in between!
- All of this works or should work with newcasters/pdas/etc etc
- Photo taking now clones the area into transit space and then operates on it, instead of on the spot, in theory making photographing things more accurate?
-
-
nicc updated:
-
- no more dark locker corner woo
- area alterations
- escape pod
- see above
- adds windoor to the plastic flaps in the atmos lobby
-
-
ninjanomnom updated:
-
- A plush that knows too much has found its way to the bus ruin.
-
-
resistor updated:
-
- Added circuit labels! You can now customize the description of your assemblies.
-
-
slate3 updated:
-
- ported a new alternative sprite for engineering borgs, mr. handy
- ported a new alternative sprite for security borgs, a spider-like walker
- ported a new alternative sprite for medical borgs, an eyebot
-
-
steamport updated:
-
- Borgs/AIs can now toggle rad collectors
-
-
ursamedium updated:
-
- slapping / slamming hands on tables now uses appropriate pronouns
- crow pAI is no longer invisible while resting
-
-
yenwodyah updated:
-
- A few virus threshold effects should work now
-
-
yorii updated:
-
- Fixed the smartfridges to be in line with all other machines and puts the released item in your hand.
-
-
yorpan updated:
-
- Brain damage makes you say one more thing.
-
-
-
04 September 2018
-
Denton updated:
-
- Mech construction messages no longer incorrectly mention high-tier stock parts.
- Added a nanite lab to Deltastation! It's at the old EXPERIMENTOR lab.
- Delta: Moved the Xenobiology disposals bin to be less obstructive. Added two sets of insulated gloves to Engineering.
- Delta: Fixed scientists not having maintenance access near the circuitry lab and toxins launch chamber.
-
-
Shdorsh updated:
-
- Made all the extinguishers use less sleep and spawn procs
-
-
-
03 September 2018
-
Cdey78 (Ported by Floyd / Qustinnus) updated:
-
- AI can now think
- New OOC emote: :thinking:!
-
-
Naksu updated:
-
- a new admin secret has been added to create a customized portal storm
-
-
Shdorsh updated:
-
- Makes it possible to create circuits that can get an item loaded into them while they are in an assembly and the assembly is open.
- Optimized electronic assemblies also.
- A bug pertaining putting batteries in assemblies
-
-
Skoglol updated:
-
- Eggplant and egg-plant seeds now have different names and plant names.
-
-
XDTM updated:
-
- Fixed nanite cloud storage not allowing uploads.
-
-
octareenroon91 updated:
-
- Supermatter more likely to log fingerprintslast when it consumes any object.
-
-
-
02 September 2018
-
Denton updated:
-
- Fixed species type names that show up on health scanners.
-
-
-
01 September 2018
-
ElPresidentePoole updated:
-
- removes curator's fear of snakes
-
-
McDonald072 updated:
-
- Defibrillator nanites work properly.
-
-
Poojawa updated:
-
- fixed clothing vendor fedoras having Detective Fedora grade armor
-
-
Potato Masher updated:
-
- The color of Wooden golems should be more in line with the color of the wood used to make it.
-
-
WJohnston updated:
-
- Reinforced floors are now shinier.
-
-
-
31 August 2018
-
Anonmare updated:
-
- AIs can now turn shield generators on and off again
-
-
Denton updated:
-
- Plastic golems can no longer vent crawl with items in their pockets.
-
-
Mickyan updated:
-
- Skateboards can fit in backpacks
- Skateboards are slower by default, speed can be adjusted by alt-clicking
- Show your support for the fine arts with these new quirks:
- Tagger: drawing graffiti takes half as many charges off your spraycan/crayon
- Photographer: halves the cooldown after taking a picture
- Musician: tune instruments to temporarily give your music beneficial effects such as clearing minor debuffs and improving mood.
-
-
Skoglol updated:
-
- Dispensers can now add 5u to buckets, plastic beakers and metamaterial beakers, down from 10u.
- You can now pour 5u from buckets, plastic beakers and metamaterial beakers, down from 10u.
- Chem dispenser window width increased slightly, no longer shuffles buttons when scroll bar appears.
-
-
The Dreamweaver updated:
-
- Sentience Potions no longer require you to have Xenomorph toggled on in preferences and now relies on its own preference in order to be notified of open roles.
- Split xenomorph, intelligence potions, and mind transfer potions into separate roles for more precise role management.
- Sentience Potion Spawns and Mind Transfer Potions are now job-bannable roles.
-
-
Time-Green and locker sprites by MrDoomBringer updated:
-
- Reports have come in that the wizard federation has harnessed some of the ancient locker force to create a wand
-
-
XDTM updated:
-
- Removed the chance of spouting brain damage lines when over 60 brain damage. The dumbness trauma still has them.
- Fixed Mechanical Repair nanites not working.
-
-
ninjanomnom updated:
-
- Computers are now visible even in the darkest of rooms. Comfy!
- Because computers are now far easier to find in dark rooms their base light output has been reduced.
- Broken components left over from the signal origin refactor should be fixed.
- Lava isn't a safe place to throw your flammable shit anymore
- The computer screen overlay being rotated incorrectly after construction has been fixed.
-
-
-
28 August 2018
-
Denton updated:
-
- The 10 second anti spam cooldown of night shift lighting now works properly.
- Added an examine message to APCs that mentions Alt-click and Ctrl-click (silicons only) behavior.
-
-
Garen updated:
-
- adds a signal for screwdriver_act
-
-
SpaceManiac updated:
-
- Multiple copies of a shuttle each get their own area instances (affects APCs and air alarms).
-
-
XDTM updated:
-
- The forcefield projector is now available ingame in the engineering protolathe. It can project up to 3 forcefields which act as transparent walls, and share a pool of health which is recharged over time. The projector must remain within 7 tiles of the forcefields to keep them active.
-
-
-
26 August 2018
-
CitrusGender updated:
-
- Added note severity to [most] bans and the notes associated with them
- Banning panel now has a severity option UI: Changed the UI of the note panel UI: Changed the UI again, added some icons, removed brackets in urls, fading out notes cannot be selected to expand the browser anymore
-
-
Floyd / Qustinnus (Credits to KMC for the sprites) updated:
-
- The Clown Car, your 18TC clown-only solution to asshole co-workers
- Regular car implementation (makes it easier to add more cars if someone actually feels like adding those)
-
-
JJRcop updated:
-
- Asay logs show "ADMINPRIVATE: ASAY:" again instead of just "ADMINPRIVATE:"
-
-
Naksu updated:
-
- living and stack typecaches now use a shared instance where it makes sense, giving small memory savings
-
-
PKPenguin321 updated:
-
- Integrated circuit medium screens have been readded. They are now called large screens. They now only work from your hands or on the ground when you're standing on top of them (NOT from pockets, lockers, backpacks, etc).
- Roundstart cyborgs will now be properly referred to as "it."
-
-
SpaceManiac updated:
-
- The shuttle manipulator now allows flying any shuttle to any port which will fit it.
- The shuttle manipulator now allows fast-travelling shuttles with 5s remaining, down from 50s.
- Status displays have been refactored to be cleaner and more flexible.
- The AI dying properly updates its status displays again.
-
-
intrnlerr updated:
-
- Refactored nettles to be reagent_containers
-
-
nicbn updated:
-
- Nanotrasen shoes no longer contain Silencium. Now footsteps make noise! Sounds from Baystation.
-
-
-
25 August 2018
-
Denton updated:
-
- Added missing export rewards for various lavaland items (tendril/megafauna/ruins) and engine parts.
- Increased export values for emitters, PA parts, field generators and radiation collectors to match the rest of engineering exports. Reduced supermatter shard value by 1000 credits.
- Removed export rewards for red/blue warp cubes since they're blacklisted from the cargo shuttle.
- Added private intercoms to the confession booths of the Deltastation+Pubbystation chapels.
- Fixed invalid radio frequencies on interrogation chamber/confession booth intercoms.
- Anime is even more horrifying than previously discovered!
- Added a new shuttle loan event where crew can get paid for having an active syndicate bomb delivered to cargo bay.
-
-
Mickyan updated:
-
- Blue polo undershirt option has been restored
- underwear "nude" option moved to the top of the list
-
-
SpaceManiac updated:
-
- The map loader now supports vars to be set to lists containing non-strings.
- Overcharging energy guns no longer crashes the server.
- Ordering the Build Your Own Shuttle kit no longer crashes the server.
-
-
The Dreamweaver updated:
-
- Refactored gift code to fix a minor inefficiency.
-
-
XDTM updated:
-
- Fixed chest and head augmentation not working properly.
-
-
-
23 August 2018
-
Naksu updated:
-
- Waddling is now available as a component
-
-
Nervere updated:
-
- re-adds the joy emoji.
-
-
SpaceManiac updated:
-
- The body zone selector now indicates which body part you are about to select when hovered over.
- Transit space initializes about five seconds faster.
-
-
Tlaltecuhtli updated:
-
- Cyborg ion thrusters consume 1/5 of their previous power.
-
-
-
22 August 2018
-
BlueNothing updated:
-
- Allows video camera circuits to be seen on networks other than the science cameranet.
- Alphabetizes camera list for camera bugs, and lets camera bugs see through borg and circuit cameras.
- Makes video camera circuits fit in tiny assemblies.
-
-
PKPenguin321 updated:
-
- The GPS circuit now has a 4th output, placing X,Y,Z all in a string.
- 2 new converters: Rel to Abs, and Advanced Rel to Abs.
- Rel to Abs takes a set of relative and a set of absolute coordinates, and converts the relative one to absolute. 1 complexity.
- Advanced Rel to Abs takes a set of relative coordinates and converts it to absolute without the need for an already known set of absolute coordinates. 2 complexity.
-
-
SpaceManiac updated:
-
- Freezers and heaters which start on no longer stay visually on when you turn them off.
- Atmospherics now initializes 93% (about 40 seconds) faster.
-
-
floyd updated:
-
- fixes the hunger alert appearing forever
-
-
intrnlerr updated:
-
- Tank temperature is no longer based on pressure
-
-
ninjanomnom updated:
-
- Shuttle templates now handle shuttle registration in the load rather than the shuttle manipulator. This means admin loaded shuttle templates no longer need to be manually registered.
-
-
oranges updated:
-
- Inventory overlay now uses a traffic light to indicate if the item can be placed in there
-
-
-
20 August 2018
-
Basilman updated:
-
- Added gondola fur products
-
-
Basilman, Sprites by WJohnston updated:
-
- His Grace ascension is back, feed Him 25 people and you will unlock His full potential.
-
-
Denton updated:
-
- Added new destinations for the parcel tagger! You can now send packages to the Circuitry Lab, Toxins, Dormitories, Virology, Xenobiology, Law Office and the Detective's office. Viro/Xeno can only receive parcels.
- Deltastation: Tagged parcels no longer get routed straight into the crusher. Untagged parcels also no longer get routed straight into the crusher!
- Deltastation: Added disposals to Xenobiology that launch contents into space.
-
-
Epoc updated:
-
- Putting an extinguisher into a cabinet with the safety off will no longer cause it to spray first
-
-
Floyd / Qustinnus updated:
-
- removes useless mood events subtypes
- fixes mood event timers not resetting when they get triggered again remove: removes the depression overlay which makes our fruit happy
-
-
Frosty Fridge updated:
-
- Added the Surgical Processor upgrade for medical cyborgs. Scan surgery disks or an operating computer to be able to initiate advanced procedures.
- Cyborgs can now perform surgery steps that do not require an instrument.
- Plastic creation reaction now properly scales with the amount of reagents; 10u = 1 sheet.
-
-
Garen updated:
-
- fixed using items on a circuit removing all its access(now access gained from each new item stacks)
- adds logging for gun circuits, grabber circuits, and dragging claw circuits
- grabbers can select what they want to drop
-
-
MrDoomBringer updated:
-
- The Nanotrasen Airspace Aesthetics division has shipped out a newer design of NT-Brand "Ore Silos". No new features have been added, but they certainly look much nicer!
-
-
Naksu updated:
-
- Having a high body temperature now increases the damage you take gradually, whether you're on fire or not. Being on fire also always increases body temperature damage
-
-
NewSta updated:
-
- The names of haircuts, facial hair, undershirts, underwear and socks have now been sorted and categorized
-
-
WJohnston updated:
-
- Remade titanium and plastitanium floors to be less of an eye strain and something mappers might actually consider using.
- New reinforced floor sprites.
-
-
XDTM updated:
-
- Added programmable nanites to science!
- Science now has a nanite chamber, a nanite program hub, a nanite cloud console and a nanite programmer.
- From the program hub you can download nanite programs (unlocked through techwebs) to disks.
- You can then customize their functionality and signal codes through the Nanite Programmer.
- The nanite chamber is necesary to inject nanites into a patient, and it's also used to install/uninstall programs into a patient's nanites. A second person is required to man the console.
- The nanite cloud console controls remote program storage; it stores program backups that nanites can be synced to through cloud IDs.
- Nanite programs range can be either helpful or harmful; their main potential is that they can be enabled at will through the use of remotes and sensors. The potential uses are endless!
- More detailed information is available in the wiki.
-
-
-
18 August 2018
-
Floyd / Qustinnus updated:
-
- moves nutrition events to the mood component
-
-
Jared-Fogle updated:
-
- Hovering over storage slots with an item in your hand will show you first if you can put the item in.
-
-
XDTM updated:
-
- Fixed augmentation not working and/or giving you extra limbs
-
-
nicbn updated:
-
- New janitor cart sprites (by Quantum-M)
- Dirt is smooth (by AndrewMontagne)
-
-
zaracka updated:
-
- You can now use certain emotes and the suicide verb while buckled, but not while stunned.
-
-
-
17 August 2018
-
Anonmare updated:
-
- Ore silos circuit boards are now constructable
-
-
SpaceManiac updated:
-
- The "Map Template - Upload" verb now reports if a map uses nonexistent paths.
-
-
Tlaltecuhtli updated:
-
- fixes diamond drill bounty having the wrong object path
+ Added the experimental dissection surgery, which can be performed once per corpse to gain techweb points.
+ Rarer specimens are more valuable, so xenos and rare species are more efficient subjects.
+ Added two new surgery procedures, under the Experimental Surgery techweb node.
+ Ligament Hook makes it so you can attach limbs manually (like skeletons) but makes dismemberment more likely as well.
+ Ligament Reinforcement prevents dismemberment, but makes limbs easier to disable through damage.
+ Golem limbs can now be disabled, although they are still undismemberable.
YPOQ updated:
- Roundstart motion-detecting cameras work again
+ Stealth implants work again
-
intrnlerr updated:
+
Yakumo Chen updated:
- "Allows image windows sent by PDA to be closed"
+ Made stealth implant boxes flimsier
+ Autocloning now requires tier 4 parts
+ Removes autoscan
+ Scanning people now requires someone to operate the cloning computer regardless of part level.
+ removed antimagic component from holymelon
-
-
15 August 2018
-
barbedwireqtip updated:
+
YakumoChen updated:
- added binoculars to the detective's locker
+ AEGs brought more in line with current radiation system. Try not to get EMP'd.
+ Jetpacks no longer last twice as long between air refills.
+ Reverted laser miniguns.
+ Adds beanbag slugs to the sec protolathe at round start
+ Brings shotgun ammo availability back in like between seclathe and autolathe.
-
-
14 August 2018
-
Coolguy3289 updated:
+
Zargserg updated:
- Removed un-needed and un-used RENAME comment from game_options.txt
+ Lungs maximum toxin threshold is 0.5% of the atmosphere.
+ Permanently contaminated atmosphere does not murder crew anymore.
-
SpaceManiac updated:
+
ZeroNetAlpha updated:
- Escape Pod 1 now reaches the CentCom recovery ship again.
-
-
WJohn updated:
-
- Titanium walls and windows are a bit prettier looking now.
-
-
Zxaber updated:
-
- Airlock electronics can have now have unrestricted access by direction set. The resulting airlock will allow all traffic from the specified direction(s) while still requiring normal access otherwise. A small floor light will indicate this.
- Medbay Cloning and Main Access doors now have unrestricted access settings set, and the buttons have been removed. All maps have been updated.
- Airlocks now correctly update their overlays (bolts lights, emergency lights) when their power state changes.
-
-
-
13 August 2018
-
Basilman updated:
-
- Adds Arnold pizza, dont try putting pineapple on it.
-
-
Denton updated:
-
- The briefcase launchpad can now hold items while in briefcase mode (just like a regular briefcase). Its remote has been disguised as a folder and now spawns pre-linked inside the briefcase.
- Increased the briefcase launchpad's range from 3 to 8 tiles, which is roughly half the screen.
- Added more ingame manuals that access wiki pages.
- Added botanical and medical bounties as well as a static adamantine bar bounty.
- Increased the syndicate document bounty's reward from 10.000 to 15.000 credits.
- Removed the gondola hide bounty and in return, increased the export value to the old level.
- The briefcase bounty now also accepts secure briefcases.
- The action figure bounty now correctly spawns as an assistant type bounty.
-
-
Logging refactor and improvement updated:
-
- All mob-related logs now include the area name and (x,y,z) position.
- All logs that included an (x,y,z) position now also include the area name.
- Standardized logging format of mob/player keys.
- Telecomms logs are now included in the individual logging panel.
- Fixed many other cases of logs being sent to either the individual logging panel or the saved log files, but not both.
- The logging system has been refactored to contain less redundant code and to produce more consistent logs.
-
-
SpaceManiac updated:
-
- The VV window loads and searches faster.
- Fields in the VV window's header will immediately show your edits.
- Selecting an action from the VV dropdown no longer leaves it selected after the action is done.
-
-
YPOQ updated:
-
- Uncalibrated teleporters can turn humans into flies again
-
-
-
12 August 2018
-
Denton updated:
-
- Killing gondolas now lets you harvest meat from them. Eating it raw might be a bad idea.
-
-
Mickyan updated:
-
- Mixed drinks now give mood boosts with varying strength depending on their quality.
- Although powerful, mood boosts from quality drinks are short lived. If you want to make the most out of them, take a sip every few minutes like a normal human being instead of downing the entire glass like the alcoholic you are.
-
-
Nichlas0010 updated:
-
- Admins with +admin and without +fun are no longer able to smite.
-
-
SpaceManiac updated:
-
- Blood and oil footprints sharing a tile no longer causes footprint decals to stack.
-
-
WJohnston updated:
-
- Syndicate (melee) simple animals will now move less predictably and attack twice as often, hopefully making them quite a bit more dangerous.
-
-
XDTM updated:
-
- Operating Computers can now sync to the research database to acquire researched surgeries, instead of requiring installation by disk.
- You can now review the full list of unlocked surgeries from the operating computer.
+ Cleans up autoylathe code and brings it back in line with the regular autolathe.
+ Fixes autoylathe interface not updating propperly.
+ Silicons are now consumable by scrub pups.
actioninja updated:
- Added (unobtainable) Felinid Mutation Toxin.
+ APC UI autoupdates correctly
-
lyman updated:
+
bluespace bio bags updated:
- Updated the Chronosuit Helmet sprite.
+ Added bluespace bio bags and put it in the tech web, in the node applied bluespace
+ added a crappy icon for bluespace bio bags
-
-
11 August 2018
-
Denton updated:
+
chef updated:
- Fixed the Beer Day date and added a few more holidays.
+ Added main hallway approach to monastery
+ Added Maintenance hallway approach, with some maint loot
+ moved the docking arm for the white ship
+ changed placement of some grills and windows
-
Jordie0608 updated:
+
coiax updated:
- Asay history is once again logged under the admin log secret.
- Notes, messages, memos and watchlists can now have an expiry time. Once expired they are hidden like as if deleted.
+ When the nuclear disk stays stationary long enough to trigger an increase for the lone op event chance, admins will be notified every five increments.
-
SpaceManiac updated:
+
dapnee updated:
- Giant spiders can now freely pull their victims through webs.
+ Plasmaglass tables, spears, tiny plasmaglass shards
+ Plasmaglass structures now drop plasmaglass shards instead of nothing
+ Trim lines!
+ You can now make plasmaglass tables again.
-
Time-Green updated:
+
deathride58 updated:
- Circuit Boards now tell you the components required to build them on examine
+ When a gamemode fails pre_setup, it will now send a message in admin IRC and in ingame admin chat, instead of only being viewable in the logs.
+ Portal guns now spawn without firing pins.
+ Reduced the default/baseline nanite pool amount from 100 nanites to 25 nanites, and reduced the maximum nanite amount from 500 nanites to 125 nanites. The safety threshold was reduced from 50 nanites to 12 nanites.
+ Most of Lavaland's mobs are now on crack.
+ Blood drunk miners now move once every two ticks, rather than once every three ticks.
+ Bubblegum now has a maximum movement speed of once every three ticks. Buffed from the original value of once per 5 ticks.
+ The minimum time for the Colossus to attack again after firing a random shot is two deciseconds, Sped up from the original value of three seconds. The minimum time for the Colossus to attack again after performing a blast is now one second, with the original value being two seconds. The minimum time for it to attack again after performing its alternating shot pattern is now two seconds, original value being four seconds.
+ Ashdrakes now move once every five ticks, rather than once every ten ticks.
+ Heirophant chasers now move once every two ticks rather than three ticks by default, and the chaser cooldown has been reduced from 10 seconds to 5 seconds. The cooldown for the Heirophant's major attacks has also been sped up to 4 seconds from the original value of 6 seconds.
+ The Legion (megafauna) now moves at two ticks per second rather than three ticks. It additionally now actually moves faster while charging. The cooldown timer for it's special attacks has been reduced from 2 seconds to 1 second. Additionally, The Legion's view range has been decreased from 13 tiles to 10 tiles.
+ All megafauna now have a default view range of 4 tiles, decreased from the original of 5 tiles, and an aggro'd view range of 15 tiles, decreased from the original of 18
+ Goliaths now move once every ten ticks, sped up from the original value of 40(!!!) ticks. Additionally, their cooldown for their tentacles has been reduced from 12 seconds to 6 seconds. To compensate, their cooldown now only decreases by 5 deciseconds every time they're attacked, rather than 10 deciseconds, their melee damage has been reduced to 18 per hit from 25 per hit, and their vision range has been decreased from 5 tiles unaggroed, 9 tiles when aggroed, to 4 tiles and 7 tiles respectively. Ancient goliaths have a default attack cooldown of 8 seconds, sped up from the original value of 12 seconds.
+ Legion (the common mob) now has a cooldown of 1.5 seconds on their skull attack, sped up from the original value of 2 seconds. Additionally, their view range has been decreased from 5 tiles, 9 tiles when aggroed, to 4 tiles, 7 tiles when aggroed.
+ Stamina no longer regenerates at hyper speeds.
+ To accommodate for upstream's stamina changes, knockdown() now applies staminaloss only to the chest.
+ adjuststaminaloss() now has a new argument that allows you to specify a zone to apply staminaloss to. This defaults to the chest
+ apply_damage() is now capable of healing carbon mobs and human mobs.
+ Since the head has the same exact effects as the chest when disabled, and doesn't really make much sense to be affected by stamina, the head no longer has stamina.
+ The chest now has a stamina cap of 200 stamina due to the above.
+ Footsteps now sound mostly the same as they did before the hard sync
+ Jukeboxes now properly remove themselves from the active jukebox list when destroyed
+ Server operators and badmins can now make the server play like TG by toggling the stamina buffer on/off using the DISABLE_STAMBUFFER config option.
+ Airlock wires now work as they did prior to the hard sync
+ The thing you're currently grabbing is now taken into account when left-click disarming. Things you have grabbed now roughly have a 45% chance to be disarmed.
+ Disarm push rolls are now determined by the target's staminaloss rather than a flat number.
+ When you're in combat mode, pushing someone who isn't in combat mode is a guaranteed knockdown. Hard counter to stam regen squeezing in melee combat.
+ Failed disarm push attempts now deals light staminaloss to the target so long as both the attacker and target are standing. The total stamloss dealt to the target is random, clocking in at a very inefficient 1-5 stamloss per unsuccessful push attempt.
+ Disarm pushes now play the thudswoosh sound regardless if they're successful or not. Had it not been for copyright, I would've used L4D's melee sound.
+ Disarm push attempts are now logged
+ Autostand no longer makes you invulnerable to dropping items when being knocked down with a force greater than 80
+ You can no longer abuse an href exploit to return from the labor camp before obtaining enough points to satisfy your point goal.
+ Norko's donor item is now listed in the right category
+ The medihound sleeper now has a non-vore variant. This will be used by default. The old voracious variant will only appear if both the person being sleeper'd and the medihound have the voracious hound sleepers pref enabled. Sprites by Toriate
+ "Allow medihound sleeper" is now labelled "Voracious medihound sleepers", and is now off by default
+ AOOC no longer prints to players in the lobby
+ Human tails and human ears now save again. Humans now use mam_tail and mam_ears for their snowflake bits instead of tg's equivalent, just as they did prior to human tail and ear saving breaking
+ Disarm pushes no longer deal staminaloss to resting targets
+ You can no longer force a hard stamcritted spaceman to stand by clicking them with help intent. Get more creative if you want to torture someone that's in hard stamcrit.
+ The revolution gamemode now waits until the 20 minute mark before checking for win conditions.
+ You can no longer resist/move out of grabs while you're resting. Disarming your way out still works, though.
+ Stamina damage now has diminishing returns on people who are in hard staminacrit with the addition of a new multiplier. When you take staminaloss while in hard staminacrit, you'll be under the effects of the new multiplier, which reduces the amount of staminaloss you take from all sources of staminaloss. The diminishing returns multiplier will steadily return to 1 once you're out of staminacrit.
+ You can now scramble while resting. You can do this by dragging your spaceman onto an adjacent turf. This works even if you're in staminacrit, but the timer depends entirely on your staminaloss.
+ Fully augged cyborg people now heal stamina damage properly.
+ Job EXP is now tracked properly for all roles.
+ Nightmares and shadowpeople have had their light threshold for being considered in darkness reduced. Nightmares can no longer stand unharmed next to a light fixture during a nightshift 100% unharmed. The threshold is high enough so that APC lights on their own won't harm a nightmare, but being on the edge of a light source will.
+ The detective revolver's .38 bullets are now non-lethal again, but now require 3 shots to hard stamcrit
+ The current lethal variant of the .38 bullets can still be printed at sec protolathes.
+ You can now access ghost roles from the latejoin menu.
+ Eyeblur now scales depending on how much actual eyeblur you actually have.
+ Ebows now induce 50 drowsiness on whatever they hit.
+ Telepads have been buffed across the board. T1 parts on a launchpad still grants you a range of 15 tiles, but T4 parts now grant you a pretty large 60 tile range (up from their original 18 tile range). Briefcase launchpads were also buffed, they now have a range of 20 tiles, up from their previous laughable 8 tiles.
+ The grace period for the revolution win condition check has been reduced from 20 minutes to 10 minutes. You don't need to wait nearly as long for the round to end if no heads join in.
+ You can now select plural and neuter as your gender. They're labelled "non-binary" and "object" in the character customization menu, respectively.
+ A lot more light sources now use the same nonbinary colored lighting philosophies as flashlights and light fixtures!
+ Flashlights mounted to guns and helmets now retain the same color and power as their original light. Lavaland's caves will reflect a fluorescent blue as you shine your KA around, and sec's helmets are now capable of illuminating maint in that fancy fluorescent blue.
+ Cameras now shine a fluorescent blue when lit up by an AI
+ Glowing goo now actually glows green.
+ Candles had their power reduced from 1 to 0.8.
+ Lighters now shine a little further, and are now properly colored.
+ PDAs now shine an incandescent yellow to match their sprite.
+ Welding tools now shine an appropriate color
+ Hardhats now shine an incandescent yellow.
+ Plasmaman helmets now shine an incandescent yellow.
+ Microwaves no longer overpower literally every single light in the game, instead having a power of 0.9.
+ Borgs now have incandescent yellow lights to match their sprites
+ Bots now shine a fluorescent blue light
+ Airlock light overlays are now on the above lighting layer. This means airlock lights can actually be seen in the dark now.
+ The mob spawners list no longer leaves null entries behind when a spawner has a job description defined. The latejoin menu will no longer show ghost roles that are filled, and the spawners menu actually works again.
+ The voting system now actually tracks who voted for what. This means it's now possible to change your vote, and it's possible to see what you voted for.
+ Using help intent on someone that's in hard stamcrit will now make them heal 15 stamloss.
+ Auto fit viewport is now enabled by default for new players. One less question off the FAQ
+ The Khajiit favorite, Skooma, was added as a chemistry recipe that can be produced with cooperation between chemistry and either cargo or service. If you want to spoil the recipe for yourself, take a look at the PR for it!
+ When the shuttle leaves for centcom, a vote will be started to select the next map instead of the map being randomly chosen via biased voting methods
+ If a server operator wishes to re-enable the biased TG preference voting system, you can do so by toggling the TGSTYLE_MAPROTATION config flag on in the config.txt. Keep in mind that doing so will bring you great misfortune.
+ Cacti in lavaland now have 6u of vitfro instead of just 4u. This lessens the gap between cacti and first aid kits, the third rarest and second rarest readily available healing methods for ashwalkers, respectively.
+ the "genitals use skintone" option now appears in the character appearance menu when appropriate again.
+ Clicking your stamina bar will now show your exact stamina along with info regarding your stamina buffer
+ The bug where ghost role spawners leave null entries in glob.mob_spawners has actually been fixed
+ The Kitchen Gun (TM) is no longer invisible.
+ The majority of cult spells no longer have exclamation marks at the end of their invocations. This means they will no longer be bound to the rules of shouting. Which means sec officers will no longer be able to hear culties sacrificing the captain from the complete opposite side of the maintenance tunnel the sacrifice is happening in. However, things like EMP pulses and runeless teleportation still have the effect due to their inherent loud nature.
+ The stun blood spell now instantly causes hard stamcrit. However, to offset this, it now also only has one charge and has a higher cost.
+ The Gloves of the North Star now restore 2/3 of the stamina used up by punches when harm intent punching. With aggressive play and good stamina buffer management, this makes it entirely plausible to roughly double your stamina regeneration per mob life process tick.
+ Revs can no longer remember the name of the person who flashed them when deconverted. This brings it in-line with the other conversion antag deconversions.
+ The bug where you can sometimes get permanently stuck in stamcrit should HOPEFULLY be fixed. I'm unable to reproduce the bug myself, but let's hope.
+ The night vision trait now grants you darksight for an entire 1:1 screen, but the alpha of the lighting plane with the trait has been increased from 245 to 250 to balance it out
+ It's now actually possible to click the stamina hud button
+ The stamina hud button now displays your stamina buffer correctly
+ Bone spears now have a reach of 2 tiles.
+ You can no longer phase through solid objects via scrambling
+ The syndicate mask now works properly as intended.
+ Stamina is no longer affected by health at all.
+ You can now right-click yourself in help intent in combat mode to instantly get up from resting. This will cost stamina equal to your entire stamina buffer. Manage your stamina well, and you'll be able to shrug off a single stray golden bolt
+ The new player panel now displays your currently selected character's name
+ Flashes no longer knockdown. Instead, they deal eyeblur and have increased confusion
+ The server's tagline is now a config option. People can now stop confusing us with BR cit
+ Attack animations will now rotate your character slightly, similar to Goon.
+ Throwing items will now perform the attack animation and play a sound
+ flashlights will now make sounds when toggled on/off
+ Things in disposals will now emit sounds every single time they hit corners. This increases immersion.
+ Air alarms now actually emit the proper light color when their status is okay.
+ Backpacks and other storage items will now jiggle and squish when you interact with them, similar to the animations seen on Goon.
+ Mops no longer have a delay on their cleaning, making them an actually viable alternative to all of the janitor's other cleaning tools
+ To balance this, mops now take stamina to clean tiles. Standard mops take 5 stamina to use, while advanced mops take 2 stamina.
+ Oh and also mops make fancy new sounds and play animations when used now
+ Pump-action shotguns now take 2 stamina per pump instead of 5 stamina per pump. This also applies to bolt-action rifles, as bolt racking counts as pumping.
+ Pickpocketing items will now place them in your hands if possible
+ Combat mode is now displayed in examine text
+ Combat mode now makes a visible message when enabled if you haven't touched your combat mode button in the last ten seconds. It's done this way to avoid chat spam from those who know how to pull off stam regen squeezing.
+ All knockdown sources will now force people to be dismounted from ridden vehicles.
+ When an item is thrown, it will now be rotated and displaced.
+ Shards of glass will now be rotated when spawned.
+ Bullet casings will now be rotated when they're ejected from a gun.
+ Bottles now have random rotations and pixel offsets when smashed via throwing.
+ Picking up an item will now reset its rotation.
+ Glasses thrown onto tables by bartenders will now have their rotation reset.
+ Slime speed potions can now only increase the speed of vehicles to be on par with sprinting speed. They can no longer make a scooter roll around ten times faster than a speeding blue hedgehog.
+ Changelings will no longer recieve team objectives
+ Changelings no longer start off with hivemind communication as an innate ability. Hivemind communication now requires 1 dna point, on par with syndicate encryption keys, which are 2 TC.
+ Hivemind link now relies on hivemind communication just like the hivemind download/upload abilities.
+ It's now only possible to zoom a gun if it's in one of your hands
+ Mobs without clients no longer cause runtimes when their eyeblur updates
+ Blood tests have been added. If a changeling has a sufficient number of loud abilities, you will be able to test their blood by heating up a sample of it. However, if the changeling has a large amount of loud abilities, attempts to test their blood will have explosive results.
+ Changelings now make a very obvious noise when readapting. This is to prevent the cheese strat of simply readapting when you get caught to avoid detection.
+ The blood splatter effect that happens when you get attacked will now always make you lose blood depending on the damage you've taken. The effect now also scales with item damage, meaning tiny little papercuts will no longer be able to cause a massive blood splatter.
+ The blood reagent will now cover items and spacemen in blood when applied to objects and mobs.
+ Helmets, masks, and neck items are all now valid targets to get splattered when you get covered in blood. Groovy.
+ The temperature notification will now take into consideration both the ambient temperature and your body temperature, increasing the responsiveness of the temperature notification and making it much more realistic.
+ Shuttle transit borders are now 10 tiles wide instead of 8 tiles, hopefully repairing the immersions that get shattered by the ability to see normal space where the transit areas end.
+ Instead of transit turfs simply teleporting things to space, transit is now handled in a somewhat realistic manner. Transit turfs now act like normal space turfs, though exiting the transit area or being present in the transit area after the shuttle moves out of transit will teleport you to space and throw you in the direction the shuttle was moving in.
+ Reservation areas are now able to designate a border turf.
+ The sprint hotkey will no longer cause you to get permanently stuck sprinting if the server lags. Just tap shift again if you get stuck
+ You can now hear sounds in the real world while inside of a VR sleeper.
+ You can now make nameless characters. Nameless characters will spawn in with their name set as their job title followed by a unique five digit number. The "Name" option in the character setup menu will be replaced with a "Default designation" option for nameless characters, and the default designation will be used in place of a job title for assistants and other jobs that don't require dress codes.
+ The out-of-game round end notification is now a little more verbose. It'll now display the round type, end result of the round, and the survival rate.
+ Xenos can no longer strip items off of people to be capable of using any item in the game.
+ also, items from pockets get placed into your hands properly now
+ A mob's last words are now properly tracked and recorded on death. The first death of the round will now actually display the victim's last words on the round end screen.
+ Divine shenanigans can no longer result in someone becoming immune to staminaloss
+ Fixed body_markings in bodyparts being assigned as a list when in reality, it's a string and literally everything expects it to be a string and uses it as a string. This should mean that markings no longer have completely fucked up caches for character preview and other things.
+ Since apparently the game is literally unplayable if items are not in the exact center of a turf, the maximum pixel variance of thrown objects has been reduced by four pixels to make things a smidge more clearer for those that dont know what a turf is.
+ Bartender glasses should HOPEFULLY no longer be tilted when landing on a table. Why the fuck is after_throw called via a timer.
+ Changeling screeches now have their own unique sounds, and are much easier to recognize.
+ Most synthetic emotes are now available to humans. *ping
+ You can now merp
+ The TEG will now only produce a meaningful amount of power if the hot pipe contains gas that's actively combusting
+ Added the "add PB bypass" and "revoke PB bypass" verbs, which allow admins to let a specific ckey to bypass the panic bunker for the rest of the round
+ Jogging is no longer treated exactly the same as sprinting for water slips. When you're jogging, you will only slip on water if you have more than 20% staminaloss.
+ The atmospherics turf subsystem now has double the wait time, which should free up server processing power for other tasks.
+ The IRC now actually displays the actual survival rate
+ Bloodcult conversions are now consensual. Convertees are given a ten second timer to accept or wait out. This should drastically improve the quality of those that get converted into bloodcult.
+ All sacrifices now count as a third of a cultist for the end-game narsie summon.
+ Nameless captains will no longer proc a "Captain Captain on deck!" message. Instead, it'll be a much more boring but much more sensical "Captain on deck!" message.
+ Transit turfs on the centcom z-level now function properly again at keeping mobs within the areas defined by their boundaries.
+ The title screen is also positioned correctly again.
+ Ghost role eligibility for both event and spawner ghost roles is now affected by DNR status. If you suicide, ghost, or cryo out, you will be unable to qualify for any ghost roles
+ Cryo now applies DNR status no matter how long the round has been going on
+ Suicide is now properly admin logged as it is supposed to be. Ghosting while alive is now also logged.
+ Sparks and igniters will now actually heat areas rather than cooling them, as was intended.
+ To alleviate some potential complaints, RPDs now have a cooldown before they can create sparks, and both RPDs and emitters produce less sparks.
+ Conversion runes will now mute the victim temporarily while they're deciding whether to convert or be sacrificed.
+ Conversion runes no longer require a third cultist to sacrifice if the victim refuses conversion
+ Staminaloss targeted at the head now properly redirects to the chest.
+ Sprinting no longer takes stam when you're being pulled or when you're in zero gravity. Other sources of involuntary movement are not affected.
+ In an attempt to improve performance during highpop, mouse movements will now only call onmousemove() while a user is in combat mode
+ Ballistic projectiles are now the only projectiles capable of emitting dinks.
+ Panic bunker toggling and bypassing is now logged in admin IRC
+ OOC and LOOC now use separate toggles. You can now use LOOC while OOC is globally toggled off, and admins now have the option to toggle LOOC off separately from OOC
+ also revamped and reorganized relevant looc adminverb code
+ The endgame narsie summon rune no longer requires 24 total sacrifices, and will now properly account for cultists that surround it
+ The succumb verb is now available in the IC tab
+ Lighting now uses a linear algorithm to calculate falloff instead of an inverse-square algorithm.
+ get_hearers_in_view() now actually caches the results of view() instead of calling view() twice
+ Goonchat's JS no longer contains checks related to a completely unused message filtering function, which should improve clientside performance quite a bit
+ The storage hud now properly takes into account the viewer's view size, meaning storage items with a large amount of storage slots will properly stretch across the bottom of the screen when running in widescreen.
+ Action buttons are now able to fill the entire screen in widescreen and other weird view sizes.
+ Omegastation's job changes will no longer be included at compile time.
+ The client update portion of /mob/Login() now double-checks to make sure client.player_details exists and is of the proper type. This should hopefully fix the "cannot read null.player_details" runtimes that can spontaneously cause clients to get kicked out and forced back to the lobby.
+ You can now quickly use unequipped items on objects by simply click-dragging the item onto the object with an empty active hand. Doing so will place the item in your hand, and then use that item on the object.
+ In an attempt to improve the performance of /mob/Stat(), various time-related procs now use defines instead of being procs that call procs that call other procs that call even more procs.
+ If a living mob has vore initialized but doesnt have voreprefs initialized, then client login will force voreprefs to load.
+ Hopefully fixed paper crash 2: electric boogaloo
+ Added unomos, which is basically listmos except gas mixtures only use one single list for handling their gasses. This is a significant performance improvement that also offers a mild memory improvement under normal circumstances.
+ Locomotion circuits are now restricted to jogging speed
+ MMI circuits and pAI circuits both now have 60 complexity, up from their original 29.
+ Biogenerators now have a sane limit for production
+ Fixed a fairly huge server crash exploit
+ Shield blobs no longer become completely invulnerable to all forms of damage after reaching a """weakened""" state
+ Taken care of what appeared to have been an oversight where shield blobs don't recover their armor after becoming weakened.
+ Nerfed concatenators by limiting the amount of characters they're able to output
+ The timer for stripping an item off of a spaceman is no longer interrupted by your active held item changing. This means you no longer have to worry about filling both of your hands when you're stripping items off of someone.
+ Ported the zulie cloak and blackredgold coat donor items from RP.
+ Normal mops now only use 2 stamina to mop a tile, nerfed from their previous value of 5 stamina per tile mopped.
+ Advanced mops now only use 1 stamina to mop turfs, from their former value of 2 stam.
+ The femur breaker now uses `*scream` instead of forced speech. This means that the femur breaker will no longer spam deadchat with "AAAAAAAAAHHHHHHHHHH!!"
+ The femur breaker will now guarantee that the victim falls into crit, which will make it harder to perform torture scenes with it since the victim can just succumb.
+ Fixed another runtime in warp whistles.
+ Spamming forged packets no longer crashes the server.
+ Things that access job_preferences now explicitly access keys, which means it no longer attempts to access invalid indices and runtimes as a result.
+ The taser's electrode has been reworked. Instead of being a strong knockdown that deals a heavy amount of stamloss, it now causes a weak knockdown, applies a debilitating status effect for 5 seconds, and deals 35 stamloss on hit up to a maximum 50 total stamloss.
+ Roundstart turrets now have a nonlethal projectile that gets used when they're set to stun and the target is resting
+ Hybrid tasers now have disablers set as their default mode.
+ There is now a 1% chance for the station's announcer to be the medibot voice instead of the classic TG announcer.
+ The map config system has been expanded to allow mappers to specify the map type, announcer voice, ingame year, and how often a given map can be voted at roundend.
+ The map vote system now takes into account map playercount limits properly.
+ Examining a spaceman, and other things that use get_examine_string(), will now actually properly show when an item is blood-stained.
+ Plasmaman tongues no longer have a maxHealth of "alien", and no longer cause the organ's on_life to always runtime.
+ Shooting a simplemob no longer causes runtimes prior to the blood effect being created.
+ Removing a filter from an object that lacks filters no longer causes runtimes.
-
WJohn updated:
+
deathride58 (Original PR by actioninja) updated:
- Added zombies to boxstation's abandoned ship.
+ Disarm pushing (combat mode right click in disarm intent) will now actually push mobs away. Knockdowns from disarm pushing are no longer rng based on the target's staminaloss. Knockdowns from disarm pushing now only happen when you push someone into another mob, a table, or a wall. Pushes will now also temporarily stop targets from using firearms, and will disarm the firearm if performed a second time. Pushes still deal staminaloss to standing targets, and won't deal a single ounce of staminaloss to resting targets.
+ You can no longer displace mobs that are in harm intent by simply walking into them. Mobs that aren't in help intent have to be disarm pushed to actually be moved.
-
YPOQ updated:
+
dtfe3 updated:
- AIs can take photos and print them at photocopiers again.
- Cult floors will not deconstruct to space
- Cult floors do not spawn rods when deconstructed
- Footprints should no longer spread out of control
+ Increased music maxlines from 300 to 600
+ Made it so any oxygen tank can be used instead of only red ones.
+ Watcher wing Trophy's effect lasts 1 second instead of 0.5
+ Pink Panties
+ Twintails
+ Schoolgirl outfits for the loadout menu!
+ Now the fox ears are located in front of hair meaning they now behave much like cat ears, that being they are on-top of the hair layer.
-
zaracka updated:
+
izzyinbox updated:
- blunt trauma causes brain damage while unconscious too
- sharp weapons no longer count as blunt trauma in all cases
+ adds VoG orgasm command using words "orgasm", "cum", "squirt", "climax"
+ adds VoG dab command using words "dab" and "mood"
+ Generic dog body marking sprite
+ colormatrix dog sprites
+ lowered the player age for command jobs to 1/3 of their previous setting
+ *bark emote
-
-
10 August 2018
-
AnturK updated:
+
jtgsz updated:
- Portable flashers won't burnout from failed flashes.
+ ported gang mode
-
Denton, Tlaltecuhtli updated:
+
kappa-sama updated:
- Added cargo bounties that require cooperation with Atmospherics, Engineering and Mining.
-
-
Naksu updated:
-
- Transformation diseases now properly check for job bans where applicable
- Fixed a bunch of runtimes that result from transforming into a nonhuman from a human, or a noncarbon from a carbon.
-
-
SpaceManiac updated:
-
- The map loader has been cleaned up and made more flexible.
-
-
nicbn updated:
-
- BoxStation science changes: Circuitry lab is closer to RnD now; cannisters, portable vents, portable scrubbers, filters and mixers have been moved to Toxin Mixing Lab. There is now a firing range at the testing lab!
-
-
-
08 August 2018
-
Denton updated:
-
- Added five new cargo packs: cargo supplies, circuitry starter pack, premium carpet, surgical supplies and wrapping paper.
- Added one bag of L type blood to the blood pack crate. Added a chance for contraband crates to contain DonkSoft refill packs.
-
-
Iamgoofball updated:
-
- The Stealth Implant was mistakenly made nuclear operatives only due to a misunderstanding of the code. This has been fixed.
-
-
Mark9013100 updated:
-
- Pocket fire extinguishers can now be made in the autolathe.
-
-
SpaceManiac updated:
-
- The power flow control console once again allows actually modifying APCs.
- Gas meters will now prefer to target visible pipes if they share a turf with hidden pipes.
-
-
daklaj updated:
-
- fixed beepsky and ED-209 cuffing their target successfully even when getting disabled (EMP'd) in the process
+ Removed racism
+ Teleporter calibration actually matters to all roundstart players
+ Slows down teleportation with the console/hub/teleporter setup if you care for your species.
+ Dedicated non-humans can now get hulk without having to become human.
+ seed
+ added obj/item/key to wallet whitelist
+ blood cult ritual daggers fit in jack/combat boots
+ voidcells can now unlock alien tech
+ rebalanced tech trees (not really)
+ hugbox (/s)
+ ashwalker spawn text now tells them "i" "c" not to leave lavaland
+ you can no longer have infinite ebows
+ kevinz forgot to nerf miasma research and cargo value after making it produce like 100x as much lmao
kevinz000 updated:
- Catpeople are now a subspecies of human. Switch your character's species to "Felinid" to be one.
- Oh yeah and they show up as felinids on health analyzers.
+ Hierophant now goes sicko mode, but hey, at least you can't be multi-hit by melee waves!
+ Racking shotguns is now more threatening.
+ Medibots no longer kill slimes when trying to heal their toxins.
+ The Syndicate started selling claymores to their agents.
+ Nerfed VTEC modules.
+ Neurotoxin no longer stuns non-carbons.
+ peacekeeper cyborgs now get a megaphone
+ Fixes storage bugs regarding reaching into things you shouldn't be able to reach into.
+ BYOND 513 preliminary support added.
+ Trashbags now only allow accessing the first 3 items. 5 for bluespace ones. experimental: Storage now allows for limiting of random access
-
-
07 August 2018
-
WJohnston updated:
+
kiwedespars updated:
- Redesigned the pirate event ship to be much prettier and better fitting what it was meant to do.
+ regenerative materia to hallucination sting
+ mindbreaker toxin as an actual chemical to hallucination sting
-
-
06 August 2018
-
Basilman updated:
+
lolman360 updated:
- Increased agent box cooldown to 10 seconds
+ NT has authorized shipments or Cotton to Megaseed Servitors. It's time to start picking, liggers.
+ missing durathread sprites
+ Added durathread jumpskirt
+ Duraskirt sprites and rolled down jumpsuit sprites.
+ Fixes an undocumented change to the naming of Plasmamen.
+ chainsaw kind of weapons and the mecha drill and the CLAMP can now be used with 100% accuracy for surgery
+ surgery tools now work on defines
+ advanced surgerytools can now switch types instead of just being faster
+ fixes bug with new surgerytools examine
-
Denton updated:
+
nicc updated:
- Omegastation's Atmospherics lockdown button now has the proper access reqs.
- Pubbystation's disposals conveyor belts now face the correct direction.
- Pubby's service techfab is no longer stuck inside a wall.
- Pubby's disposal loop is no longer broken.
- The Lavaland seed vault chem dispenser now has upgraded stock parts.
- Metastation: Extended protective grilles to partially cover the Supermatter cooling loop.
+ Exo-suit
+ SEVA suit
+ Flags for Goliath resistance and weakness
+ suit voucher
+ temp suit sprites
+ *dab
+ teg less gay maybe
-
Epoc updated:
+
ninjanomnom and WhoneedSpacee updated:
- You can now show off your Attorney's Badge
+ Some rpg affixes now have special effects
+ New RPGLoot modifiers: Vampirism which heals you when you attack, Pyromantic which sets things you hit on fire. Shrapnel which causes projectiles fired from a gun to fire projectiles in a radius when they hit something. Finally, Summoning which summons mobs that sometimes aid you in combat.
-
Garen updated:
+
original by @randolfthemeh and @twaticus, port by sishen1542 updated:
- Fixed AddComponent(target) not working when an instance is passed rather than a path
+ jumpskirts
+ more jumpskirts
+ jumpskirt/suit prefs
-
JJRcop updated:
+
original by Bumtickley00, port by sishen1542 updated:
- Fixed some strange string handling in SDQL
+ Suit storage units will now also remove radiation from mobs.
-
Jared-Fogle updated:
+
original by GuyonBroadway, SkowronX, and Arizon5. port by sishen1542 and kerse updated:
- Moths can now eat clothes.
+ Clockwork cultists may now summon forth Neovgre, the ratvrarian super weapon. This powerful mech can be summoned when applications scripture has been unlocked, boasts superior offensive and defensive capabilities, however once a pilot enters he cannot leave and is doomed to die with the mech.
+ Sexy Sprite work courtesy or SkowronX from /tg/
+ brass edits by Arizon5
+ steamy laser by kerse
-
JohnGinnane updated:
+
original by Skoglol, port by sishen1542 updated:
- Users can now see their prayers (similar to PDA sending messages)
+ Added lots of new virus cures, made cure difficulty scale more consistently. Cures are now picked from a list of possible cures per resistance level, multiple diseases at the same level no longer always share a cure. Looking at you table salt.
+ Dynamic gamemode now more auto-deadmin friendly.
-
Mickyan updated:
+
original by TheChosenEvilOne, port by sishen1542 updated:
- Drinking alcohol now improves your mood
+ Ported dynamic mode from /vg/, originally made by @DeityLink, @Kurfursten and @ShiftyRail
-
Shdorsh updated:
+
original by Tlaltecuhtli, port by sishen1542 updated:
- The previously-added find-replace circuit now actually exists.
+ rcd disk that gives rcd computer frame and machine frame designs
+ upgraded rcd in CE lockers
+ moved deconstruction to the upgrade disk, ashwalker rcd comes upgraded
-
Tlaltecuhtli (and then Cobby) updated:
+
original by actioninja, port by sishen1542 updated:
- Science Bounties are now available!
+ Medical and Security consoles now check access on worn or inhand ID instead of requiring an inserted ID
+ mining vendor now reads from ID in hand or on person instead of requiring an inserted ID
+ ORM is functional again (for real this time)
+ ORM claim points button transfers points to worn/inhand ID instead of to an inserted ID, no longer accepts insertions
+ Same for gulag consoles
-
WJohnston updated:
+
original by redmoogle, port by sishen1542 updated:
- Rebalanced the simple animal syndies on the metastation ship to be a bit less destructive of their surroundings, and downgraded the smg guy to a pistol and upgraded the other guys to knives.
+ Added support for 3 new gasses; Tritium, Pluoxium, and BZ
-
Y0SH1 M4S73R updated:
+
original by: WJohnston, Antur, Arcane, plapatin, sprites by cogwerks and edited by mrdoombringer. port by sishen1542 updated:
- windoors now have NTNet support. The "open" command toggles the windoor open and closed. The "touch" command, not usable by door remotes, functions identically to walking into the windoor, opening it and then closing it after some time.
+ THE GOOSE IS LOOSE
-
cyclowns updated:
+
r4d6 updated:
- Fusion has been reworked to be a whole lot deadlier!
- You can now use analyzers on gas mixtures holders (canisters, pipes, turfs, etc) that have undergone fusion to see the power of the fusion reaction that occurred.
- Several gases' fusion power and fusion's gas creation has been reworked to make its tier system more linear and less cheese-able.
+ Added decoratives angel wings for Mammalians only
+ Added blindfolds to the Loadout list
+ Added Decorative Wings for Humans, Felinids, Slimepersons and Lizardpeoples.
+ Change the SEVA suit & Exo-suit's descriptions
+ Batteries are now Rad-Proof like the other stock parts
-
-
03 August 2018
-
ArcaneMusic updated:
+
tigercat2000@Paradise updated:
- Added a new, shoutier RoundEnd Sound.
+ fixed invalid characters breaking chat output for that message
-
Basilman updated:
+
tinfoil hat wearer updated:
- fixed agent box invisibility
+ Added a new alien technology disk to scientist and roboticist uplinks that allows them to research the heavily-guarded secrets of the Grays.
+ Alientech is now the only Hidden alien research. To compensate for this, alien_bio and alien_engi have had their research costs doubled and now require advanced surgery tools and experimental tools respectively to research. Their export price is also halved.
+ roboticists now have brainwashing disks AND alien technology added to their role-restricted uplink section. alien technology gives them brainwashing at a much later date, so brainwashing is the much cheaper option for instant power. makes logical sense because doctors get it as well because they do surgery, and roboticists can now either choose to brainwash people for less price but less power or emag borgs for higher prices, limited uses, but higher power.
-
Denton updated:
+
ursamedium updated:
- Syndicate lavaland base: Added a grenade parts vendor and smoke machine board. The testing chamber now has a heatproof door and vents/scrubbers to replace air after testing gas grenades. Chemical/soda/beer vendors are emagged by default; the vault contains a set of valuable Syndicate documents.
- Added a scrubber pipenet to the Lavaland mining base.
-
-
Garen updated:
-
- mobs now call COMSIG_PARENT_ATTACKBY
-
-
JJRcop updated:
-
- Deadchat can use emoji now, be sure to freak out scrying orb users.
-
-
Kmc2000 updated:
-
- You can now attach 4 energy swords to a securiton assembly instead of a baton to create a 4 esword wielding nightmare-bot
-
-
Mickyan updated:
-
- added sprites for camera when equipped or in hand
- cameras are now equipped in the neck slot
-
-
SpaceManiac updated:
-
- Traps now have their examine text back.
-
-
Supermichael777 updated:
-
- Cigarettes now always transfer a valid amount of reagents.
- Reagent order of operations is no longer completely insane
-
-
WJohnston updated:
-
- Added a gun recharger to delta's white ship and toned it down from a "luxury" frigate to just a NT frigate, it's just not made for luxury!
-
-
XDTM updated:
-
- Beheading now works while in hard crit, so it can be used against zombies.
- You can now have fakedeath without also being unconscious. Existing sources of fakedeath still cause unconsciousness.
- Zombies and skeletons now appear as dead. Don't trust zombies on the ground!
- You can now make Ghoul Powder with Zombie Powder and epinephrine, which causes fakedeath without uncounsciousness.
-
-
granpawalton updated:
-
- pubby round start atmos issues resolved
- pubby departures lounge vent is no longer belonging to brig maint
- pipe dispenser on pirate ship
-
-
ninjanomnom updated:
-
- The first pod spawned had some issues with shuttle id and wouldn't move properly. This has been fixed.
-
-
-
01 August 2018
-
Basilman updated:
-
- Added the stealth manual to the uplink, costs 8 TC. Find it under the implant section
-
-
Cobby updated:
-
- Drone's Law 3 has been edited to explicitly state that it's for the site of activation (aka people do not get banned for going to upgrade station as derelict drones since it's explicitly clear now). See https://tgstation13.org/phpBB/viewtopic.php?f=33&t=18844&p=429944#p429944 for why this was PR'd
- PENLITEs are now actually spawnable in techwebs. Reminder to make sure everything is committed before PRing haha!
-
-
Denton updated:
-
- New bounties have been added for the Firefighter APLU mech, cat tails and the Cat/Liz o' Nine Tails weapons.
- ExoNuclear mech reactors now noticably irradiate their environment.
- Adjusted suit storage unit descriptions to mention that they can decontaminate irradiated equipment.
-
-
Hate9 updated:
-
- Added tiny-sized circuits (called Devices)
- added new icons for the Devices
-
-
Iamgoofball updated:
-
- Buzzkill Grenade Box Cost: 5 -> 15
-
-
Shdorsh updated:
-
- Text replacer circuit
-
-
SpaceManiac updated:
-
- The bridge of the gulag shuttle now has a stacking machine console for ejecting sheets.
-
-
Time-Green updated:
-
- You can now mount energy guns into emitters
- portal guns no longer runtime when fired by turrets
-
-
barbedwireqtip updated:
-
- Adds the security guard outfit from Half-Life to the secdrobe
-
-
granpawalton updated:
-
- Removed old piping sections and replaced with Canister storage area in atmos incinerator
- scrubber and distro pipes moved in atmos incinerator to make room for added piping
- added filter at connector on scrubbing pipe in atmos incinerator
- replaced vent in incinerator with scrubber in **Both** incinerators
- mixer placed on pure loop at plasma
- delta and pubby atmos incinerator air alarm is no longer locked at round start
- pubby atmos incinerator now starts without atmos in it
-
-
kevinz000 updated:
-
- Cameras now shoot from 1x1 to 7x7, fully customizable. Alt click on them to change the size of your photos. experimental: All photos, assuming the server host turns this feature on, will be logged to disk in round logs, with their data and path stored in a json. This allows for things like Statbus, and persistence features among other things to easily grab the data and load the photo.
- Mappers are now able to add in photo albums and wall frames with persistence! This, obviously, requires photo logging to be turned on. If this is enabled and used, these albums and frames will save the ID of the photo(s) inside them and load it the next time they're loaded in! Like secret satchels, but for photos!
-
-
-
30 July 2018
-
Anonmare updated:
-
- Upload boards and AI modules, in addition to Weapon Recharger boards, are now more expensive to manufacture
-
-
Basilman updated:
-
- fixed BM Speedwagon offsets
-
-
Cobby (based off Wesoda25's idea) updated:
-
- Adds the PENLITE holobarrier. A holographic barrier which halts individuals with bad diseases!
-
-
Denton updated:
-
- Techweb nodes that are available to exofabs by roundstart have been moved to basic research technology.
- Ripley APLU circuit boards are now printable by roundstart.
- Odysseus, Gygax, Durand, H.O.N.K. and Phazon mech parts have to be researched before becoming printable (same as their circuit boards).
- Arrivals shuttles no longer throw objects/players when docking.
- Regular fedoras no longer spawn containing flasks.
- Increased the range of handheld T-ray scanners.
- Cargo bounties that request irreplaceable items have been removed.
-
-
Garen updated:
-
- Throwers no longer deal damage
- Flashlight circuits are now the same strength as a normal flashlight
- Grabber circuits are now combat circuits
- Removed smoke circuits
- Removed all screens larger than small
- Ntnet circuits can no longer specify the passkey used, it instead always uses the access
-
-
Hate9 updated:
-
- Added pulse multiplexer circuits, to complete the list of data transfers.
-
-
Jared-Fogle updated:
-
- NanoTrasen now officially recognizes Moth Week as a holiday.
- Temporarily removes canvases until someone figures out how to fix them.
-
-
Mickyan updated:
-
- Social anxiety trigger range decreased. Stay out of my personal space!
- Social anxiety no longer triggers while nobody is around but you
-
-
WJohnston updated:
-
- Redesigned the metastation white ship as a salvage vessel.
-
-
YoYoBatty updated:
-
- SMES power terminals not actually deleting the terminal reference when by cutting the terminal itself rather than the SMES.
- SMES now reconnect to the grid properly after construction.
- SMES now uses wirecutter act to handle terminal deconstruction.
-
-
ninjanomnom updated:
-
- Objects picked up from tables blocking throws will no longer be forever unthrowable
-
-
-
28 July 2018
-
CitrusGender updated:
-
- Removed slippery component from water turf
-
-
Denton updated:
-
- The Odysseus mech's movespeed has been increased.
- Metastation: Spruced up the RnD circuitry lab; no gameplay changes.
- Due to exemplary performance, NanoTrasen has awarded Shaft Miners with their very own bathroom, constructed at the mining station dormitories. Construction costs will be deducted from their salaries.
-
-
Mickyan updated:
-
- insanity static is subtler
- neutral mood icon is now light blue
-
-
SpaceManiac updated:
-
- Cyborgs and AIs can now interact with items inside them again.
-
-
Tlaltecuhtli updated:
-
- Mouse traps are craftable from cardboard and a metal rod.
-
-
WJohnston updated:
-
- Syndicate and pirate simple animals should have stats that more closely resemble fighting a human in those suits, with appropriate health, sounds, and space movement limitations.
- Pirates in space suits have more modern space suits.
-
-
-
27 July 2018
-
ShizCalev updated:
-
- Destroying a camera will now clear it's alarm.
-
-
ninjanomnom updated:
-
- The cargo shuttle should move normally again
+ Gas icons changed.
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index c75712610c..75cb5f4040 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -20597,3 +20597,2525 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
the released item in your hand.
yorpan:
- rscadd: Brain damage makes you say one more thing.
+2019-11-04:
+ 4dplanner, MMiracles:
+ - tweak: Wizard shapeshift now converts damage taken while transformed
+ - bugfix: transform spell transfers damage correctly instead of healing most of
+ the time
+ - bugfix: 0% simplemob health maps to 0 carbon health, 100% simplemob to 100% carbon
+ - bugfix: transforming to a form with brute resistance no longer heals you
+ - bugfix: transforming back to a species with brute resistance no longer heals you
+ AdmiralPancakes1:
+ - rscadd: 'Cryo cell shortcuts: alt-click toggles the doors, ctrl-click toggles
+ the power'
+ Alonefromhell:
+ - rscadd: Ported Oracle UI, a framework for self-updating and neat UI's
+ - refactor: Paper now uses OUI
+ - refactor: Bins now use OUI
+ - bugfix: fixes tootip offset
+ AnalWerewolf:
+ - rscadd: Fritz plushie
+ - rscadd: Donor item
+ Anonymous:
+ - imageadd: 'More crusader armor variants to pick from armament: Teutonic and Hospitaller.'
+ Arturlang:
+ - rscadd: You can now use CTRL and ALT click on pumps and filters to toggle them
+ on and off and max their output respectively
+ - rscadd: You can now use RPDs on windows and grilles.
+ - rscadd: The RD can now suplex a immovable rod. Good fucking luck.
+ - bugfix: Fixes high alert ERT suit sprites. You can see them now!
+ - rscadd: Traitor codewords are now highlighted for traitors.
+ - rscadd: You can now examine pumps filters and mixers to see if you can use CTRL
+ and Alt click on them.
+ - bugfix: Fixes brain damage/trauma healing nanites so they actually work while
+ there are only traumas.
+ - tweak: Advanced toxin filtration nanites now heal slimes
+ Bhijn:
+ - rscadd: It's now possible to forcefully eject the occupants of a dogborg's sleeper
+ by using a crowbar on them. This action is instant.
+ - tweak: Resist values for dogborg sleepers have been adjusted. The baseline has
+ been decreased from 30 seconds to 15 seconds. Medihound sleepers have a resist
+ timer of 3 seconds. Sechound sleepers retain a resist timer of 30 seconds.
+ - tweak: It now takes 10 full seconds to insert people into your sleeper. This should
+ hopefully give people some more room to breathe and react to a dogborg attempting
+ to sleeper someone either for no reason or in a way that violates law 2.
+ - bugfix: Warp whistles no longer grant permanent invulnerability and invisibility
+ - bugfix: You can now actually use the resist hotkey to resist out of handcuffs.
+ Woah, revolutionary
+ - bugfix: the `!tgs poly` command now actually works
+ - rscadd: Poly now has a 0.01% chance per squawk to speak through the TGS relay.
+ - balance: The point production mode of radiation collectors has been reverted to
+ the original behavior of using all of the stored power every process cycle instead
+ of just 4% of it
+ - tweak: Radiation collectors now display the amount of power/research points they're
+ producing per minute rather than per process cycle, which should hopefully clear
+ up a lot of confusion.
+ - tweak: Radiation collectors also display what's happening to the gas within them,
+ which should make it a lot more obvious as to how you get tritium.
+ - tweak: Security borgs and K9s are now only available during red alert or higher.
+ - server: Headmins or other folks with access to the server's config can choose
+ the minimum alert level for secborgs to be chosen via the MINIMUM_SECBORG_ALERT
+ config option. See the default game_options.txt for more info.
+ - bugfix: The server no longer attempts to check if the CID matches the IP of any
+ bans, or if the IP matches any CIDs of any active bans, during client analyzation
+ - balance: Vampires can now only ventcrawl in bat form if their blood level is below
+ the bad blood volume (224 blood total)
+ - balance: Vampires now only take 5 burn per mob life cycle while within chapel
+ areas, down from the original 20 burn per life cycle.
+ - tweak: K9 pounces have received a minor rework. It now has an effective cooldown
+ of 2.5 seconds, can now only deal up to 120 staminaloss, deals a maximum of
+ 80 stamloss on hit, has a spoolup of half a second, and now has telegraphing
+ in the form of a quiet noise.
+ - balance: K9s now only have 80 health
+ - balance: Secborgs (but not k9s) now have a hybrid taser. This can be toggled via
+ server config.
+ - tweak: The disabler cooler upgrade now applies to all energy-based firearms for
+ borgs
+ - rscadd: Dogborg jaws are now capable of incapacitating targets if using help intent.
+ This deals a hard stun depending on how much staminaloss the target has, and
+ whether or not they're resting. This behavior can be toggled via server config.
+ - balance: K9 jaws now have 15 force, up from their nerfed 10 force.
+ - balance: Borg flashes regained their ability to cause knockdown. This can be toggled
+ via server config.
+ - server: The WEAKEN_SECBORG config option will disable the new dogborg jaws mechanic
+ and make secborgs spawn with a standard disabler.
+ - server: The DISABLE_BORG_FLASH_KNOCKDOWN will disable the ability for borg flashes
+ to knockdown.
+ - tweak: Jukeboxes now have 6 audio channels available to them, up from the previous
+ accidental 2 and previously intended 5 channels.
+ - bugfix: Jukeboxes now work again on clients running versions higher than 512.1459.
+ - bugfix: People will no longer have their ears consumed by an eldritch god if multiple
+ jukeboxes are active and the first jukebox in the jukebox list stops playing,
+ then tries to play again
+ - tweak: Instead of the debug text for invalid jukebox behavior being printed to
+ world, the debug text is now restricted to the runtime panel.
+ BurgerB:
+ - tweak: Tweaked the UI of the loadout to be less cluttered due to an issue with
+ formatting.
+ BurgerBB:
+ - rscadd: Adds the bonermeter; a device that measures arousal based statistics.
+ - refactor: Added a new input to the electrostimulator that controls the strength
+ of the shock. It accepts negative inputs which reduce arousal. Added a new output
+ to the electrostimulator that displays the amount of arousal gained.
+ - balance: Rebalanced the electro-stimulator to be less spammy by giving it a 2.5
+ second enforced cooldown per circuit contraption. Increased the complexity of
+ electro stimulator from 10 to 15.
+ - refactor: Reworked the Vent Clog event to spray smoke instead of foam, also made
+ it shoot smoke over time instead through each vent instead of all at once.
+ - tweak: Increased the spawn area of the City of Cogs (Reebe). This does not affect
+ the area in which builders can build.
+ - balance: Significantly tweaks the Wizard race transformation event to be less
+ unreasonably troublesome.
+ - rscadd: Adds a new 0 cost trait that makes you immune* to Crocin and Hexacrocin
+ - tweak: Tweaks how slurring works so it's more of a gradual change into slurring
+ instead of immediate.
+ - balance: Slurring is now directly proportional to your drunkenness, with other
+ sources of slur being added on top of it.
+ - tweak: Bras are now separate from underwear, meaning you can mix and match bras
+ if you're into that.
+ - tweak: Men can wear female accessory clothing, and females can wear men accessory
+ clothing. It's not a fetish, mom, it's PROGRESSIVE.
+ - code_imp: Reorganized accessories into their own files to prevent a massive 1000
+ line file.
+ - server: i'm 10% sure that merging this PR will cause preference corruption sooooooooooo
+ I just need to hear from @deathride58 or perhaps someone else on how much damage
+ this could possibly do.
+ - tweak: Tweaked penis.
+ - balance: Rebalanced penis.
+ - rscadd: 'Added the following reagents to the common list of vent clog reagents:
+ ~~Cooking Oil~~, ~~Frost Oil~~, Sodium Chloride, Corn Oil, Uranium, Carpet,
+ Firefighting Foam, semen, femcum, tear juice, strange reagent, ~~spraytan~~.'
+ - balance: Vent Clog smoke emits the same transparent smoke as a smoke machine,
+ including how much it transfers. Vent Clogs also do not trigger in areas deemed
+ "Safe" in code, such as in the dorms or trusted areas where dangerous things
+ shouldn't occur.
+ - rscadd: Adds additional random brain damage text
+ - rscadd: Adds penis enlargement pills.
+ - rscadd: Adds Stun Circuit and Pneumatic Cannon Integrated Circuits
+ - bugfix: Fixed extinguisher and smoke circuits not accepting any reagents.
+ - rscadd: Adds a few important clockcult tips.
+ - rscadd: Added Mech Sensors, a brass-created trap that activates when a mech not
+ controlled by a cultist crosses it.
+ - rscadd: Added power nullifiers, an emp trap that emps everything in a 3x3 area,
+ with the center suffering a heavy EMP.
+ - tweak: Brass Skewers now deal 50 damage to mechs.
+ - balance: Ass slapping only works if you're actually behind the target. Ass slapping
+ now respects disarm blocking. You can no longer face/ass slap someone on an
+ intent other than help, unless they are also face/ass slapping.
+ - bugfix: Fixed ass and face slapping grammar.
+ - rscadd: Adds meh effects for ass and face slapping.
+ - tweak: '"Unwillingly" eating food now sends a warning message instead of a notice.
+ Unable to stuff food down your throat sends a danger message instead of a warning
+ message.'
+ - rscadd: Adds clockwork reflectors, a fragile anti-laser reflection shield object
+ that can be constructed for 10 brass sheets. Upon firing on the object in the
+ direction where it is shielded, it ricochets the bullet off of it relative to
+ the shooting angle.
+ - tweak: Renames some windows in the build menu for consistency.
+ - balance: Clockwork Cult walls can no longer be deconstructed by RCDs when heated.
+ - rscadd: Adds several new toy loot to the arcade machine.
+ - balance: Rebalanced the arcade machine loot. Battlemachines now have a 0.5 second
+ delay instead of a second delay between actions.
+ - bugfix: Fixed a bug that would not allow the one in a million pulse rifle to spawn.
+ - rscadd: Adds a new trait "Buns of Steel" that makes you immune to the effects
+ of ass slapping, and temporarily makes the user's arm useless like a stun baton
+ hit. It costs 0 points.
+ - balance: Ass slapping blowback from the Buns of Steel perk now deals 20 stamina
+ damage instead of 50, and no brute damage.
+ - rscadd: Gamemode voting results are displayed at the end-round screen.
+ - balance: Cloning no longer gives you positive mutations, but a chance for a negative
+ one. Cloning has a chance to "scramble" your visual DNA.
+ - balance: Chestbursters no longer give and remove your brain. They just disembowel
+ and kill you now.
+ - bugfix: Fixes WarOps miscalculating players.
+ - balance: Activating the nuclear device during war-ops informs the crew of the
+ nuke's position.
+ - rscadd: The alert level is displayed at the job selection screen.
+ - balance: Central Command informs you when a Meteor Storm is about to hit 5 to
+ 10 minutes before it happens.
+ BurgerLUA:
+ - code_imp: Added a new framework for reagents. Reagents can now have a bool that
+ determines if it can be detected by handheld medical analyzers. Currently only
+ the changeling sting chemical does this.
+ - balance: Made changeling transformation string last between 10-15 minutes. Lowered
+ the dna cost of changeling sting from 3 dna to 2 dna. Lowered the chemical cost
+ from 50 to 10. Lowered the loudness from 2 to 1. Changeling sting transformation
+ can be removed via high doses of calomel.
+ - bugfix: Fixed most reagents having a placeholder color.
+ - bugfix: Fixed autolathe wires not correctly shocking you when pulsed.
+ - balance: Rebalanced special jetpacks.
+ CalamaBanana:
+ - rscadd: Added Deer taur
+ - rscadd: Added Elf ears to mammals
+ CameronWoof:
+ - rscadd: Medihounds now have rollerbeds for non-vore patient transport
+ - bugfix: The closed O2 crate now uses the same color scheme as the open one
+ - tweak: air alarms are green now instead of blue when the atmosphere is ideal
+ - tweak: Hexacrocin overdose no longer causes climaxes
+ - tweak: Altered the icons for inventory backplates. Sleek! Stylish! New!
+ - bugfix: Attaching a beaker that contains water to an IV stand no longer causes
+ a visual glitch
+ - tweak: Fluid-producing sexual organs no longer start full
+ - tweak: Sexual organ fluid capacity decreased from 50 to 15
+ - tweak: Sexual organ production rate decreased from 5u to 0.035u per two seconds.
+ - tweak: Sexual fluid decals no longer contain reagents
+ - tweak: Sexual fluids cannot by synthesized (e.g., by the Odysseus)
+ CdrCross:
+ - rscadd: Adds the ability for cloning consoles to read and write record lists to
+ the circuit board, and provides a template for giving other machines local circuit
+ board memory.
+ Cebutris:
+ - rscadd: Hugs of the North Star! Get them from the arcades (if you're lucky) and
+ hug your friends at INCREDIBLE hihg speeds!
+ - bugfix: Tea Aspera now properly contains tea powder
+ - tweak: Breasts no longer lactate by default, lactation is now a preference
+ Chayse:
+ - tweak: Changed the Warden's compact combat shotgun to instead be a regular combat
+ shotgun with a foldable stock and penalties for being folded.
+ - rscadd: Assorted space-worthy helmets can now act as masks for internals.
+ - refactor: Internals code can now check any item with the ALLOWSINTERNALS flag
+ through the GET_INTERNAL_SLOTS define. For now this only checks head and mask
+ slots, since those are the most realistically speaking usable ones.
+ - tweak: Medbay doors can now be opened by anyone from the inside without having
+ to press the exit button.
+ - bugfix: Borgs now have the necessary dexterity to unbuckle people from themselves
+ and from bucklable objects.
+ - bugfix: Fixes the Trek Uniform/Suit worn icons
+ - bugfix: AIs can now once more talk through holopads successfully
+ Code-Cygnet:
+ - rscadd: Added new things - Mind trait, alcohol reagent, chemical reagent, drink
+ sprite and recipe.
+ - imageadd: added commander_and_chief sprite to drinks.dmi
+ Coolgat3:
+ - tweak: Changed player number checks to 20 from 24 for cult and clockcult, also
+ made nukeops 28 required players instead of 30.
+ - tweak: Changed enemy minimum age from 14 to 7
+ - rscadd: Added the code for the semen donut and made it craftable
+ - imageadd: Added the donut sprites
+ - bugfix: Made the sec and warden berret offer as much protection like the helmet
+ - rscadd: Added berets for all the heads.
+ - imageadd: Added sprites for the berets.
+ - code_imp: Coded the berets to spawn in appropiate lockers.
+ - tweak: Raised the ripley's movement speed and lights range by 1, also lowered
+ its armor to compensate.
+ - rscadd: Added combat gloves sprite
+ - imageadd: Added said sprite
+ - imageadd: added combat boots sprite
+ Coolgat3 / Avunia:
+ - rscadd: Made kindle put the target into stamcrit, which makes it an actually working,
+ useful stun.
+ - rscadd: Added a stamina loss modifier to the vanguard spell which makes the user's
+ stamina drain at a way slower rate. This doesn't make them immune to tasers,
+ but it takes a few hits to actually get them to fall down.
+ - tweak: Made it so that clock culties don't start with a chameleon suit. Instead
+ they start with an engineer suit which is pretty much the same sprite and looks.
+ If this is not perfect, then I am willing to make a slightly more brass-colored
+ version of the engineer suit sprite and call it a ratvarian engineer jumpsuit.
+ - balance: Increased the cost of vanguard, as it is now a spell that works somewhat
+ like adrenals, minus the move speed, making your stamina drain really slow and
+ making you unable to get knocked onto the ground by just a single taser shot.
+ - balance: Lowered the charge time of kindle, reason being that you can usually
+ have only one active spell on you, or two at max if you decide to run two slabs,
+ but the fact that kindle silences people for such a small amount of time makes
+ up for it, in my opinion.
+ - server: Figured out that the consoles and their warp function actually work with
+ the current code. The thing that makes them not work is when the gamemode is
+ ran on debug mode, without the required players to actually support it. It also
+ breaks the ark timer which is stuck on -1 seconds until activation. Whenever
+ the gamemode starts properly, like any other gamemode, with player checks and
+ all, everything seems to work just fine.
+ CydiaButt13:
+ - rscadd: Lamp Plushie to loadout
+ - imageadd: added plushie_lamp to plush icons
+ - code_imp: added Lamp Plush to loadout and icons and items
+ EgoSumStultus:
+ - bugfix: Fixed blood chiller's inhand
+ - bugfix: FIXED SHIELF
+ - bugfix: fixed magpistol magazine sprites
+ - rscadd: Added the Femur Breaker
+ - rscadd: Adds male AI vox.
+ EmeraldSundisk:
+ - rscadd: Adds a gun range to Box Station
+ - rscadd: Provides some extra power grid connections
+ - rscdel: Sunglasses and Earmuffs removed from the Warden's Office - they can be
+ found at the range instead
+ - tweak: Rearranges a few objects within the prison as to accommodate the new gun
+ range
+ - rscadd: Adds a mass driver to Delta Station's chapel
+ - rscadd: Adds a second means of entry into the chapel
+ - tweak: Slightly expands the chapel to make room for the driver, slight adjustment
+ to air systems
+ - tweak: Clears a path in the station exterior for the mass driver to work properly
+ - tweak: Nearby maintenance loot has been relocated to accommodate the chapel expansion,
+ surrounding area has been "cleaned up" somewhat
+ - tweak: CentCom has noticed the lack of coffins in Delta Station's chapel and provided
+ some, but in exchange for reducing the chapel morgue's capacity.
+ - tweak: Fixed a maintenance door the chaplain should have been able to open.
+ - bugfix: 'Fixes space areas outside the driver removal: CentCom Defense Analysts
+ have ordered the maintenance hatch to the Mass Driver room be removed citing
+ "security concerns".'
+ - rscadd: Increases the number of plots to 9 (from 5)
+ - rscadd: Additional lighting placed directly outside the garden
+ - tweak: Cleans up the area to reflect use. Moves the seed extractor to a more central
+ location
+ - tweak: 'Relocates the seed packs on botany''s counter to the garden removal: Removes
+ wooden barricades outside the garden'
+ - config: Renames "Abandoned Garden" area designation to "Maintenance Garden", but
+ does not replace the icon in Dream Maker
+ - rscadd: Expands the chapel mass driver room to make it easier to use
+ - rscadd: Rearranges the chapel backroom so there are now six coffins and burial
+ garments roundstart
+ - tweak: Cleans up the Janitor's office
+ - tweak: Readjusts the station exterior so mass-driven coffins (hopefully) have
+ less friction
+ - bugfix: Adds a fan to the chapel driver
+ - bugfix: The Janitor missed a few spots around the newly renovated Maintenance
+ Garden
+ - bugfix: Readjusts positioning of Delta's QM keycard device
+ - bugfix: 'Cleaned up a few spots I missed in #9356, particularly around the janitor''s
+ office'
+ - rscadd: Adds some potted plants around Box Station
+ - bugfix: 'The tile mentioned in #9409 should now be radiation-free.'
+ Fermi:
+ - bugfix: Fixes tiny runaway decimals in reagents system.
+ - bugfix: 'SDGF: Fixes infinite clones.'
+ - bugfix: fixed an angery PR
+ Fermis:
+ - rscadd: Added a panda simplemob
+ - bugfix: fixes empathy exploit.
+ - rscadd: Added the secbat, a box to hold it and the ability to dispense it from
+ the SecTech vendor.
+ - rscadd: Adds 3 new music tracks.
+ - tweak: tweaked Neurotoxin
+ - balance: added more depth to Neurotoxin
+ - bugfix: fixed the inability to create Neurotoxin
+ - bugfix: fixes fermichem reactions for tiny volumes work
+ - tweak: makes quantisation level for chemistry finer
+ - tweak: re-enables femichem explosions in grenades.
+ - tweak: adds nuance to the SDGF and hatmium explosions.
+ - bugfix: Fixes analyse function on ChemMasters to correctly display purity.
+ - bugfix: Fixes the custom transfer for buffer to beaker button.
+ - rscadd: 'Debug option: Generate Wikichems'
+ - rscadd: graft synthtissue surgery, new reagent synthtissue
+ - tweak: 'neurine fixes brain objs merge: combines fermichem''s lung damage with
+ tg''s'
+ - rscadd: on_mob_dead(), bitflags and CHECK_MULTIPLE_BITFIELDS
+ - refactor: refactored fermichem vars, moved impure chems into their own reagents
+ subtype
+ - bugfix: Fixes small residues of chems that won't go away!
+ - tweak: tweaked beaker health and allows use of syringes/droppers on chem_heaters
+ - soundadd: added a sound for when beakers take temperature damage.
+ - imageadd: added some icons for melting beakers
+ - refactor: refactored how beakers take damage
+ - bugfix: fixes how beakers would only take one instance of damage on pH damage
+ - bugfix: fixes Janitor grenades.
+ - bugfix: fixes reaction mechanics at low volumes
+ - bugfix: stops reactions constantly bubbling on the edge of reaction temperature
+ - bugfix: stops small amount reactions from occurring, and prevents disappearing
+ tiny numbers
+ - tweak: Reduced minimum reaction volume from 1 to 0.01
+ - refactor: cleaned up Fermichem
+ - rscadd: Adds Jacqueline the Pumpqueen and her familiar Bartholomew for the spooky
+ season
+ - soundadd: Adds a giggle
+ - imageadd: 'Adds cauldron, Jacq and Jacq o lanterns, and a costume for halloween!
+ mapedit: adds a new landmark so Bartholomew can spawn somewhere sensible.'
+ - bugfix: fixes food reactions and explosion runtimes,
+ - bugfix: fixes the too much yes problem
+ - bugfix: Heart, Tongue and stomach regen.
+ - bugfix: lung damage threshholds.
+ - bugfix: Graft synthtissue
+ - bugfix: Skeleton's burning for no reason
+ - bugfix: Organ freezing handling.
+ - bugfix: Fixes chemistry books to point to the right wiki, and keeps tg's just
+ in case
+ - tweak: Changes top right wiki button location to go to both wikis
+ - bugfix: fixed Jacq's fondness for the AI
+ Ghom:
+ - code_imp: minor clean up on hydroponics reagent containers.
+ - bugfix: fixes the perpetual lack of moisture that has affected genitalia descriptions
+ since, like, forever.
+ - rscadd: implements the arousal state for mammary glands.
+ Ghommie:
+ - bugfix: Fixes many possible situations of null icons for cit races' bodyparts.
+ - imagedel: Removes duplicate slimepeople' sprites.
+ - code_imp: Purges that draw_citadel_parts().
+ - code_imp: Fixes ISINRANGE_EX using the wrong relational operator.
+ - tweak: The kindle status effect stun duration now properly proportional to the
+ owner's remaining health.
+ - tweak: Clockwork cult's kindle now affects silicons.
+ - tweak: Cyborg mounted disablers/tasers/lasers now slowly self-recharge off the
+ cyborg user's power cell instead of draining from it directly.
+ - tweak: Borg rechargers now properly recharge the borg module's energy guns.
+ - bugfix: Prevents a couple more special/mounted guns from being preserved on cryo
+ - balance: Halved borg energy guns self-recharge delay and increased their cell
+ capacity by 3/4
+ - bugfix: Fixes chemical patches always checking the suit slot even if the targetted
+ limb was the head.
+ - bugfix: Skeleton, nightmare and golem races are once again available to get chemical
+ patches applied onto.
+ - rscadd: Adds two cartons of space milk to the space skellie pirates cutter's fridge.
+ - refactor: Refactored implants to not be located inside mobs codewise, akin to
+ organs.
+ - bugfix: Fixed gps tracking implants.
+ - bugfix: Fixed item not being dumped out of storage implants onto the owner's turf
+ upon removal.
+ - bugfix: Fixes cult potentially stalling if the target is erased from existence
+ without being sacced.
+ - balance: Nukes the stunprod's 3 seconds delay.
+ - bugfix: Fixes teleprods.
+ - bugfix: Stops pulls of resting mobs breaking off whenever you swap turfs with
+ someone else because of crawling delays.
+ - bugfix: fixes IAA.
+ - balance: EMPs now flick off stunbatons, they can be turned back on immediately
+ by the user anyway.
+ - balance: Stunbatons now very slowly consume charge whilst kept on, at a rate of
+ 4/1000th of a standard batoning charge cost per tick.
+ - balance: Softened up the charge cost checks to stop the above update from practically
+ reducing the maximum uses of a stun baton by one. Now, should the remaining
+ charge be lower than the hit cost, the resulting stun will be be proportional
+ to the remaining charge divided by the hitcost, within a limit under which the
+ stun batoning just won't happen.
+ - balance: Buffs condensed capsaicin, a yet another feature previously dunked by
+ stam combat.
+ - balance: speeds up pepper spray puffs.
+ - balance: Buffed krav maga leg sweep stun and stamina damage. On the other hand,
+ it's now unable to be used on already lying targets.
+ - bugfix: fixes eyestabbing people with cutlery while being a pacifist.
+ - bugfix: Reduces goonchat lag from being blasted by pellets and bullets repeatedly
+ whilst wearing armor by properly removing the armor protection texts this times.
+ - spellcheck: also reduced the size of armor protection messages in general. they
+ clog up the chat box.
+ - bugfix: Fixes stunbatons icon not properly updating on cell removal and insertion.
+ - tweak: Allows lower charge cells to be used with stun batons, and thus single
+ use crapshots batons.
+ - balance: Adds in a 7 seconds delay to the jackhammer dismantling a superheated
+ clockwork wall.
+ - tweak: escape pods emergency suits storage can now be busted open by emags or
+ excessive damage.
+ - bugfix: Fixes alt click bypassing the escape pods' suits storage lock.
+ - bugfix: Fixes emags wasting charges on un-emaggable & co stuff.
+ - code_imp: Ported some radials code updates.
+ - rscadd: Ported the RCL wiring menu and a comfier RCD interface.
+ - tweak: A milder combat stance message will show up if the user switch combat mode
+ on while on help intent.
+ - spellcheck: Properly rewords the extinguisher's instructions on how to empty it
+ on the floor since it was changed to be a screwdriver action instead of Alt
+ Click a while ago.
+ - rscadd: Reskinnable PDAs. A related game preference.
+ - refactor: Refactoring the pda, pda painter, obj reskinning and chameleon pda a
+ bit to support this feature.
+ - imageadd: more PDA sprites and ported reskins.
+ - refactor: turned virtual reality into a component datum, which is then applied
+ to spawned virtual mobs. This fixes mob transformations (such as wabbajack and
+ monkeyizing) breaking the previously hardcoded behaviour and trapping you in
+ VR, also enabling a more concrete virtual reality inception experience.
+ - bugfix: Fixes power cells being unable to be rigged. Also prevents them from starting
+ processing on init if they don't self recharge.
+ - bugfix: Fixes many, little or otherwise, issues with the stunbaton status refactor.
+ - bugfix: The sacrificial target icon will now display onto the cult objective ui
+ alert once again.
+ - bugfix: Stopping borgs from sprinting into negative cell charge.
+ - tweak: The default amount of z-levels reserved specifically for space ruin generation
+ has been increased from 1 to 2
+ - tweak: 'Moving some tablecrafting recipes to the appropriate categories: Kitty
+ ears and lizard cloche hats to "clothing"; Hot dogs to "Sandwichs"; Cuban carb,
+ fish and chips and fish fingers to "Fish".'
+ - bugfix: Fixes the not-a-sandwich recipe being M.I.A.
+ - rscadd: Adding in peanuts, peanut butter, peanut butter toasts and sandwiches,
+ and the PB&J sandwich. The peanuts contain a little bit of extractable cooking
+ oil (similarly to soy beans) and can be microwaved or dried in a drying rack
+ to make roasted peanuts, which can be mixed in a all-in-one-grinder for peanut
+ butter, required to make those sandwiches.
+ - balance: Buffed wizard and artificier's Magic Missile, wizard and xeno queen's
+ Repulse and juggernaut's Gauntlet Echo.
+ - bugfix: Fixes flashlights being unable to be used for rudimentary eyes and mouth
+ exams.
+ - rscadd: Adds in a grey jumpsuit to the loadout choices, restricted to Assistants.
+ - bugfix: Fixes CWC construct shells being visible as ghost role to latejoiners.
+ - imageadd: new sprites for the flechette gun, its magazines and the toy ray gun
+ - tweak: Merges the end-of-shift and its shuttle autocall announcements into one.
+ - bugfix: Prevents the end-of-shift shuttle from being recalled (even if to no avail).
+ - bugfix: Fixes being able to teleport papers to your location with TK.
+ - bugfix: Fixed some monkey-code shenanigeans making items sometimes disappear from
+ pickpocketing.
+ - imageadd: New sprites for the some pda cartridges.
+ - tweak: The crew monitor's entry for the Quartermaster will now appear bolded,
+ while HoP's will be of the same color of the service/unknown/other jobs.
+ - bugfix: emergency pods' storage will now properly work.
+ - bugfix: The PDA skin preference will now properly save up.
+ - tweak: Changed the default PDA icon var to match the default PDA skin preference.
+ - bugfix: Fixing the `(pointless) badassary` category appearing between the `dangerous
+ and conspicious` and `stealthy and inconspicious` categories.
+ - bugfix: Combat gloves plus now properly use the combat gloves sprite.
+ - bugfix: Fixes the space ninja's energy netting.
+ - rscadd: Adding one pAI to the wizard shuttle and ERT prep room
+ - bugfix: Fixes the rocket launcher being unreloadable.
+ - balance: Buffed its accuracy a bit.
+ - tweak: Replaced the grenade launcher emagged minesweeper loot with the rocket
+ launcher like it was originally supposed to be.
+ - imageadd: 'Tweaked the :b: emoji.'
+ - rscadd: Rubber Toolboxes.
+ - rscadd: 'Porting in two bar signs: Cyber Sylph''s and Meow Mix.'
+ - bugfix: Fixing stamina damage melee weaponry being unusable by pacifists, and
+ still damaging objects and triggering electrified grilles when thrown.
+ - refactor: refactored underwears to allow custom color preferences, instead of
+ manually colored sprites.
+ - rscdel: The aforementioned manually colored pieces. Some of your char preferences
+ may have been resetted as result.
+ - rscadd: 'More underwear choices, including: Bowling shirts, long johns, a tank
+ top, fishnets, more bee socks, bee t-shirt and bee boxers (original PR for the
+ latter three by nemvar from /tg/station).'
+ - tweak: random bodies will now have random underwear again.
+ - bugfix: Dressers will now properly change undergarment again.
+ - tweak: Toned down many species' female chest sprites to fit the smaller cups.
+ - bugfix: Fixed some body parts sprites inconsistencies, such as the W/E female
+ and male chest sprites being the same in some species, and jellypeople's legs
+ being one tile off on W/E
+ - bugfix: Fixing baklava pies a bit.
+ - tweak: Sweaters now cover groins too.
+ - balance: Improved the zelus flask to be more viable for bottle smashing than the
+ average barman's selection.
+ - code_imp: Very slight bottle smashing code clean up, stupid const vars.
+ - bugfix: Fixes krav maga gloves, wizard spells knockdowns.
+ - tweak: Added in an alert pop up to the cult convertees, on top of the older "click
+ here to become a blood cultist" chat message.
+ - tweak: The convertee's screen will now flash red to fit in the aforementioned
+ message's fluff.
+ - spellcheck: Made said message less verbose.
+ - rscadd: Towels. Crafted with 3 sheets of cloth, they can be worn on head, suit
+ and belt slots even without uniform, or laid flat on the floor. Sprites from
+ Baystation and Aurora Station.
+ - rscadd: You can combat mode right click people while wielding rags and towels
+ to pat out their flames (to no use for rags) or otherwise drying them out.
+ - balance: toned down the stamina costs of some of the bulkier weapons.
+ - code_imp: repathed hypereutactic blades to be a subtype of dual sabers. Way less
+ copypasta.
+ - bugfix: Fixing CX Shredder guns not accepting standard flechette mags.
+ - bugfix: Fixing missing magpistol magazines icon states.
+ - rscadd: sort of overhauled darkmode/lightmode to /vg/station's, also reincluding
+ the pre-existing black'n'white theme.
+ - bugfix: Fixed LOOC color, fixed .userlove and .love span classes being a bit too
+ blurry on dark mode.
+ - rscadd: The syndicate base's bathroom is now fitted with a shower, and a special
+ towel.
+ - bugfix: Fixed many issues with towels.
+ - tweak: The dry people off with rags/towels action can only be done if the object
+ is NOT moist with reagents now. Also cleans banana creaming.
+ - rscadd: Towels deal more damage while soaked with reagents.
+ - rscadd: You can now squeeze rags/towels with Alt-Click.
+ - rscdel: deleted an old and crappier towel sprite that got in the way.
+ - bugfix: Fixes Pubby's disposal conveyor belts and lack of a second lawyer spawner.
+ - code_imp: Cleaned up the absolute state of the arousal module.
+ - refactor: refactored exhibitionism into a quirk.
+ - tweak: arousal states won't persist after death.
+ - bugfix: Fixes testicles size adjective thing.
+ - bugfix: undergarments toggling now works instead of just making underwear disappear
+ and not come back.
+ - tweak: The "Always visible" genitals setting will now display them above clothes.
+ - bugfix: combat pushes will now properly stop targets from using firearms, and
+ will disarm the firearm if performed a second time, and also slow down people
+ by 15%, and won't push people on tables blocked by shutters or other dense object
+ anymore.
+ - bugfix: Fixes CHECK_BITFIELD macro.
+ - bugfix: Fixes hypovials being unable to transfer out liquids or be refilled by
+ large dispensers like water tanks.
+ - bugfix: Fixes chem-masters machineries not dispensing newly made pills inside
+ loaded in pill bottles.
+ - rscadd: Stunswords now fit in the captain's sabre sheat.
+ - rscadd: reworked ninja's stealth mode. Increased invisibility, but engaging in
+ combat, attacking or throwing things, bumping people will temporarily lower
+ it.
+ - rscadd: Ninja shoes are even stealthier.
+ - code_imp: cleaned up some 2014 tier processing code horror.
+ - tweak: the oxyloss fullscreen overlays now also take in consideration 1/5 of the
+ user stamina loss.
+ - rscadd: When you're jogging, you will only slip on water if you have more than
+ 20% staminaloss, for real this time.
+ - imageadd: Different cuffs now come with different worn overlays instead of a generic
+ one.
+ - bugfix: High luminosity eyes can now be properly deactivated and won't illuminate
+ your surroundings again until turned back on.
+ - bugfix: Fixes freshly cloned people starting with undershirts. Fixes random characters
+ possibly rolling with undergarments of the opposite gender (Doesn't affect preferences'
+ freedom of choice).
+ - balance: MRE menu 3 has cuban nachos instead of a chili now.
+ - bugfix: Removed the illustration overlay from MREs, looks pretty weird otherwise.
+ - rscadd: MRE menu 4, vegetarian.
+ - bugfix: fixes a few bad touchs on combat mode pushing.
+ - bugfix: Fixes clock cult Abscond scripture not dragging pulled mobs into Reebe.
+ Also fixes blood cult tele runes teleporting you from the source turf to the
+ source turf.
+ - bugfix: fixes clock cult mass recall.
+ - bugfix: Fixes underwear colors a bit.
+ - bugfix: Fixes Blood Cult conversion prompts
+ - rscdel: Removes an obnoxious temporary overlay var.
+ - bugfix: colorable socks can be colored again.
+ - bugfix: Fixed undergarments color preferences resetting each round.
+ - bugfix: Fixed a few dozen suits' body coverage inconsistencies. These changes
+ shouldn't affect armor and utility vests for most.
+ - bugfix: Fixed clown shoes and work boots.
+ - bugfix: Fixed some overlay bug that happens when legcuffed and then handcuffed.
+ - balance: Slowed down police baton and tele baton speed by 75%, should be still
+ be faster than the legacy speed (2 seconds) by 0.6 seconds. Telescopic batons'
+ stamina cost per swing is now on par with police batons, ergo more expensive.
+ - bugfix: Fixed undershirts n socks colors prefs.
+ - bugfix: You can now alt-click to rotate machinery such as the tachyon-droppler
+ array or emitters again.
+ - bugfix: Sofas can't be wielded and transformed back into plain chairs anymore.
+ - rscadd: Enables emojis for PDA messages.
+ - balance: Removes revenant blight's shabby toxin damage in favor of mood maluses,
+ and a dangerous necropolis curse if not cured in time. Remember
+ - tweak: Blood cult altar, forge and archives now use radial menus.
+ - bugfix: Fixed some machineries' UIs.
+ - tweak: blood and clock cultists messages from metabolizing
+ - bugfix: Fixed advanced medical scanners borg upgrades.
+ - bugfix: Fixes certain borg upgrades being unapplicable on dogborg counterparts
+ of the target cyborg type.
+ - bugfix: Fixed people being shovable hrough windows, windoors and the such.
+ - rscadd: You can now shove people into disposal bins.
+ - refactor: refactored altdisarm(), ergo the "shoving people around" proc.
+ - tweak: war ops is now lowpop friendly and doesn't require roughly 54 starting
+ players anymore.
+ - rscadd: Singularity beacons now also moderately increases the odds meteor waves,
+ while lowering their estimeed arrival countdown.
+ - bugfix: non-alphanumeric graffiti decals will no longer display as "letter".
+ - balance: Nerfs cyborg disabler and its internal power cell to hold 25 disabler
+ beam shots rather than 43/44, just like a normal disabler.
+ - bugfix: Adds some missing species_traits for cloth, clockwork and cult golems.
+ - rscadd: Added towel linen bins, found in dormitory restrooms. Also enhanced the
+ bedsheet bins found in some stations' dormitories
+ - imageadd: Resprited bedsheet bins in 3/4 perspective
+ - tweak: Made SDGF ghost poll message less verbose, made the experimental cloner's
+ complaint with the former, and added ghost poll ignore options for both.
+ - bugfix: fixing some related onmob sprites issues with the above accessory.
+ - bugfix: Teleprods work on non-carbons mobs now.
+ - bugfix: Fixed tracking implant teleport issues.
+ - balance: Increased stunbatons power cell depletion rate when left on by 50%.
+ - bugfix: Gorlex Marauders are pleased to announce non-slip grooves were given to
+ their .50 sniper rifles, and thus shouldn't accidentally flop on the floor like
+ pocket spaghettis whenever taken out of a bag anymore.
+ - bugfix: Silicons can now operate teleporter, medical and security records console
+ from a distance again.
+ - bugfix: Fixed custom say emotes conflict with drunk memes.
+ - bugfix: Fixes identity transfer (envy knife, changeling transformation, making
+ a vr avatar) not copying digitigrade legs.
+ - bugfix: Fixes temporary transformation sting triggering heart attacks on heartless
+ humans.
+ - bugfix: Fixed mobs folded inside bluespace bodybags getting their clothing and
+ items deleted when passing through a recycler.
+ - bugfix: The alien-bursting-from-your-thorax and the xeno "hud" embryo stage images
+ will now properly delete them once the embryo egg lifecycle is complete.
+ - bugfix: Fixed artificier lesser magic missile.
+ - bugfix: Phantom thief masks will now fancy your combat mode yet again.
+ - bugfix: Fixed gulag teleporter stripping the user of stuff it really shouldn't
+ (like storage implant bags).
+ - bugfix: fixing cydonian armor a bit.
+ - imageadd: Resprited wooden and critter crates.
+ - imageadd: Improved the Cyber Sylph' good yet cumbersome bar sign a little.
+ - bugfix: Cyborgs can now use camera consoles on the edge of their widescreen. These
+ consoles are also TK friendly now.
+ - imageadd: Updated gang dominator sprites.
+ - bugfix: Miner borgs can again have installed PKA mods.
+ - bugfix: Fixed invisible blackberry n strawberry chocolate cake slices.
+ - bugfix: Nuke ops / adminbus combat mechs will no longer spawn with tracking beacons.
+ - imageadd: Arcade machine directional sprites.
+ - tweak: 'lowered the arcade''s random plush / other prizes ratio from 1 : 2.5 circa
+ to 1 : 5. Dehydratated carps and the awakened plush can not be achieved this
+ way anymore.'
+ - imageadd: Added armrests overlays to sofas and tweaked their sprites a little.
+ - bugfix: Fixed dogborg sleepers. Just don't tell me what is exactly fixed, cause
+ I don't want to find out.
+ - bugfix: Buffed the deep space familiar gorilla against runtimes.
+ - imageadd: Updated ratvarian computer sprites.
+ - bugfix: Fixed storage implant transplant.
+ - bugfix: Refactored how Jacqueen teleportation destination is selected, preventing
+ them from teleporting on off-station holopads.
+ Ghommie && Kevinz000:
+ - balance: Lichdom and necromantic stone skeletons are now of the spaceproof kind
+ too.
+ - tweak: skeletons now also like dairy products.
+ - rscdel: Halloween roundstart skeletons and zombies are no more spaceproof.
+ - rscadd: You can choose to set your species to zombie or skeleton through the pride
+ mirror yet again, Alas they are not of the spaceproof kind either.
+ Ghommie (Credits to Kmc2000 for the original PR):
+ - rscadd: Porting in MRE boxes from Yogstation. But be careful, eating possibly
+ expired MREs found in maintenance comes with an unrealistically large (actually
+ small) chance of food poisoning. Otherwise just bail out and order actually
+ safe-to-eat MREs from cargo for 2000 credits.
+ Ghommie (Original PR by Dennok):
+ - bugfix: Now areas_in_z get areas spawned by templates and blueprints.
+ Ghommie (Original PR by Dreamweaver):
+ - rscadd: Nanotrasen has received word of a high-tech research facility that may
+ contain advancements in bluespace-based research. Any crew members who become
+ aware of its whereabouts are to report it to CentCom immediately and are restricted
+ from sharing said info.
+ - refactor: The turf reservation system now dynamically creates new z levels if
+ the current reserved levels are full.
+ Ghommie (Original PR by JJRcop):
+ - rscadd: 'Ports in more emojis, including : flushed :'
+ Ghommie (Original PR by LaKiller8):
+ - bugfix: Goonchat options should now save properly.
+ Ghommie (Original PR by Vile Beggar):
+ - rscadd: Warden now has an added drill hat in his locker. You can change the loudness
+ setting of it by using a screwdriver on it. Use wirecutters on it for a surprise.
+ Ghommie (Original PR by coiax):
+ - refactor: atom/var/container_type has been moved into datum/reagents/var/reagents_holder_flags.
+ There should be no visible changes to effects.
+ Ghommie (Original PR by nemvar):
+ - rscadd: Botanists can now get beeplushies (or cultivator and bucket) as an heirloom.
+ - bugfix: Clowns and mimes will now properly pick either a can of paint or their
+ brand as heirloom now.
+ Ghommie (Original PR by tralezab):
+ - bugfix: Fixes an issue with spontaneous appendicitis picking incompatible mob
+ biotypes.
+ Ghommie (Original PRs by Tortellini Tony and BuffEngineering):
+ - bugfix: E-cigs will continue to display their setting after being emagged.
+ - bugfix: Vapes now come out of the mouth. fix Fixes an E-cig initialize() runtime.
+ Ghommie (Original PRs by nemvar and Rowell):
+ - rscadd: Added beekini bras and panties, thigh-high and knee-high bee socks.
+ Ghommie (by Arkatos):
+ - bugfix: Fixed an issue with a Lizardwine drink crafting, where a final product
+ would contain unwated 100u of Ethanol.
+ Ghommie (by Floyd / Qustinnus, Arathian):
+ - rscadd: The robotocist now has robe to show his love for toasters
+ Ghommie (by nemvar):
+ - tweak: Dwarfs are now more robust.
+ Ghommie (original PR by 4dplanner):
+ - bugfix: thrown objects (but not mobs) no longer hit the thrower
+ - bugfix: mirror shield rebound no longer depends on the original thrower's momentum
+ Ghommie (original PR by 81Denton, kriskog and nemvar):
+ - spellcheck: Sleepers now show a message if players try to unscrew the maintenance
+ hatch while they're occupied or open. Fixed typos in sleeper/organ harvester
+ messages.
+ - tweak: Sleepers and dna scanners can now be pried open with crowbars.
+ - tweak: You can open and close sleepers and dna scanners by alt-clicking them.
+ - bugfix: The scanner's hatch now must be closed (on top of being unoccupied), just
+ like sleepers, before being screwdriverable. This fixes a tricky door stuck
+ issue with the machine.
+ Ghommie (original PR by AffectedArc07 and Shazbot):
+ - imageadd: Added 8 new sock styles
+ Ghommie (original PR by AffectedArc07):
+ - tweak: Religion is now a globalvar instead of being a subsystem for some reason
+ Ghommie (original PR by AnturK):
+ - bugfix: Supermatter now melt walls if it finds itself in one.
+ Ghommie (original PR by Anturk):
+ - rscadd: Recipe for fabled secret sauce can now be found in the deepest reaches
+ of space.
+ Ghommie (original PR by Barhandar:
+ - bugfix: Pumpkin meteors on Halloween now replace catastrophic meteor waves, instead
+ of ALL OF THEM.
+ Ghommie (original PR by CrazyClown12):
+ - tweak: The chloral hydrate inside of the sleepy pen is no longer slower acting
+ than chloral hydrate made in chemistry.
+ - tweak: The chloral hydrate inside of cookies synthesised by emagged borgs is no
+ longer slower acting than chloral hydrate made in chemistry.
+ - balance: Slight tirizene buff.
+ - rscdel: Delayed chloral hydrate
+ Ghommie (original PR by Denton):
+ - tweak: Nanotrasen has started shipping more types of bedsheets to its stations.
+ - rscadd: Added in Runtime, Pirate and Gondola bedsheets. The second one can also
+ be found in some pirate ships, while the last can be crafted from gondola hides.
+ - balance: You can no longer reveal the 'illegal tech' research node by deconstructing
+ .357 speedloaders, riot dart boxes, syndicate cigarettes, syndicate playing
+ cards or syndicate balloons.
+ Ghommie (original PR by Mickyan):
+ - bugfix: Fixed being unable to smother people using the damp rag
+ Ghommie (original PR by MrDoomBringer):
+ - bugfix: morgues have had their proton packs removed and as such no longer suck
+ in ghosts on closing.
+ Ghommie (original PR by MrDoomBringer, AnturK and YPOQ):
+ - bugfix: Explosions will no longer damage wizards in rod form, the supermatter
+ monitoring radio and megafauna GPS.
+ - bugfix: Supplypods no longer detonate their contents.
+ - bugfix: Fixed silicon items (e.g. cyborg modules) being destroyed by explosion
+ epicenters.
+ Ghommie (original PR by Naksu):
+ - code_imp: get_area() is now a define rather than a proc.
+ Ghommie (original PR by Nicjh):
+ - rscadd: Abductor console's select disguise option now uses a radial
+ Ghommie (original PR by ShizCalev):
+ - bugfix: Pineapple haters/lovers will get/no longer get pineapple pizzas respectively
+ from infinite pizza boxes.
+ - bugfix: As a non-human mob, hovering your cursor over an inventory slot while
+ holding an object in your active hand shouldn't runtime now.
+ Ghommie (original PR by Skoglol):
+ - code_imp: New helper proc for alt-click turf listing, bypasses any interaction
+ overrides.
+ - code_imp: Ghosts and revenants now use the new proc.
+ - bugfix: Ghosts can no longer toggleopen sleepers, adjust skateboard speed or close
+ laptops
+ - bugfix: Revenant can now alt-click turf to list contents.
+ - tweak: Revenant now slightly less nosy, use shift click to examine.
+ - tweak: Alt-clicking the same turf again no longer closes the turf listing tab.
+ - bugfix: Reduced ventcrawl lag greatly.
+ - bugfix: Mining bags will no longer drop ore into backpack.
+ - bugfix: Mining bags in backpack no longer interferes with other mining bags.
+ - bugfix: Fixes some storage size circumventions.
+ - tweak: Moved machine and computer frames below objects, parts are now always on
+ top.
+ - tweak: Moved structures (chairs, closets, windows, cult altars etc etc) below
+ objects.
+ - tweak: Moves mineral doors to airlock layers
+ - tweak: morgue/crematorium trays' layers shouldn't overlap bodybags' anymore.
+ Ghommie (original PR by SpaceManiac):
+ - bugfix: Disassembling a chem dispenser for the first time will no longer always
+ yield a fully-charged cell.
+ Ghommie (original PR by Swindly):
+ - rscadd: Arm-mounted implants that contain more than one item use a radial menu
+ instead of a list menu.
+ Ghommie (original PR by Tlaltecuhtli):
+ - bugfix: Other people's clothes burning no longer spam you
+ Ghommie (original PR by XDTM):
+ - bugfix: Reagents now stop their passive effects (for example, stun immunity) if
+ the liver stops working while they're active.
+ Ghommie (original PR by YPOQ):
+ - bugfix: Fixing roffle waffle, mushroom halluginogen and some invalid reagents.
+ - bugfix: Fixes clockwork armor not actually having armor.
+ Ghommie (original PR by cacogen):
+ - rscadd: The font size of all text in the chat window now scales
+ - tweak: High volume (megaphone/head of staff headset) is a slightly smaller
+ - tweak: Admins have slightly larger OOC text
+ Ghommie (original PR by coiax):
+ - code_imp: Randomly coloured gloves and randomly coloured glowsticks now have slightly
+ different typepaths, but otherwise function the same.
+ - code_imp: The Squeak subsystem has been renamed to Minor Mapping.
+ Ghommie (original PR by duckay):
+ - rscadd: Added better names and descriptions for blueshirt officer gear.
+ - rscadd: Added the above gear to the premium selection of the sectech
+ Ghommie (original PR by harmonyn):
+ - balance: Resisting out of bucklecuffs takes more/less time depending on the handcuffs
+ you used, i.e., fake handcuffs will not bucklecuff someone for ages.
+ - tweak: fake handcuffs shouldn't no longer demoralize restrained criminals scums.
+ Ghommie (original PR by monster860):
+ - bugfix: fixes advanced proccall
+ Ghommie (original PR by mrhugo13 on tgstation13):
+ - rscadd: The Syndicate has decided to equip their Syndicate leaders operative (Aswell
+ as their clown counterparts) with the new Combat Glove Plus! The new Combat
+ Glove Plus does everything the old boring Combat Gloves does but with the added
+ extra of learning Krav Maga upon wearing them, any other Syndicate operative
+ who wants to get in on the action will have to pay 5tc.
+ Ghommie (original PR by nemvar):
+ - imageadd: Some drinks have new icons or slightly altered icons. In particular
+ Wizz Fizz, Bug Spray, Jack Rose, Champagne and Applejack.
+ Ghommie (original PR by ninjanomnom):
+ - bugfix: Orbiting is a little more aggressive about staying in orbit. The wisp
+ as a result now correctly follows you over shuttle moves.
+ - bugfix: Gaps between sounds in some looping sound effects should no longer happen
+ as much under heavy server lag.
+ Ghommie (original PR by variableundefined):
+ - bugfix: Cancel button to assault pod destination selector.
+ Ghommie (original PR by wesoda25):
+ - balance: disembowelment no longer works on mobs that aren't dead or in critical
+ condition
+ Ghommie (original PRs by Akrilla, Arkatos and Denton):
+ - tweak: Sprays cans have a cap on how dark you can make objects. Art is uneffected.
+ - bugfix: Fixed a bug where you could get cyborg spraycans via pyrite extracts.
+ - rscadd: Added an infinite spraycan for admins to spawn.
+ Ghommie (original PRs by Denton and Skoglol):
+ - tweak: Reorganized the syndicate uplinks. Items are now mostly alphabetical, some
+ misplaced items moved to more fitting categories. Bundles, random item and TC
+ have been moved into a new category called "Bundles and Telecrystals". Gloves
+ of the North Star and Box of Throwing Weapons have been moved to Conspicuous
+ and Dangerous Weapons. Combat Gloves Plus have been moved to Stealthy and Inconspicuous
+ Weapons. Moved all implants into the Implants category.
+ - tweak: 'Added a new category to the uplink: Grenades and Explosives.'
+ Ghommie (original PRs by Floyd/Qustinnus, optimumtact, Denton and coiax):
+ - rscadd: You can now select what your pills will look like when making pills from
+ the Chem Master
+ - rscadd: Red pills can make you think.
+ Ghommie (original PRs by Jujumatic and PKPenguin321, respectively):
+ - rscadd: Minesweeper Arcade machines. The higher the difficulty setting, the better
+ the prizes will be.
+ - rscadd: Also keep your eye out for another new (and rare) arcade game!
+ Ghommie (original PRs by Kmc2000 and actioninja):
+ - rscadd: Added darkmode! You can opt-in to this by clicking the new toggle darkmode
+ button just beside the settings one.
+ - rscadd: Byond members will now have a new setting for their Antag OOC color, instead
+ of using their OOC one. (Antag OOC still locked under admin discretion though)
+ - rscdel: Default black'n'white windows style.
+ Ghommie (original PRs by Mickyan, Anturk, ShizCalev, nemvar and Naksu):
+ - rscadd: After rigorous mandatory art training for the crew, many new graffiti
+ styles are now available
+ - bugfix: Cleaned up some crayon and spraycan code for futureproofing.
+ - bugfix: Spraypainting blast doors no longer makes them see-through.
+ - balance: Paint remover now works on blast doors and the like.
+ - rscadd: Most objects can now be colored using a spray can.
+ - spellcheck: Added visible message to spraying objects and windows.
+ - rscadd: Colored lights now shine in different colours.
+ - rscdel: Removed individual buttons text in crayon/spraycan UI, speeding it up.
+ - bugfix: Text mode buffer is actually visible in the UI.
+ - tweak: Last letter of a text mode buffer no longer rotates out to be replaced
+ with "a", allowing the text mode to be used for individual symbols.
+ Ghommie (original PRs by Naksu and XDTM):
+ - bugfix: Transferring quirks now properly removes the roundstart trait from the
+ person losing the quirk.
+ - bugfix: Roundstart traits no longer block the removal of other sources of that
+ trait.
+ - code_imp: status traits are now a datum var, the accessors are now defines rather
+ than functions.
+ Ghommie (original PRs by Naksu and coiax, loser):
+ - code_imp: Cleaned up saycode
+ - bugfix: Taking mutadone while having the communication disorder brain trauma will
+ no longer spam your chat with messages.
+ - rscadd: IPCs now come with a subtype of robotic tongue without the omnilingual
+ ability, instead of innately having robotic voice spans.
+ Ghommie (original PRs by Nichlas0010 and ShizCalev):
+ - tweak: AI core display screen can now be set in character preferences.
+ - bugfix: AI core display screen will now be restore when revived.
+ - spellcheck: Corrected some inconsistent capitalization in the player preferences
+ screen.
+ - imageadd: Readded some forgotten AI sprites.
+ - bugfix: Fixed Hades AI death animation not playing.
+ - tweak: the AI icon-selection menu now uses a radial.
+ - imageadd: Added in the death icon_states for the "TechDemon" AI screen.
+ Ghommie (original PRs by ShizCalev and bobbahbrown):
+ - rscadd: Headsets now dynamically show in their description how to speak on any
+ channels they can use when held or worn.
+ - code_imp: Radio channels names and keys now use defines.
+ - tweak: The head arrival announcement will now be broadcast to the supply for the
+ quartermaster.
+ Ghommie (original PRs by ShizCalev):
+ - bugfix: Fixed a bug that allowed you to teleport an ID in your possession to a
+ PDA anywhere ingame.
+ - bugfix: Fixed an exploit allowing you to steal ID's/pens from PDA's not in your
+ possession.
+ - bugfix: Fixed an exploit allowing you unlimited control of a PDA's interface even
+ if it wasn't near you/in your possession.
+ - bugfix: Fixed Pride Mirror exploits.
+ - tweak: Corgi collars can now be removed!
+ - tweak: Updated the corgi & parrot inventory panels to use the same formatting
+ as other mobs
+ - bugfix: Fixed corgi inventory panels not closing properly.
+ - bugfix: Fixed the parrot inventory panel not closing properly if you're not able
+ to interact with it.
+ Ghommie (original PRs by ShizCalev, MrDoombringer, AnturK, bgobandit, 81Denton and actioninja):
+ - rscadd: Failsafe codes for uplinks are now available for purchase.
+ - rscadd: Nuke Ops now have the ability to purchase a usable RPG, the PML-9, as
+ well as a couple different types of rockets for it. you can also suicide rocket
+ jump with them!
+ - spellcheck: Improved Uplink item descriptions and formatting.
+ Ghommie (original PRs by ShizCalev, coiax and Tlaltecuhtli):
+ - bugfix: Caks will no longer override the bonus reagents provided in a donut when
+ frosting them.
+ - bugfix: Caks can no longer create frosted frosted jelly donuts.
+ - bugfix: Jelly donuts will no longer lose their vitamins when they're frosted.
+ - bugfix: Fixed chaos donuts potentially doubling the amount of reagents added when
+ microwaved with something else.
+ - bugfix: Donuts now always contain 1 sprinkles as was stated on the wiki. Frosted
+ donuts have a chance at adding an extra sprinkle.
+ - code_imp: Improved the code for ensuring that security members enjoy donuts and
+ security-themed alcoholic drinks.
+ - balance: neurotoxin doesnt insta stun but gives you limb paralysis overtime and
+ heart attacks if it stays in for too long and it is also alcholic
+ - balance: beepsky smash now summons imaginary beepskys that deal stamina damage
+ instead of outright stunning
+ Ghommie (original PRs by Time-Green and Qustinnus):
+ - tweak: loot crates can't explode after unlocking anymore
+ - bugfix: jumping into loot crates no longers causes them to go boom
+ - bugfix: You can now deconstruct abandoned crates with a welder without making
+ them go boom. After unlocking them, of course.
+ Ghommie (original PRs by Tlaltecuhtli and nicbn):
+ - rscadd: alt click to eject beakers from chem masters + chem dispensers + grinders
+ + chem heaters
+ - rscadd: hit chem master + chem dispenser + chem heaters with a beaker and if its
+ loaded with another it swaps em
+ - rscadd: All-In-One Blender UI uses a radial menu now. You can see the contents
+ and reagents by examining.
+ Ghommie (original PRs by XDTM, 4dplanner, nemvar and, yes, myself):
+ - code_imp: Merged tinfoil hat kind of protection into the anti_magic component.
+ - rscadd: Tinfoil hats can also be warped up from excessive dampening of mindray/though
+ control/psicotronic anomalies, or by simply being microwaved in an oven, and
+ become useless.
+ - rscadd: Immortality Talisman and Paranormal Hardsuit helmets now come with tinfoil
+ protection too (minus the paranoia and limited charges).
+ - balance: Genetics/Slime/Alien Telepathy and Slime Link are now stopped by tinfoil
+ protection.
+ Ghommie (original PRs by XDTM, optimumtact, Nichlas0010 and monster860):
+ - rscadd: 'Added Quantum Keycards, devices that can link to a quantum pad, and can
+ be used on any other quantum pad to teleport to its linked pad. spellchecking:
+ Renamed "Bluespace Teleportation Tech" tech node to "Bluespace Travel".'
+ - tweak: Moved roasting sticks from the "Bluespace Travel" to "Practical Bluespace".
+ - rscadd: Spraying holy water on tiles will now prevent cult-based teleportation
+ from using them as a destination point.
+ - tweak: Quantum, wormhole and magic teleportation is no longer disrupted by bags
+ of holding.
+ - bugfix: You are now also blocked from teleporting IN to no-teleport areas, not
+ just out of them.
+ - tweak: Quantum teleportation now makes pretty rainbow sparks instead of the normal
+ ones.
+ - bugfix: Non-bluespace teleportation (spells etc.) no longer makes sparks.
+ - bugfix: Fixed teleportation deleting mob spawners like golem shells and ashwalker
+ eggs.
+ ? Ghommie (original PRs by carshalash, GranpaWalton, BebeYoshi & Hexmaniacosanna,
+ Fire Chance, Ordonis, Krysonism and OnlineGirlfriend)
+ : - tweak: Reduced booze power of Mead, Red Mead, and Irish Cream.
+ - tweak: Increased booze power of Grappa.
+ - rscadd: Added a new premium drink to the soda machine called "Grey Bull" which
+ gives temporary shock resistance
+ - rscadd: A new drink called Blank Paper was added to the bar menu, it was made
+ by a mime and it represents a new start.
+ - rscadd: 'Adds a variety of fine alcoholic beverages for discerning patrons of
+ the bar: Wizz Fizz, Bug Spray, Champagne, Applejack, Jack Rose, Turbo, Old
+ Timer, Rubberneck, Duplex, Trappist Beer, Blazaam and Planet Cracker!'
+ - rscadd: 'Also more nonalcoholic drinks: Cream Soda, Lemonade and Red Queen.'
+ - rscadd: Packs of a novel artificial sweetener have been added to the kitchen
+ vendor.
+ - rscadd: Bottles of trappist beer and champagne are now available in the premium
+ seection of the booze-o-mat.
+ - rscadd: Juicing parsnips now yields parsnip juice.
+ - rscadd: Maintenance peaches.
+ - bugfix: Grape soda now cools you down like other sodas.
+ - tweak: tweaked the Arnold Palmer recipe, it now uses lemonade.
+ - imageadd: Added new drink, bottle, vomit and peach can sprites.
+ Ghommie (original PRs by grandpawalton and Mickyan):
+ - tweak: the contents on the smartfridge icon now change depending on how many items
+ it contains
+ - bugfix: opening the maintenance panel of smartfridges now correctly updates the
+ icon
+ - bugfix: Screwing a disk compartmentalizer no longer makes it look like a smartfridge.
+ Ghommie (original PRs by nicbn and coiax):
+ - rscadd: Microwave UI uses a radial menu now. You can see the contents by examining.
+ - rscadd: Microwaves have a single wire accessible when open, the activation wire.
+ When cut, the microwave will no longer function, when pulsed, the microwave
+ will turn on.
+ - rscadd: Stabilized dark purple extracts now cook items in your hands, rather than
+ dropping the cooked item on the floor.
+ Ghommie (original PRs by ninjanomnom and nemvar):
+ - bugfix: Trays now scatter their contents when used for attacks, like they are
+ supposed to.
+ Ghommie (original PRs by ninjanomnom, coiax, yoyobatty):
+ - bugfix: Fixed slaughter demons not getting a speed boost when exiting a pool of
+ blood. Fixed slaughter demon giblets not being visible.
+ Ghommie (original PRs by subject217, AarontheIdiot, pireamaineach, Gousaid67 and SouDescolado):
+ - balance: Removed plasmamen species speedmod in favor of a slowdown for envirosuits.
+ - rscadd: Nanotrasen has began deploying departementalized enviro plasmasuits to
+ the station! plasmamens can now benefit from some of the bonuses aswell as the
+ color pattern of their job, while allowing others to easily determine their
+ profession!
+ - bugfix: Benevolent Nanotrasen makes gulag available for everyone! (Plasmamen retain
+ their equipment and don't die.)
+ - rscdel: Removes code that theoretically limits plasmamen from being clowns and
+ mimes, but actually doesn't.
+ Ghommie (original PRs by zeroisthebiggay, AnturK, MrDoomBringer, Cobby, ATHATH, optimumtact, GranpaWalton, Skoglol):
+ - bugfix: Blob overminds, sentient diseases, etc. can no longer dump out boxes.
+ Sorry gamers.
+ - rscadd: Sentient Disease now has almost all symptoms at its disposal.
+ - code_imp: Adding single-symptom disease abilities is super easy now.
+ - bugfix: Sentient Disease can now hear (not sure if this was a bug or intentional).
+ - rscadd: Sentient Disease is a linguist and knows all languages. Still cannot speak.
+ - tweak: Gives Sentient Diseases a medical hud to observe their victims further
+ with.
+ - bugfix: Fixes and moves around some on_stage_change() and Start()-related things
+ for virus symptoms and (sentient) diseases.
+ - bugfix: The inorganic biology symptom should work properly now when bought by
+ a sentient disease.
+ - bugfix: Oxyloss icon no-longer shows up when someone has the self respiration
+ symptom
+ - tweak: The self respiration now makes you not contract diseases through the air
+ and not breathe in smoke
+ - bugfix: Sentient diseases can no longer pick two cures that react and disappear
+ when eaten.
+ - balance: Sentient disease cures are now consistently harder, will only pick cures
+ from tier 6 and up.
+ - bugfix: Disease cures should now stay the same for all infected mobs.
+ - rscadd: The regenerative coma symptom has a new resistance 4 threshold effect!
+ Said threshold effect will give hosts of the symptom's virus the TRAIT_STABLECRIT
+ trait if its threshold is met.
+ - bugfix: An obscure, probably never reported before bug that may or may not exist
+ involving sentient diseases and the self-respiration symptom should be fixed
+ now (if it even existed in the first place).
+ - balance: The cooldown time between each removal or addition of a symptom for sentient
+ diseases has been brought down from an agonizingly long 2 minutes to a more
+ reasonable 1 minute.
+ Ghommie (original pr by Dennok on tgstation):
+ - bugfix: Now you don't lose your pulled thing on the z level edge.
+ GrayRachnid:
+ - rscadd: Added windoors to all the flaps on delta.
+ - balance: rebalanced k9dogborgs
+ Hatterhat:
+ - rscadd: Magnetic pistols now fit in boot pockets - jackboots, workboots, etc.
+ - tweak: literally every pistol subtype fits in shoes now. go wild.
+ Hippie Circuit Port:
+ - rscadd: Added all Atmospheric Circuits
+ - rscadd: Added the ability to color data disks
+ - rscadd: Added Selection and Storage Examiner Circuits
+ - rscadd: Added Smoke, Extinguisher, and Beaker Connector Circuits
+ - rscadd: Added Inserter, Renamer, Redescriber, and Repaint Circuits
+ - rscadd: Added MMI Tank and pAI Connector Circuits (The possibilities are endless!)
+ Improving and Balancing Cyborgs:
+ - rscadd: Added Crew Pinpointer to Security Borg
+ - rscadd: Added Crew Monitor to Medical Borg
+ - rscadd: Added Crew Pinpointer to MediHound Borg
+ - tweak: Made the Disabler_Cooler compatible with both Security Borg and K9 Borg
+ - tweak: Changed the Warning Text upon selecting Security or K9 module
+ ItzGabby:
+ - rscadd: Bat Species parts for more leeway for character customization.
+ - code_imp: Alphabetized decor wing selection window in character creator for simplicity.
+ JTGSZ:
+ - tweak: Added one more gang boss slot bringing total to 4 from 3
+ - bugfix: Fixed Gang Boss being able to be deconverted
+ - tweak: Gave Qualifies_for_Rank Check back its checks in job controller.
+ - rscadd: Optional species based clothing restrictions
+ - tweak: Gang Dominator excessive wall check tweaked to 25 open turfs
+ - bugfix: Gang Dominator no longer functions off-station.
+ - rscadd: Adds more control over species based offsets.
+ - bugfix: qualifies_for_rank now checks latejoin menu
+ - rscadd: Added Halloween Dwarves, for Halloween... Yep.
+ - bugfix: Can flip pipes once more.
+ - bugfix: barricade girder walls use PlaceOnTop instead of new
+ Linzolle:
+ - rscadd: ability to quickly max sensors
+ - bugfix: atmos helmet visual bug
+ - bugfix: supply display are now properly on the wall
+ - tweak: consistency in hop and cap berets
+ - tweak: slime people now enjoy eating toxic food and it will not disgust them
+ - bugfix: hos trenchcloak now properly has a sprite on digi characters
+ - rscdel: duplicate definition of hos and sec skirts
+ - bugfix: Krav Maga leg sweep now works properly.
+ - rscadd: shoes can have a different icon used for their item and mob icons
+ - bugfix: combat gloves plus having no mob icon
+ - rscadd: inhands sprite for rainbow knife
+ - tweak: colour of highlight on the regular knife when held in the right hand
+ - rscadd: mining shuttle console can now be printed after computer consoles have
+ been researched
+ - rscadd: can now carry people on your back by aggressive grabbing them while they
+ are laying down and then dragging their sprite onto yours.
+ - tweak: dragging people who are prone is now much slower, and carrying them will
+ allow you to move faster at the cost of taking 5 seconds to lift them up onto
+ your back.
+ - tweak: pacifists can now aggressive grab (cannot table slam people though)
+ - bugfix: blood on your body floating a bit to your right if you're a taur
+ - bugfix: some suits having no icon on tauric characters
+ - tweak: front facing CMO hardsuit icon for naga taurs
+ - tweak: colour of medical cross on CMO hardsuit for taurs
+ - bugfix: taur body and jumpsuit showing through mining suits
+ - tweak: all chaplain suits can hold the same items in suit storage
+ - code_imp: improvement to organisation for chaplain suits
+ - bugfix: blood halberd not going back to 17 force after unwielding
+ - spellcheck: unnecessary 's at the end of blood rites healing
+ - rscadd: QoL to blood rites, examine the ritual aura to view how many blood charges
+ are left
+ - code_imp: surgery cleanup
+ - tweak: dissection available round-start
+ - rscadd: better dissection surgeries from RnD, gives more points
+ - rscadd: abductors can now see what glands do
+ - code_imp: antagonist abductors now have a surgeon trait that teaches them every
+ surgery rather than having it just check if they're an abductor
+ - rscadd: muscled veins surgery
+ - bugfix: having one of your hands used up if you fireman carry but the person being
+ carried dismounts any way other than you dropping them
+ - rscadd: Four colour variants of ankle coverings. Select them on the loadout screen.
+ - imageadd: ankle coverings
+ - tweak: allows for shoes that don't cover your feet to be taken into account for
+ footstep sound effects and glass shards
+ - rscadd: Tend Wounds surgery. Heal in the field, with better healing the more damage
+ the patient has.
+ - rscdel: Reconstruction replaced by Tend Wounds
+ - balance: made Revival more accessible, more viable alternative to cloning.
+ - bugfix: advanced surgery tools can't perform lobectomy or coronary bypass
+ - rscadd: Decorative and insect wings can now be coloured individually, similar
+ to horns.
+ - bugfix: people getting assigned wings if their savefile is old.
+ - rscdel: wings that take the hair colour. Unnecessary if you can just set the colour.
+ - tweak: Cannot make horns pure black. Trying to do so will set it to a default
+ value.
+ - bugfix: decorative angel wings being invisible
+ - bugfix: abductors now actually work
+ - tweak: abductor scientist has their own greet message now
+ - bugfix: unable to read paper on airlocks
+ - tweak: ai can see paper (still just shows stars)
+ - rscadd: Target head and throw a hat at someone to toss it onto their head, knocking
+ whatever they're wearing off if they are wearing a hat. Some headgear can't
+ be knocked off this way.
+ MediHound:
+ - rscadd: Made Cyborgs be affected by Ion Storm Law Changes like AIs
+ MrJWhit:
+ - balance: rebalance melee stamloss
+ Multicam Config:
+ - config: removed whether or not the stuff for multicam was checking the useless
+ var and instead now checks the CONFIG_GET flag.
+ - admin: Admins now have a verb in the Server tab to turn AI multicam on and off.
+ Naksu:
+ - code_imp: default radiation insulation is now handled by atom vars rather than
+ a component, components can still be used.
+ - code_imp: squeezed a little bit more perf out of atmos
+ Nero1024:
+ - soundadd: Bare feet will now make the correct footstep sounds.
+ - soundadd: Other mobs will make the correct footstep sounds.
+ - soundadd: Crawling/dragging sounds for downed/incapacitated mobs
+ Onule & Nemvar (ported by Ghommie):
+ - imageadd: New Revenant icons
+ Original by Citinited, port by Sishen1542:
+ - rscadd: You can now use an airlock electronics on a locker to add a lock, and
+ can screwdriver an unlocked locker to remove its lock.
+ - rscadd: You can now remove the locks on broken or emagged lockers.
+ - tweak: Removing the lock from a personal locker now wipes that locker's ID details.
+ - tweak: Broken lockers have had their appearance changed.
+ Owai-Seek:
+ - rscadd: custodial cruiser cargo crate
+ - tweak: removed light replacer from power designs and moved to misc designs
+ - tweak: added pimpin ride to custodial locator
+ - tweak: added additional items to janibelt whitelist
+ - tweak: made plant DNA manipulator unwrenchable
+ - balance: reduced janitor premium supply costs
+ - bugfix: fixed them strawberries
+ - rscadd: false codpiece
+ - rscadd: crocin/camphor bottles
+ - tweak: updated kinkmate item list
+ PersianXerxes:
+ - code_imp: Adds the clockwork_warp_allowed flag to the Captain's Office area, set
+ to FALSE the same way it is for the chapel and armory.
+ - tweak: Relocates cult catwalks outside the Reebe dressing room.
+ Poojawa:
+ - rscadd: Digitigrade legs are now able to wear shoes and look fancy, Uniforms to
+ come.
+ - tweak: Xenos are only digitigrade now, mammals and aquatics have the option.
+ - rscadd: Fire Alarms are visible in low light situations
+ - bugfix: fixed vore prefs saving inconsistently, new characters might have a previous
+ slot's prefs tacked on.
+ - bugfix: fixed mammals not having the option for digilegs. Sprites are fucky until
+ body-part related sprites are done.
+ - refactor: improved vore sound responsiveness to preference choices.
+ - balance: removed morphine from Medihound sleeper chemical list
+ - bugfix: fixed preference setting being broken
+ - refactor: Medihound sleepers are Initialized properly, and icons update correctly
+ now on eject
+ - tweak: Air alarm All clear color changed from green to blue
+ - balance: APCs are harder to destroy.
+ - rscadd: Added Digitigrade versions of everything appliciable in suit.dmi
+ - imageadd: Snowflake Icons weren't modified, and were given NO_MUTANTRACE_VARIATION
+ - imageadd: naga and quad Taurs literally don't freeze their ass off in space anymore.
+ - bugfix: Digitigrade legs will toggle on/off properly on character menue
+ - bugfix: The misleading "normal" has been removed from species options
+ - balance: Added sanity checks to emag usage
+ - bugfix: fixed vtech, but it still doesn't work because of overriding jog/sprint
+ mechanics from combat reworks.
+ - bugfix: Puppy jaws properly store if you're emagged, they are also toggle-able
+ for stealth like the tongue.
+ - bugfix: 'Digitigrade legs should properly fucking update for the last fucking
+ time. Fucking snowflake code. refractor: Got rid of snowflake sechound cuffs,
+ gave them normal zipties like regular secborgs.'
+ - bugfix: dogborg sleepers actually extinguish people who are on fire, in case you
+ don't have time to lick them out.
+ - bugfix: Taur suits should fix themselves properly when worn by other people.
+ - rscadd: Added the Yogs/Oracle ported latejoin menu
+ - rscadd: All markings, tails, ears, and snouts for Citadel races are color matrixed!
+ - imageadd: all markings are on a per-limb basis, including Digitigrade legs!
+ - imageadd: a bunch of tails were blessed with tail wagging sprites, Fish, Sharks,
+ Fennecs, Wahs, raccoons, and others.
+ - imageadd: Tiger markings + tail added, skunk tails improved via sprites from Virgo
+ - tweak: tweaked some sprites to look better, but they absolutely could use a few
+ extra passes for quality
+ - rscadd: HumanScissors in the Tools folder will permit anyone to contribute matrix'd
+ markings to the sprite sheet, however Mam_markings is very, very full. Be careful.
+ - tweak: Character preview was both optimized for taurs and bad-touched for better
+ updating. I don't know if it'll be bad, but hey its better.
+ - rscadd: Added Dark Medihound and Pup Dozer from Virgo
+ - tweak: Clone pods no longer announce the name of the clone
+ - bugfix: fixed flavor text appearing when your face is hidden but you're not an
+ Unknown
+ - bugfix: Tauric suits now apply an (placeholder) blood overlay, as well as their
+ shield overlay.
+ - balance: Ashwalkers now have lungs. They cannot breath station air without suffocation
+ effects, but are completely fine on their homeworld.
+ - balance: Carbon mobs now have a maximum tolerance to oxygen of 50kPa.
+ - balance: Deluxe synthetic lungs have a very high bonus to O2 tolerance.
+ - bugfix: Digitigrade legs returned to normal, since digi leg markings overlay them
+ anyway.
+ - bugfix: commented out lizard mam_snout entries, because too many abominations
+ - bugfix: Vore Panel restored to have various interactions available again. Semi-untested
+ but should work as advertised.
+ - tweak: Vore Panel has more feedback.
+ - rscadd: is_wet var to bellies, toggled in the panel, will remove flesh sounding
+ struggles and the internal loop. JSON version updated.
+ - rscadd: Feeding var. You will need to enable feeding to recieve any feed vore
+ actions, but you can now feed yourself to mobs that have this set. TODO, Dogborg
+ sleeper feeding.
+ - rscadd: vore mode button now required to be enabled to perform vore actions. It's
+ the mouth icon!
+ - bugfix: Ash Drake vore fixed for actual reals this time
+ - bugfix: Mobs shouldn't spam the released contents announcement anymore on qdel
+ or death. Only if triggered
+ - tweak: Hostile mob code now properly ignores targets in bellies
+ - rscadd: Your belly can quietly growl if you're starving now.
+ - bugfix: Normal blood splattering isn't offset due to tauric mode
+ - rscadd: Added plasma man suit icons for taurs
+ - rscadd: Added bee butt for insects to have stripes
+ - tweak: adjusted random spawn sprite accessories, humans won't be demi by default
+ and lizard/mammal spawns will randomly get digitigrade legs
+ - bugfix: sprite adjustments for tentacles, as well as a misspelling.
+ - bugfix: Humans once again use ears and tail_human, as intended. This is to prevent
+ garish randomness
+ - bugfix: istype for species is actually correct and usable now, it'll be a factor
+ for monkey form expansions.
+ - bugfix: Hair functions are de-gendered and more easily selectable now.
+ - bugfix: Slimes can *wag, select markings and snouts, and yes it works.
+ - bugfix: Slimepeople extra parts now respect their hair_alpha in terms of being
+ somewhat see-through. it shouldn't stand out as badly now!
+ - bugfix: Hunger noises are now toggled per character
+ - bugfix: Ashwalker den is habitable by ashwalkers again
+ - rscadd: Medical belts now have overlays! Now you can see if a belt is useful or
+ just flatout empty.
+ - bugfix: fixed hypo MK IIs not being able to be put on medical belts
+ - bugfix: fixed Navy officer uniforms that failed to spawn
+ - code_imp: Loadout items will be forcefully added to backpacks or at your feet
+ instead of left behind at title screen
+ - tweak: hypospray kits hold 12 now, but only vials and sprays themselves
+ - bugfix: labcoats can carry MK II hyposprays on them now.
+ - rscadd: Vore Mobs are a thing now, not just ash drakes
+ - rscdel: 'Removed hunger sound stuff. never taking requests from Coolgat3 ever
+ again. refractor: Simple Mobs use the same system regular human mobs do, itjustworks.png'
+ - tweak: Character Window settings unsnowflaked and normalized. I have no fucking
+ clue how to make them work with taurs still tho, sorry.
+ - imageadd: added rotating background images for better clarity and contrast than
+ just SOLID FUCKING BLACK. Images from Virgo/Polaris/Eris
+ - balance: Defib users automatically stop pulling when they attempt to perform a
+ defib shock
+ - imageadd: added muzzled varients of space helmets and full masks
+ - imageadd: added knight_grey to taur suits, all paranormal ERT now have tauric
+ versions enabled
+ - bugfix: Lava knights have digitigrade and tauric versions now
+ - rscadd: Added a glass version of the gas mask, because it was in the files and
+ looked nice. does everything regular ones do except make you an unknown
+ - rscadd: Added custom species names! Examining people will now display their species
+ name unless they're an Unknown or have their face hidden. like flavor text.
+ Set it in your character window!
+ - code_imp: changed how health scanners print messages, wrapping it in msg for one
+ to_chat instead of printing every line to_chat.
+ - server: Discord bot will now report when a round ends and give the vague news
+ ticker that a sister-station would have received for the game mode and result
+ of the round.
+ - bugfix: fixed medical hardsuit overlay issue. I thought it was going to work well
+ but fuck byond.
+ - bugfix: None body markings shouldn't give rgb hell, but it also should reset properly
+ anyway. ree.
+ - bugfix: Sorted some sprites to better sooth my byond icon limit anxiety.
+ - bugfix: Box Cryopods expanded to 6 public. Permabrig cryo fixed.
+ - bugfix: Delta Cryopods expanded to 6 public. Permabrig cryo fixed.
+ - bugfix: MetaStation Crypods expanded to 6 public, relocated above sparring ring.
+ Permabrig cryo fixed
+ - bugfix: PubbyStation gained one more cryopod, Permabrig's cryo fixed.
+ - rscadd: Omega given one more crypod as well.
+ - rscadd: Gulag was given a cryopod.
+ - tweak: Box and Meta's cryo rooms are now a new room entirely.
+ - rscadd: Added erect states for all phallic bodyparts
+ - bugfix: YOUR DICK ACTUALLY STANDS UP NOW, YOU'RE WELCOME.
+ - bugfix: skintone locked genitals match the new skintone colorations.
+ - rscadd: added two new vaginal types and descriptions.
+ - bugfix: fixed borg defib runtimes
+ - bugfix: fixed heart attacks being nonlethal
+ - rscadd: Ported Oracle's cloning set up, you're now visible like cryo when being
+ cloned, though it's a mystery until you have skin on your meat puppet existance
+ - balance: Recyclers are unable to destroy the indestructible any longer.
+ - bugfix: Kiara's toy sabre now actually is the correct item + icon states
+ - bugfix: Generic armor for taurs fixed, there isn't actually any sprites for 'em,
+ so. Full sprites overlay over bodies, but I really can't be bothered to do all
+ the offset fixes otherwise.
+ - rscadd: Large maps have had a patient room transformed into micro chemistry stations
+ with nothing else in them. They've been labelled 'Apothecary' rooms and are
+ accessible by doctors.
+ - rscadd: females now have female defined sprites
+ - bugfix: Slime legs have had their excess pixels adjusted
+ - bugfix: Mammal normal legs are more in line with human legs now
+ - bugfix: fixed species like abductors and golems getting the fat tiddy or pingas
+ - bugfix: Atmos and Station alerts should be more alerting.
+ - rscadd: Added visible and hidden testicles
+ - rscadd: Added multi-boob support. Now you can have two or three pairs of breasts.
+ - bugfix: fixed missing vagina and breast sprites
+ - bugfix: fixed prosthetic hands being invisible
+ - bugfix: male foxes exist again
+ - bugfix: female chest markings improved from being too dark in comparison to their
+ other colors, blending better
+ - bugfix: Markings behave better on non-organic limbs.
+ - tweak: tweaked the name of Sublter to distinguish its use
+ - tweak: Gave a hint for vore posting.
+ - rscadd: Readded Ninja speech modifications with their mask
+ - rscadd: Pacifists can eat people for heal belly or noisy. Digestive modes are
+ auto-swapped to noisy
+ - rscadd: Added an underwear toggle button under 'Object' tab
+ - tweak: Genitals now layer under underwear. Hide these if they're too obnoxious.
+ - rscadd: Added digitigrade socks of all known ones anyway.
+ - tweak: tweaked the Genital character creation layout to look better
+ - bugfix: fixed having balls/womb when you don't have the linked organ at character
+ creation
+ - bugfix: fixed being able to squeeze semen directly from your balls. Probably.
+ - rscadd: NT Newscasters have had repeated reports of gang activity and are now
+ looking into it.
+ - rscadd: NT Psykers keep mumbling about last words of someone who died. Somehow
+ they even have a newsletter for this...
+ - bugfix: Gangster greeting messages are a batch message rather than 5 laggy to_chats
+ - imageadd: RCL now show what color is currently in use
+ - rscadd: Added RGB blood effects, know whose blood this is by color!
+ - rscadd: Added Synthetics blood, and a machine that produces it. A universal donor
+ for medical to heal people with. Make it via medical protolathe!
+ - bugfix: With hearts, slimepeople shouldn't die from the effects of not having
+ a heart.
+ - bugfix: Plasma vessels from xenomorphs will restore blood if you're on resin.
+ - server: Poly's speech now echos to the chat bot.
+ - rscadd: Added new wings to Insects and separated fluff from old ones, they're
+ Insect's new body markings now without being per-limb (for now).
+ - rscadd: Horns are now available to mammals, and they have their own color.
+ - rscadd: Legs are no longer a binary hack code, but actually something that can
+ be changed. Framework for tauric adaptations.
+ - rscdel: Purged Modular Citadel's sprite_accessories.
+ - bugfix: improved the quality of a number of sprites.
+ - tweak: Moths are now all insects. Avians and Aquatics are all anthromorphics.
+ Just as planned.
+ - rscadd: Anthromorphs can choose their preferred gibbing meat. I guess. Snowflakes
+ are weird.
+ - bugfix: Additional Gentlemen names.
+ - rscadd: Medical huds are now calibrated for Radioactive wavelengths.
+ - balance: Engineering equipment, blue space, and common storage containers are
+ radiation protected
+ - bugfix: fixed suit storage not cleaning radiation levels of everything stuffed
+ into them.
+ - bugfix: QM is able to hire/fire people to their department now.
+ - bugfix: cryopod UI isn't complete shit anymore
+ - bugfix: Cryopods purge silicon gear more efficiently now. Same with ghosts.
+ - balance: Med Sprays are now more aligned with patch mechanics
+ - balance: Chemistry is encouraged to be more varied in their healing, as well as
+ careful in its application
+ - tweak: Active NPC priority set much higher priority for the MC, with the intent
+ on making NPC combat more interesting
+ - bugfix: Clarified access descriptions of some jobs
+ - bugfix: fixed missing deco wing states
+ - bugfix: fixed a few things related to vore content
+ Putnam3145:
+ - tweak: Bottles in PanD.E.M.I.C 2200 can now be replaced with an inhand bottle
+ directly
+ - tweak: Ejecting a bottle from the PanD.E.M.I.C 2200 puts it directly into the
+ user's hand
+ - tweak: Alt-clicking the PanD.E.M.I.C 2200 ejects the current bottle
+ - bugfix: neural nanites only work/drain if you have brain damage or traumas the
+ nanites can fix
+ - tweak: Pod people can no longer get fat from standing in the light
+ - tweak: PanD.E.M.I.C 2200 now ejects onto itself instead of onto user if user's
+ hands are full
+ - rscadd: Added configs for a bunch of Dynamic rule parameters.
+ - config: Added defaults for all the configs (WIP).
+ - config: Added dynamic midround/latejoin antag injection to the config.
+ - balance: Made starlight condensation not kill slime people.
+ - balance: Added not-killing-slime-people to the transmission threshold of plasma
+ fixation and radioactive resonance.
+ - tweak: Made the clone scanner lock while it's scanning.
+ R3dtail:
+ - rscadd: Added 16 saltprimaryobject items Added 4 saltsecondarysubject items
+ - rscadd: Added a new carpet. Red! Also added said carpet to the Premium Carpet
+ crate from the cargo supply console. Trilby said she'd take care of the crafting
+ recipe.
+ Raptorizer:
+ - tweak: Doubled peach spawn rate
+ - tweak: tweaked numbers/variables
+ - balance: rebalanced numbers/variables
+ - spellcheck: removed unneeded code
+ Seris02:
+ - rscadd: Abductor Replication Lab ruin and advanced tools
+ - rscadd: Added looc hotkey
+ - tweak: made the autoprocess button relevant
+ - tweak: changes so that spooktober starts earlier
+ - bugfix: fixed the dark blue lum major effect
+ Sirich96 and Dennok (ported by Ghommie):
+ - rscadd: Added new Teleporter Station sprites
+ - rscadd: Added teleport station calibration animation.
+ Sishen1542:
+ - rscadd: Pentetic Jelly, new chemical made through mixing 1:1 slime jelly and pentetic
+ acid.
+ - tweak: Anatomic panacea now gives pent jelly instead of pent acid. Medbeams now
+ have TRUE tox healing to heal TOXINLOVER as well.
+ - balance: Changed bible heal proc, halving the healed damage and increasing brain
+ damage 5x in exchange for a much wider array of items to protect you from it.
+ - tweak: Moved around some chems from emag list into upgrades.
+ - balance: Added some fun chems to dispensers.
+ - bugfix: Gave dispensers old tg functionality.
+ - rscadd: Leather, cardboard, bronze & bone golems!
+ - rscadd: Bone hurting juice and interactions with plasmamen, skeletons & bone golems!
+ - rscadd: Ported addition of new CAS cards.
+ - bugfix: Ported a fix for CAS.
+ - rscadd: Added the ability to alter your genitalia as a slimeperson more than addition/removal.
+ - bugfix: fixed genitalia removal proc in alter form.
+ - balance: Ported the inability for non-station AI to interact with station z-level.
+ - balance: HoS mains can now peacefully sleep in their office.
+ - tweak: Podpeople now have customization options.
+ - bugfix: Removed the human check for cult conversion of captain/chaplain minds.
+ - balance: Roundstart carbon jetpacks now have full_speed FALSE.
+ - tweak: Adds plasteel to medical and security techfabs.
+ - rscadd: Added public autolathes to all maps.
+ - tweak: density = 0
+ - balance: hugboxing mining loot
+ - balance: ling blade now has 40 armor pen
+ - rscadd: fun
+ - rscdel: bad stuff
+ - balance: mech bad
+ - balance: rebalances strained muscles
+ - rscadd: added in the assistant response team
+ - bugfix: fixed up access on the centcom hangar button
+ - balance: storage tweaks for belt briefcase
+ - imageadd: codersprite for belt briefcase
+ - rscadd: added pharaoh gear to chaplain vendor
+ - spellcheck: fixed typos in pharaoh items
+ - rscadd: made laser minigun not shitcode and also craftable
+ - soundadd: added new fire sounds for the laser minigun
+ - rscadd: holy lasrifle, hypertool, divine lightblade, and blessed baseball bat.
+ Four new holy weapons!
+ - balance: stamina and force tweaks for most holy weapons.
+ - tweak: prayer beads no longer deconvert after a 10 second timer, now just inject
+ holy water for delayed effect
+ - tweak: cultist runes are now destroyed with a bible or a null rod
+ - tweak: bo-staff now functions as a nerfed sleepy carp staff
+ - bugfix: fixed kevinz code to add in non-null rod child items as holy weapons
+ - bugfix: fixing chems for strained muscles
+ - bugfix: narsie no longer asks for consent
+ - bugfix: removed reflect from divine lightblade
+ - bugfix: teleporting a locker is bad
+ Sishen1542, original by @Tlaltecuhtli:
+ - bugfix: alt clicking the emitter now rotates it instead of only flipping
+ Sishen1542, original by @zxaber:
+ - balance: Utility mechs no longer automatically get beacons.
+ - balance: Tracking beacons no longer delete themselves when EMPing a mech, and
+ instead have a ten-second cooldown in-between EMPs. They also now do heavy EMP
+ damage rather than light.
+ - balance: Mechs that take EMP damage lose the use of their weapons and equipment
+ temporarily. Movement and abilities are not effected.
+ - balance: Mechs taking EMP damage no longer roll for a random malfunction.
+ Sishen1542, original by Arkatos:
+ - rscadd: Action buttons can now be dragged onto each other to swap places
+ Sishen1542, original by NewSta:
+ - tweak: updated the miasma canister sprites
+ Sishen1542, original by Skoglol:
+ - rscadd: Heaters/freezers now support ctrl clicking to turn on and alt clicking
+ to min/max target temperature.
+ Sishen1542, original by XDTM:
+ - rscadd: Using the wrong surgery tool during surgery no longer attacks the patient,
+ if on help or disarm intent.
+ - rscadd: Surgery steps are now shown in detail only to the surgeon and anyone standing
+ adjacent to them; the patient and people watching from further away get a more
+ vague/ambiguous description.
+ Skoglol:
+ - rscadd: You can now alt click storage (bags, boxes, etc) to open it.
+ Skully):
+ - rscadd: Nudity Permit, a completely invisible uniform that still has pockets and
+ such, to loadout options. It is more or less a direct port from the RP server.
+ SkullyRoberts:
+ - rscadd: Penis autosurgeon as rare maint loot.
+ TerraGS / Skoglol:
+ - rscadd: Adds toggleable light and blinking charge indicator to kinetic crusher
+ - rscadd: Kinetic crusher can now be one-hand carried. You'll still need two hand
+ to use it.
+ Thalpy:
+ - bugfix: fixes message_admins in SDZF
+ - tweak: Alkaline buffer recipe so people don't get grumpy and expanded the pH range
+ - bugfix: fixes buffers
+ - bugfix: fixes broken compiler because a var changed name
+ - bugfix: impure travis var anger
+ - rscadd: Added the ability to dispense smartdarts from the chemmaster.
+ - tweak: Tweaks medolier amd chembags to allow quickpickups of smartdarts, lets
+ the latter soak in beakers (on the floor)
+ - bugfix: fixed rounding errors with smartdart mixes.
+ - imageadd: added modified smartdartgun icon.
+ - bugfix: 1. Kev asked that there were no antag datums used, so that's been changed.
+ 2. Tricks can no longer turn someone into a dullahan, instead you have to spend
+ candies to get that. I felt it was too mean to turn people into that, I didn't
+ realise you couldn't revert it. 3. Barth will no longer as for impossible items.
+ 4. Barth will no longer as for the same item multiple times. 5. Barth will now
+ accept broader things, rather than asking for something, when meaning something
+ specific. 6. Jacq will now no longer poof off the z level. 7. Jacq will (hopefully)
+ stop spooking the AI by teleporting into there 8. Jacq will now try to teleport
+ to a location with someone nearby. 9. Barth will tell you where Jacq is currently
+ when you speak to him. 10. You can trade 2 candies for a Jacq Tracq (tm) 11.
+ Jacq should stop getting mad and cover the station in gas when killed. 12. Fixed
+ Jacq not singing (the link died). 13. Slightly changed wording so that people
+ will hopefully get to know her. 14. Jacq no longer disappears when you're getting
+ to know her.
+ Toriate:
+ - imageadd: 'All regular crates are now 3/4ths ToriCrates iamgeadd: Unused plastic
+ crate sprite added'
+ - rscadd: Blood freezer crates now have unique sprites.
+ - rscadd: RPD now has inhands
+ - imageadd: New sprites for RCDs and RPDs, inhands included
+ - imageadd: Updated the sprites of all the regular crates
+ Trilbyspaceclone:
+ - rscadd: cakes!
+ - imageadd: Made some sprites! -Love them really came out well
+ - rscadd: new economics
+ - tweak: cargo and robotics relationships
+ - balance: unbalanced something
+ - bugfix: fixed a maybe oversight
+ - rscdel: Fun
+ - tweak: costs of suit voucher
+ - balance: Unblances miner vender
+ - bugfix: spare cheaper brute kit
+ - tweak: harm from hentie
+ - balance: rebalanced goliaths stun to be less auto death
+ - rscadd: Armor to blob shields
+ - tweak: block weaken state to 70% from 75%
+ - bugfix: restores the deathriplys missing armor
+ - rscadd: new lockable colalr
+ - tweak: armor
+ - bugfix: missing hopes and dreams
+ - code_imp: orgized the weapon file to be more cat brain friendly
+ - imageadd: This means sprite right?
+ - rscdel: Many engi flags on non-engi things
+ - code_imp: changed some code to be organized at a glance
+ - balance: '25% < --- 50% For NPC blocking bullshit ided: Yes'
+ - rscadd: mag gun uses cells
+ - balance: kev things their to op
+ - rscadd: syndicate phobia
+ - tweak: other phobia's
+ - bugfix: laser carbine
+ - tweak: makes collars only locked via key
+ - tweak: charging
+ - rscadd: Combat inducers for COMBAT!
+ - code_imp: made it look nice
+ - rscadd: golden swag boxes
+ - rscadd: Crafting suitcases
+ - rscadd: more bountys
+ - rscdel: Nitryl bounty
+ - rscadd: better stocks
+ - rscadd: more evil blood fluff text
+ - rscadd: Added more mime names
+ - tweak: replaces a sink with a autolathen
+ - balance: 2 -> 3
+ - rscadd: MASON SUIT!
+ - rscadd: adds the sec jetpack to sec hardsuit storge
+ - rscadd: Added a few jet packs to the space queens men
+ - tweak: volume of jet packs
+ - rscadd: Bad Idea
+ - rscadd: bio mass meat
+ - rscadd: more box options
+ - bugfix: a lack of replaceable boxes
+ - bugfix: clothing needing a emag
+ - tweak: 4 - > 5
+ - tweak: 5->6
+ - tweak: 4tc - > 2tc
+ - tweak: mulligan costs 4 - > 3
+ - tweak: Tuberculosis 12tc - > 8tc
+ - tweak: 15 - >10
+ - bugfix: both bags have the same name
+ - tweak: 5 - > 2
+ - tweak: 3 -> 1
+ - tweak: 2 < - 4
+ - tweak: 1->2 and ultra
+ - rscadd: shield + crafting
+ - tweak: hierophant movment and melee attack
+ - rscadd: More plushies
+ - tweak: attack verbs and descs
+ - rscadd: bone satchles
+ - balance: rebalanced stunslugs
+ - rscadd: colored boxes, and more types
+ - tweak: harm and such
+ - balance: item classes
+ - bugfix: resonators being so shitty
+ - bugfix: 'Game braking bug critical: bug fix'
+ - rscadd: items to syndie surgery bags
+ - rscadd: SNOW CONES
+ - rscadd: carts buy-able cargo
+ - tweak: selling/time to craft
+ - bugfix: crafting problems, and red stamp exsplote
+ - rscadd: gives paper work sprites that are nicer
+ - rscadd: origami
+ - rscadd: gang tower shield
+ - tweak: costs of boots
+ - rscadd: organ box
+ - rscadd: Medical breifcaseses
+ - rscadd: New cargo crate for tech-slugs!
+ - rscadd: Ammo to each fitting crate
+ - bugfix: Cat-code
+ - spellcheck: fixed a few typos - Again my bad
+ - bugfix: fixed airless place
+ - rscadd: baklava
+ - balance: makes uplink kits more usefull for the risk
+ - code_imp: Changes some files to be better
+ - balance: As all things are not
+ - bugfix: fixing cat code that dosnt work, my bad
+ - bugfix: Arcades stealing from noodles
+ - rscadd: rapier
+ - tweak: speedy quirk
+ - spellcheck: Ironic
+ - bugfix: A bunch of minor issues with xenobiology are no more!
+ - bugfix: I didn't code it right it in the first place
+ - rscadd: new nodes
+ - balance: points and node gear
+ - rscadd: stuff n things
+ - rscadd: gear harness and a conflict merg
+ - rscdel: Nudity permits
+ - bugfix: nothing
+ - rscadd: Donner item
+ - rscadd: Luna's Gauntlets
+ - balance: rebalanced lingy dingy powery gamey
+ - tweak: melee and block harm
+ - bugfix: sprites*
+ - balance: bone satchles
+ - tweak: holster doing holster things
+ - rscadd: Donor item
+ - rscadd: Joy, Happiness, Honk
+ - bugfix: small mix up in terms
+ - rscadd: Promiscuous Organs crate, pills to lewd crate and testicles to maints
+ - bugfix: Made unholy water healtoxinlover
+ - rscadd: Zelus Oil, brass flasks
+ - rscadd: Added new chairs
+ - admin: Bugtesting zone upgrades for easy bug/game testing
+ - rscadd: more cargo to cargo
+ - rscadd: More loadout gear
+ - bugfix: Poojawa power creep
+ - bugfix: Not my work not my credit
+ - rscadd: Emitter gun
+ - bugfix: suit storage nulling anti magic item protection
+ - balance: rebalanced steal goals restrictions
+ - spellcheck: fixed a few misleading goals
+ - bugfix: ports a fix
+ - bugfix: oversight in benos
+ - bugfix: QM rooms not getting Key Aunths
+ - rscadd: new books/cooking
+ - spellcheck: less bad wording in slime
+ - rscadd: strawbarries and such
+ - rscadd: amazing things like tea of catnip, catnip and plant
+ - tweak: glue uplinks
+ - rscadd: RPDs to drones
+ - rscadd: Armor and such
+ - rscadd: flavor
+ - bugfix: maybe a runtime
+ - rscadd: chameloen clothing
+ - rscadd: tons of peach themed items
+ - spellcheck: caje
+ - rscadd: New book - Unused
+ - code_imp: organized files
+ - imageadd: redid brass tools to look better*
+ - bugfix: /cursed from a item path
+ - rscadd: Almost all clothing and most weaponds can be sold for pocket change
+ - tweak: Cargo costs of packets and selling
+ - balance: Lowered mat selling as well as most if not all bountys
+ - code_imp: Adds more files for easy finding/adding in packs
+ - bugfix: oops not being blacklisted
+ - code_imp: removes some cit-modular things
+ - bugfix: Missing sprites with bad ones
+ - tweak: emag charge amount
+ - rscadd: Reebe QoL aka creep in gear
+ - bugfix: ???
+ - server: HEY MADE THE REEBEEE WAY SMALLER - Making it less lagging hopefully
+ - rscadd: Surgerys and spays in bags
+ - tweak: earthbloods stam regen
+ - imageadd: Red to Blue/Black crosses as questioned by Bhijn
+ - bugfix: clean bot not cleaning basic cleanables
+ - rscadd: new traitor bundle
+ - rscadd: trash
+ - imageadd: 'eye bleed :add: misstakes'
+ - rscdel: Removed old things!
+ - bugfix: UI memes
+ - rscadd: Blue space blood bag
+ - tweak: blood costs
+ - rscadd: Beebal and Honeybalm plants
+ - tweak: Costs of crates and paperwork
+ - rscadd: Adds 2 more crates hacked only
+ - rscadd: Added two seed packets of cotten to ash walkers base
+ Tupinambis:
+ - tweak: Changes large parts of the nuclear operative base, including the addition
+ of a new barracks where the ops spawn, a personal bedroom for the leader, the
+ rearrangement of numerous rooms, some added fluff, a slightly more roomy bar,
+ a larger hanger, a kitchen, and various other small changes to make the base
+ feel just a bit more alive. This was achieved by completely redoing the base
+ from scratch so there was room to work with, as a result potential bugs could
+ crop, please do report them.
+ - bugfix: The drop pod chamber was airless. This seems like an oversight, and has
+ been filled with air.
+ - rscadd: Cryo Sleepers have been added to Perma on all four maps in rotation. the
+ bathroom windoor and window have switched places to accommodate this change.
+ - rscadd: You can now choose the pre-exisiting "loader" sprite as an appearance
+ for your engineering borg.
+ - tweak: A vast majority of references to humans within ion laws have been replaced
+ with crew. AI modules have received similar treatment
+ - rscadd: 'Adds a syndicate themed emergency shuttle that costs 20000 credits, and
+ can ONLY be purchased when the communications console is emagged. This shuttle
+ features a fully stocked medbay with self serve sleepers, plenty of room that
+ can fit highpop, a fully featured bridge, ballistic auto turrets, and an armory,
+ EVA prep room, and bar, all of which are only accessible by either an agent
+ ID or through hacking.
+
+ -EVA prep features 2 syndicate hardsuits and 3 syndicate softsuits. -Armory
+ features 5 stetchkins with spare ammo, and 2 riot c-20r''s.
+
+ '
+ - balance: Lone operatives no longer spawn with a syndicate hardsuit and a bulldog.
+ They instead spawn with a black and red EVA suit and an extra 15 TC (40 in total)
+ 
+ - rscadd: The tesla engine has been replaced with a supermatter engine, and pubby
+ engineering has been redesigned to accommodate this change.
+ - rscdel: The tesla engine has been completely removed along with any related components
+ - bugfix: RD and R&D vents are now actually connected to the air distribution.
+ - rscadd: New engineering hivebot. Has a bit more health but otherwise aesthetic.
+ - tweak: Oldstation no longer has an excessive amounts of hivebots within it, however
+ the bots that remain are individually a larger threat.
+ - balance: Hivebots are now more robust, with a higher melee damage output and health.
+ - server: Remove this ruin from the blacklist or this PR is pointless.
+ - bugfix: the air injectors for the SM engine waste and for toxins waste should
+ now receive power
+ - tweak: Adds a mixed clothing closet to Deltastation Dorms.
+ - tweak: Adds a bottle of unstable mutagen to Botany, on account of its distance
+ from Chemistry.
+ - bugfix: Omegastation should no longer have any turf with missing textures, as
+ those spots have been replaced with playing covered in a sandy turf decal.
+ - tweak: Removed all living eggs from the xeno ruin because people self antag. Honk.
+ - rscadd: Adds a new security level between Blue and Red (Amber). The shuttle call
+ time at this level is 8 minutes.
+ - tweak: Blue security level now has a shuttle call time of 12 minutes.
+ - tweak: The security level increase/decrease texts have been modified to accommodate
+ the change.
+ - imageadd: Adds a code Amber sprite for the fire alarms
+ - tweak: Removed the plushes from the toy crate, giving them their own.
+ - tweak: Plushes are now less likely to spawn out of arcades
+ - imagedel: Removes a moth plush from the game.
+ - balance: added a small fire delay (3 ticks) to automatic shotguns
+ - balance: Reduced buckshot brute damage by 20%. (12.5 -> 10 brute per pellet) (75
+ -> 60 brute at close range)
+ - balance: Reduced rubbershot stamina damage by 40% (25 -> 15 stamina per pellet)
+ (150 -> 90 stamina at close range)
+ - balance: Reduced beanbag stamina damage by 12.5% (80 -> 70 stamina per shot)
+ - balance: Engivend RCDs now vend upgraded RCDs
+ - imageadd: Beautified and stylized the cyborg HUD sprites, animated and cleaned
+ up some of the old, modernized APC hacking and Doomsday sprites,
+ - tweak: moved cyborg language select above the radio icon, instead of above the
+ picture icon.
+ Twaticus & Poojawa:
+ - rscadd: Added new carpets from TauCetiStation!
+ - rscadd: More Liquid carpet chemicals, mix carpet with certain reagents to get
+ different colors!
+ - refactor: Tablets have a better means of being assembled codewise. nothing's different
+ on player end.
+ UntoldTactics:
+ - tweak: Rewords the click here prompt given when an attempted conversion is done
+ on an offer rune (for blood cult)
+ UristMcAstronaut:
+ - bugfix: allows a pai to activate its holoform while in a pai connector without
+ getting derped.
+ Useroth:
+ - bugfix: the collars are now aware of their proper overlay sprites
+ - bugfix: The space hotel dorms are now properly boltable with the buttons inside.
+ - bugfix: Makes the booze-o-mat hacked by default. Alternative to https://github.com/Citadel-Station-13/Citadel-Station-13/pull/8350.
+ - bugfix: After the PR which raised the ammo capacity of said magazines, due to
+ the code, they ended up with an invalid icon state. Fixed through changing the
+ icon state name in the icon file.
+ - rscadd: 'Taeclowndo shoes which grant the four following abilities: - Conjuring
+ a cream pie right into their hand. Every three seconds. - Making a banana peel
+ appear out of thin air at the tile of the clown''s choice. Every ten seconds.
+ - Mega HoNk. A touch-ranged, very small AOE ability, with effect equal to being
+ honked by a Honkerblast on a clown mech, with the effects halved for anyone
+ who isn''t its direct target. Every ten seconds. - Bluespace Banana Pie. You
+ don''t throw this one... not right away at least. This baby can fit an entire
+ body inside. Good for disposal of evidence. 25 second-long action, 45 second
+ cooldown. Also produces a "[victim''s name] cream pie". The body drops out of
+ the pie if you splat it somewhere or destroy the pie. If you eat it, it will
+ chestburst out of you a''la monkey cube.
+
+ It''s a 14 TC item for traitor clowns and a 12 TC item for clown-ops.'
+ - tweak: The tentacle now directly puts the item in your hands, instead of toggling
+ your throwing and tossing it at you. Tentacles suffer from ranged inaccuracies
+ as if they were guns, I think it's enough of an inconvenience.
+ - tweak: Makes the netting much less clunky. If there's only one target you can
+ net while you press the button, it will just net that target instead of bringing
+ up a list of mobs.
+ - tweak: Energy nets now revive and fully heal capturees (even dead ones, after
+ calculating points). If someone's got a scan and wants to get cloned, they can
+ always kill themselves still.
+ - tweak: Capture points are added on capture, rather than round-end, so it no longer
+ matters whether your captures kill themselves in the holding facility or not.
+ - balance: Makes the nets a bit more sturdy. (previously it took mere two welder
+ hits to break one)
+ - balance: Makes stungloves actually stun people (currently comparably with stunbatons,
+ adjustable). Because electrocute_act(25, H) did fuck all, stunwise, and on top
+ of that, people in insulated gloves were completely unaffected.
+ - balance: Reduced the stunglove electrocute_act value to 15 due to above. Could
+ possibly be lowered further.
+ Weblure:
+ - rscadd: Added the relevant Beepsky animations from TG's aibots.dmi file to Cit's
+ aibots.dmi file.
+ WhiteHusky:
+ - rscadd: Sleepers now show blood level and type.
+ - tweak: Changed the styling of arousal messages to use pink-ish colors.
+ - bugfix: The orgasm moodlet message new-lines properly.
+ - bugfix: Flavor text with special characters will not get partially unescaped.
+ - bugfix: Canceling when setting flavor text does not clear it anymore.
+ - tweak: Checking yourself shouldn't freeze the client anymore.
+ XDTM:
+ - rscadd: Added the experimental dissection surgery, which can be performed once
+ per corpse to gain techweb points.
+ - rscadd: Rarer specimens are more valuable, so xenos and rare species are more
+ efficient subjects.
+ - rscadd: Added two new surgery procedures, under the Experimental Surgery techweb
+ node.
+ - rscadd: Ligament Hook makes it so you can attach limbs manually (like skeletons)
+ but makes dismemberment more likely as well.
+ - rscadd: Ligament Reinforcement prevents dismemberment, but makes limbs easier
+ to disable through damage.
+ - tweak: Golem limbs can now be disabled, although they are still undismemberable.
+ YPOQ:
+ - bugfix: Stealth implants work again
+ Yakumo Chen:
+ - balance: Made stealth implant boxes flimsier
+ - balance: Autocloning now requires tier 4 parts
+ - rscdel: Removes autoscan
+ - balance: Scanning people now requires someone to operate the cloning computer
+ regardless of part level.
+ - balance: removed antimagic component from holymelon
+ YakumoChen:
+ - tweak: AEGs brought more in line with current radiation system. Try not to get
+ EMP'd.
+ - tweak: Jetpacks no longer last twice as long between air refills.
+ - rscdel: Reverted laser miniguns.
+ - rscadd: Adds beanbag slugs to the sec protolathe at round start
+ - bugfix: Brings shotgun ammo availability back in like between seclathe and autolathe.
+ Zargserg:
+ - balance: Lungs maximum toxin threshold is 0.5% of the atmosphere.
+ - bugfix: Permanently contaminated atmosphere does not murder crew anymore.
+ ZeroNetAlpha:
+ - tweak: Cleans up autoylathe code and brings it back in line with the regular autolathe.
+ - bugfix: Fixes autoylathe interface not updating propperly.
+ - tweak: Silicons are now consumable by scrub pups.
+ actioninja:
+ - bugfix: APC UI autoupdates correctly
+ bluespace bio bags:
+ - rscadd: Added bluespace bio bags and put it in the tech web, in the node applied
+ bluespace
+ - imageadd: added a crappy icon for bluespace bio bags
+ chef:
+ - rscadd: Added main hallway approach to monastery
+ - rscadd: Added Maintenance hallway approach, with some maint loot
+ - tweak: moved the docking arm for the white ship
+ - tweak: changed placement of some grills and windows
+ coiax:
+ - admin: When the nuclear disk stays stationary long enough to trigger an increase
+ for the lone op event chance, admins will be notified every five increments.
+ dapnee:
+ - rscadd: Plasmaglass tables, spears, tiny plasmaglass shards
+ - bugfix: Plasmaglass structures now drop plasmaglass shards instead of nothing
+ - rscadd: Trim lines!
+ - bugfix: You can now make plasmaglass tables again.
+ deathride58:
+ - admin: When a gamemode fails pre_setup, it will now send a message in admin IRC
+ and in ingame admin chat, instead of only being viewable in the logs.
+ - balance: Portal guns now spawn without firing pins.
+ - balance: Reduced the default/baseline nanite pool amount from 100 nanites to 25
+ nanites, and reduced the maximum nanite amount from 500 nanites to 125 nanites.
+ The safety threshold was reduced from 50 nanites to 12 nanites.
+ - balance: Most of Lavaland's mobs are now on crack.
+ - balance: Blood drunk miners now move once every two ticks, rather than once every
+ three ticks.
+ - balance: Bubblegum now has a maximum movement speed of once every three ticks.
+ Buffed from the original value of once per 5 ticks.
+ - balance: The minimum time for the Colossus to attack again after firing a random
+ shot is two deciseconds, Sped up from the original value of three seconds. The
+ minimum time for the Colossus to attack again after performing a blast is now
+ one second, with the original value being two seconds. The minimum time for
+ it to attack again after performing its alternating shot pattern is now two
+ seconds, original value being four seconds.
+ - balance: Ashdrakes now move once every five ticks, rather than once every ten
+ ticks.
+ - balance: Heirophant chasers now move once every two ticks rather than three ticks
+ by default, and the chaser cooldown has been reduced from 10 seconds to 5 seconds.
+ The cooldown for the Heirophant's major attacks has also been sped up to 4 seconds
+ from the original value of 6 seconds.
+ - balance: The Legion (megafauna) now moves at two ticks per second rather than
+ three ticks. It additionally now actually moves faster while charging. The cooldown
+ timer for it's special attacks has been reduced from 2 seconds to 1 second.
+ Additionally, The Legion's view range has been decreased from 13 tiles to 10
+ tiles.
+ - balance: All megafauna now have a default view range of 4 tiles, decreased from
+ the original of 5 tiles, and an aggro'd view range of 15 tiles, decreased from
+ the original of 18
+ - balance: Goliaths now move once every ten ticks, sped up from the original value
+ of 40(!!!) ticks. Additionally, their cooldown for their tentacles has been
+ reduced from 12 seconds to 6 seconds. To compensate, their cooldown now only
+ decreases by 5 deciseconds every time they're attacked, rather than 10 deciseconds,
+ their melee damage has been reduced to 18 per hit from 25 per hit, and their
+ vision range has been decreased from 5 tiles unaggroed, 9 tiles when aggroed,
+ to 4 tiles and 7 tiles respectively. Ancient goliaths have a default attack
+ cooldown of 8 seconds, sped up from the original value of 12 seconds.
+ - balance: Legion (the common mob) now has a cooldown of 1.5 seconds on their skull
+ attack, sped up from the original value of 2 seconds. Additionally, their view
+ range has been decreased from 5 tiles, 9 tiles when aggroed, to 4 tiles, 7 tiles
+ when aggroed.
+ - bugfix: Stamina no longer regenerates at hyper speeds.
+ - tweak: To accommodate for upstream's stamina changes, knockdown() now applies
+ staminaloss only to the chest.
+ - tweak: adjuststaminaloss() now has a new argument that allows you to specify a
+ zone to apply staminaloss to. This defaults to the chest
+ - tweak: apply_damage() is now capable of healing carbon mobs and human mobs.
+ - tweak: Since the head has the same exact effects as the chest when disabled, and
+ doesn't really make much sense to be affected by stamina, the head no longer
+ has stamina.
+ - tweak: The chest now has a stamina cap of 200 stamina due to the above.
+ - tweak: Footsteps now sound mostly the same as they did before the hard sync
+ - bugfix: Jukeboxes now properly remove themselves from the active jukebox list
+ when destroyed
+ - rscadd: Server operators and badmins can now make the server play like TG by toggling
+ the stamina buffer on/off using the DISABLE_STAMBUFFER config option.
+ - bugfix: Airlock wires now work as they did prior to the hard sync
+ - balance: The thing you're currently grabbing is now taken into account when left-click
+ disarming. Things you have grabbed now roughly have a 45% chance to be disarmed.
+ - balance: Disarm push rolls are now determined by the target's staminaloss rather
+ than a flat number.
+ - balance: When you're in combat mode, pushing someone who isn't in combat mode
+ is a guaranteed knockdown. Hard counter to stam regen squeezing in melee combat.
+ - balance: Failed disarm push attempts now deals light staminaloss to the target
+ so long as both the attacker and target are standing. The total stamloss dealt
+ to the target is random, clocking in at a very inefficient 1-5 stamloss per
+ unsuccessful push attempt.
+ - tweak: Disarm pushes now play the thudswoosh sound regardless if they're successful
+ or not. Had it not been for copyright, I would've used L4D's melee sound.
+ - tweak: Disarm push attempts are now logged
+ - bugfix: Autostand no longer makes you invulnerable to dropping items when being
+ knocked down with a force greater than 80
+ - bugfix: You can no longer abuse an href exploit to return from the labor camp
+ before obtaining enough points to satisfy your point goal.
+ - bugfix: Norko's donor item is now listed in the right category
+ - rscadd: The medihound sleeper now has a non-vore variant. This will be used by
+ default. The old voracious variant will only appear if both the person being
+ sleeper'd and the medihound have the voracious hound sleepers pref enabled.
+ Sprites by Toriate
+ - tweak: '"Allow medihound sleeper" is now labelled "Voracious medihound sleepers",
+ and is now off by default'
+ - bugfix: AOOC no longer prints to players in the lobby
+ - bugfix: Human tails and human ears now save again. Humans now use mam_tail and
+ mam_ears for their snowflake bits instead of tg's equivalent, just as they did
+ prior to human tail and ear saving breaking
+ - bugfix: Disarm pushes no longer deal staminaloss to resting targets
+ - bugfix: You can no longer force a hard stamcritted spaceman to stand by clicking
+ them with help intent. Get more creative if you want to torture someone that's
+ in hard stamcrit.
+ - tweak: The revolution gamemode now waits until the 20 minute mark before checking
+ for win conditions.
+ - balance: You can no longer resist/move out of grabs while you're resting. Disarming
+ your way out still works, though.
+ - rscadd: Stamina damage now has diminishing returns on people who are in hard staminacrit
+ with the addition of a new multiplier. When you take staminaloss while in hard
+ staminacrit, you'll be under the effects of the new multiplier, which reduces
+ the amount of staminaloss you take from all sources of staminaloss. The diminishing
+ returns multiplier will steadily return to 1 once you're out of staminacrit.
+ - rscadd: You can now scramble while resting. You can do this by dragging your spaceman
+ onto an adjacent turf. This works even if you're in staminacrit, but the timer
+ depends entirely on your staminaloss.
+ - bugfix: Fully augged cyborg people now heal stamina damage properly.
+ - bugfix: Job EXP is now tracked properly for all roles.
+ - balance: Nightmares and shadowpeople have had their light threshold for being
+ considered in darkness reduced. Nightmares can no longer stand unharmed next
+ to a light fixture during a nightshift 100% unharmed. The threshold is high
+ enough so that APC lights on their own won't harm a nightmare, but being on
+ the edge of a light source will.
+ - balance: The detective revolver's .38 bullets are now non-lethal again, but now
+ require 3 shots to hard stamcrit
+ - rscadd: The current lethal variant of the .38 bullets can still be printed at
+ sec protolathes.
+ - rscadd: You can now access ghost roles from the latejoin menu.
+ - rscadd: Eyeblur now scales depending on how much actual eyeblur you actually have.
+ - balance: Ebows now induce 50 drowsiness on whatever they hit.
+ - balance: Telepads have been buffed across the board. T1 parts on a launchpad still
+ grants you a range of 15 tiles, but T4 parts now grant you a pretty large 60
+ tile range (up from their original 18 tile range). Briefcase launchpads were
+ also buffed, they now have a range of 20 tiles, up from their previous laughable
+ 8 tiles.
+ - tweak: The grace period for the revolution win condition check has been reduced
+ from 20 minutes to 10 minutes. You don't need to wait nearly as long for the
+ round to end if no heads join in.
+ - tweak: You can now select plural and neuter as your gender. They're labelled "non-binary"
+ and "object" in the character customization menu, respectively.
+ - tweak: A lot more light sources now use the same nonbinary colored lighting philosophies
+ as flashlights and light fixtures!
+ - tweak: Flashlights mounted to guns and helmets now retain the same color and power
+ as their original light. Lavaland's caves will reflect a fluorescent blue as
+ you shine your KA around, and sec's helmets are now capable of illuminating
+ maint in that fancy fluorescent blue.
+ - tweak: Cameras now shine a fluorescent blue when lit up by an AI
+ - tweak: Glowing goo now actually glows green.
+ - tweak: Candles had their power reduced from 1 to 0.8.
+ - tweak: Lighters now shine a little further, and are now properly colored.
+ - tweak: PDAs now shine an incandescent yellow to match their sprite.
+ - tweak: Welding tools now shine an appropriate color
+ - tweak: Hardhats now shine an incandescent yellow.
+ - tweak: Plasmaman helmets now shine an incandescent yellow.
+ - tweak: Microwaves no longer overpower literally every single light in the game,
+ instead having a power of 0.9.
+ - tweak: Borgs now have incandescent yellow lights to match their sprites
+ - tweak: Bots now shine a fluorescent blue light
+ - tweak: Airlock light overlays are now on the above lighting layer. This means
+ airlock lights can actually be seen in the dark now.
+ - bugfix: The mob spawners list no longer leaves null entries behind when a spawner
+ has a job description defined. The latejoin menu will no longer show ghost roles
+ that are filled, and the spawners menu actually works again.
+ - rscadd: The voting system now actually tracks who voted for what. This means it's
+ now possible to change your vote, and it's possible to see what you voted for.
+ - balance: Using help intent on someone that's in hard stamcrit will now make them
+ heal 15 stamloss.
+ - tweak: Auto fit viewport is now enabled by default for new players. One less question
+ off the FAQ
+ - rscadd: The Khajiit favorite, Skooma, was added as a chemistry recipe that can
+ be produced with cooperation between chemistry and either cargo or service.
+ If you want to spoil the recipe for yourself, take a look at the PR for it!
+ - rscadd: When the shuttle leaves for centcom, a vote will be started to select
+ the next map instead of the map being randomly chosen via biased voting methods
+ - server: If a server operator wishes to re-enable the biased TG preference voting
+ system, you can do so by toggling the TGSTYLE_MAPROTATION config flag on in
+ the config.txt. Keep in mind that doing so will bring you great misfortune.
+ - balance: Cacti in lavaland now have 6u of vitfro instead of just 4u. This lessens
+ the gap between cacti and first aid kits, the third rarest and second rarest
+ readily available healing methods for ashwalkers, respectively.
+ - bugfix: the "genitals use skintone" option now appears in the character appearance
+ menu when appropriate again.
+ - rscadd: Clicking your stamina bar will now show your exact stamina along with
+ info regarding your stamina buffer
+ - bugfix: The bug where ghost role spawners leave null entries in glob.mob_spawners
+ has actually been fixed
+ - bugfix: The Kitchen Gun (TM) is no longer invisible.
+ - balance: The majority of cult spells no longer have exclamation marks at the end
+ of their invocations. This means they will no longer be bound to the rules of
+ shouting. Which means sec officers will no longer be able to hear culties sacrificing
+ the captain from the complete opposite side of the maintenance tunnel the sacrifice
+ is happening in. However, things like EMP pulses and runeless teleportation
+ still have the effect due to their inherent loud nature.
+ - balance: The stun blood spell now instantly causes hard stamcrit. However, to
+ offset this, it now also only has one charge and has a higher cost.
+ - balance: The Gloves of the North Star now restore 2/3 of the stamina used up by
+ punches when harm intent punching. With aggressive play and good stamina buffer
+ management, this makes it entirely plausible to roughly double your stamina
+ regeneration per mob life process tick.
+ - balance: Revs can no longer remember the name of the person who flashed them when
+ deconverted. This brings it in-line with the other conversion antag deconversions.
+ - bugfix: The bug where you can sometimes get permanently stuck in stamcrit should
+ HOPEFULLY be fixed. I'm unable to reproduce the bug myself, but let's hope.
+ - balance: The night vision trait now grants you darksight for an entire 1:1 screen,
+ but the alpha of the lighting plane with the trait has been increased from 245
+ to 250 to balance it out
+ - bugfix: It's now actually possible to click the stamina hud button
+ - bugfix: The stamina hud button now displays your stamina buffer correctly
+ - balance: Bone spears now have a reach of 2 tiles.
+ - bugfix: You can no longer phase through solid objects via scrambling
+ - bugfix: The syndicate mask now works properly as intended.
+ - balance: Stamina is no longer affected by health at all.
+ - rscadd: You can now right-click yourself in help intent in combat mode to instantly
+ get up from resting. This will cost stamina equal to your entire stamina buffer.
+ Manage your stamina well, and you'll be able to shrug off a single stray golden
+ bolt
+ - rscadd: The new player panel now displays your currently selected character's
+ name
+ - balance: Flashes no longer knockdown. Instead, they deal eyeblur and have increased
+ confusion
+ - server: The server's tagline is now a config option. People can now stop confusing
+ us with BR cit
+ - rscadd: Attack animations will now rotate your character slightly, similar to
+ Goon.
+ - rscadd: Throwing items will now perform the attack animation and play a sound
+ - rscadd: flashlights will now make sounds when toggled on/off
+ - rscadd: Things in disposals will now emit sounds every single time they hit corners.
+ This increases immersion.
+ - bugfix: Air alarms now actually emit the proper light color when their status
+ is okay.
+ - rscadd: Backpacks and other storage items will now jiggle and squish when you
+ interact with them, similar to the animations seen on Goon.
+ - balance: Mops no longer have a delay on their cleaning, making them an actually
+ viable alternative to all of the janitor's other cleaning tools
+ - balance: To balance this, mops now take stamina to clean tiles. Standard mops
+ take 5 stamina to use, while advanced mops take 2 stamina.
+ - tweak: Oh and also mops make fancy new sounds and play animations when used now
+ - balance: Pump-action shotguns now take 2 stamina per pump instead of 5 stamina
+ per pump. This also applies to bolt-action rifles, as bolt racking counts as
+ pumping.
+ - tweak: Pickpocketing items will now place them in your hands if possible
+ - rscadd: Combat mode is now displayed in examine text
+ - rscadd: Combat mode now makes a visible message when enabled if you haven't touched
+ your combat mode button in the last ten seconds. It's done this way to avoid
+ chat spam from those who know how to pull off stam regen squeezing.
+ - balance: All knockdown sources will now force people to be dismounted from ridden
+ vehicles.
+ - rscadd: When an item is thrown, it will now be rotated and displaced.
+ - rscadd: Shards of glass will now be rotated when spawned.
+ - rscadd: Bullet casings will now be rotated when they're ejected from a gun.
+ - rscadd: Bottles now have random rotations and pixel offsets when smashed via throwing.
+ - rscadd: Picking up an item will now reset its rotation.
+ - rscadd: Glasses thrown onto tables by bartenders will now have their rotation
+ reset.
+ - balance: Slime speed potions can now only increase the speed of vehicles to be
+ on par with sprinting speed. They can no longer make a scooter roll around ten
+ times faster than a speeding blue hedgehog.
+ - rscdel: Changelings will no longer recieve team objectives
+ - balance: Changelings no longer start off with hivemind communication as an innate
+ ability. Hivemind communication now requires 1 dna point, on par with syndicate
+ encryption keys, which are 2 TC.
+ - code_imp: Hivemind link now relies on hivemind communication just like the hivemind
+ download/upload abilities.
+ - bugfix: It's now only possible to zoom a gun if it's in one of your hands
+ - bugfix: Mobs without clients no longer cause runtimes when their eyeblur updates
+ - rscadd: Blood tests have been added. If a changeling has a sufficient number of
+ loud abilities, you will be able to test their blood by heating up a sample
+ of it. However, if the changeling has a large amount of loud abilities, attempts
+ to test their blood will have explosive results.
+ - rscadd: Changelings now make a very obvious noise when readapting. This is to
+ prevent the cheese strat of simply readapting when you get caught to avoid detection.
+ - tweak: The blood splatter effect that happens when you get attacked will now always
+ make you lose blood depending on the damage you've taken. The effect now also
+ scales with item damage, meaning tiny little papercuts will no longer be able
+ to cause a massive blood splatter.
+ - rscadd: The blood reagent will now cover items and spacemen in blood when applied
+ to objects and mobs.
+ - tweak: Helmets, masks, and neck items are all now valid targets to get splattered
+ when you get covered in blood. Groovy.
+ - tweak: The temperature notification will now take into consideration both the
+ ambient temperature and your body temperature, increasing the responsiveness
+ of the temperature notification and making it much more realistic.
+ - tweak: Shuttle transit borders are now 10 tiles wide instead of 8 tiles, hopefully
+ repairing the immersions that get shattered by the ability to see normal space
+ where the transit areas end.
+ - rscadd: Instead of transit turfs simply teleporting things to space, transit is
+ now handled in a somewhat realistic manner. Transit turfs now act like normal
+ space turfs, though exiting the transit area or being present in the transit
+ area after the shuttle moves out of transit will teleport you to space and throw
+ you in the direction the shuttle was moving in.
+ - tweak: Reservation areas are now able to designate a border turf.
+ - bugfix: The sprint hotkey will no longer cause you to get permanently stuck sprinting
+ if the server lags. Just tap shift again if you get stuck
+ - rscadd: You can now hear sounds in the real world while inside of a VR sleeper.
+ - rscadd: You can now make nameless characters. Nameless characters will spawn in
+ with their name set as their job title followed by a unique five digit number.
+ The "Name" option in the character setup menu will be replaced with a "Default
+ designation" option for nameless characters, and the default designation will
+ be used in place of a job title for assistants and other jobs that don't require
+ dress codes.
+ - admin: The out-of-game round end notification is now a little more verbose. It'll
+ now display the round type, end result of the round, and the survival rate.
+ - bugfix: Xenos can no longer strip items off of people to be capable of using any
+ item in the game.
+ - bugfix: also, items from pockets get placed into your hands properly now
+ - bugfix: A mob's last words are now properly tracked and recorded on death. The
+ first death of the round will now actually display the victim's last words on
+ the round end screen.
+ - bugfix: Divine shenanigans can no longer result in someone becoming immune to
+ staminaloss
+ - bugfix: Fixed body_markings in bodyparts being assigned as a list when in reality,
+ it's a string and literally everything expects it to be a string and uses it
+ as a string. This should mean that markings no longer have completely fucked
+ up caches for character preview and other things.
+ - tweak: Since apparently the game is literally unplayable if items are not in the
+ exact center of a turf, the maximum pixel variance of thrown objects has been
+ reduced by four pixels to make things a smidge more clearer for those that dont
+ know what a turf is.
+ - bugfix: Bartender glasses should HOPEFULLY no longer be tilted when landing on
+ a table. Why the fuck is after_throw called via a timer.
+ - rscadd: Changeling screeches now have their own unique sounds, and are much easier
+ to recognize.
+ - rscadd: Most synthetic emotes are now available to humans. *ping
+ - rscadd: You can now merp
+ - balance: The TEG will now only produce a meaningful amount of power if the hot
+ pipe contains gas that's actively combusting
+ - admin: Added the "add PB bypass" and "revoke PB bypass" verbs, which allow admins
+ to let a specific ckey to bypass the panic bunker for the rest of the round
+ - rscadd: Jogging is no longer treated exactly the same as sprinting for water slips.
+ When you're jogging, you will only slip on water if you have more than 20% staminaloss.
+ - tweak: The atmospherics turf subsystem now has double the wait time, which should
+ free up server processing power for other tasks.
+ - bugfix: The IRC now actually displays the actual survival rate
+ - rscadd: Bloodcult conversions are now consensual. Convertees are given a ten second
+ timer to accept or wait out. This should drastically improve the quality of
+ those that get converted into bloodcult.
+ - rscadd: All sacrifices now count as a third of a cultist for the end-game narsie
+ summon.
+ - bugfix: Nameless captains will no longer proc a "Captain Captain on deck!" message.
+ Instead, it'll be a much more boring but much more sensical "Captain on deck!"
+ message.
+ - bugfix: Transit turfs on the centcom z-level now function properly again at keeping
+ mobs within the areas defined by their boundaries.
+ - bugfix: The title screen is also positioned correctly again.
+ - tweak: Ghost role eligibility for both event and spawner ghost roles is now affected
+ by DNR status. If you suicide, ghost, or cryo out, you will be unable to qualify
+ for any ghost roles
+ - tweak: Cryo now applies DNR status no matter how long the round has been going
+ on
+ - tweak: Suicide is now properly admin logged as it is supposed to be. Ghosting
+ while alive is now also logged.
+ - bugfix: Sparks and igniters will now actually heat areas rather than cooling them,
+ as was intended.
+ - tweak: To alleviate some potential complaints, RPDs now have a cooldown before
+ they can create sparks, and both RPDs and emitters produce less sparks.
+ - tweak: Conversion runes will now mute the victim temporarily while they're deciding
+ whether to convert or be sacrificed.
+ - bugfix: Conversion runes no longer require a third cultist to sacrifice if the
+ victim refuses conversion
+ - bugfix: Staminaloss targeted at the head now properly redirects to the chest.
+ - tweak: Sprinting no longer takes stam when you're being pulled or when you're
+ in zero gravity. Other sources of involuntary movement are not affected.
+ - code_imp: In an attempt to improve performance during highpop, mouse movements
+ will now only call onmousemove() while a user is in combat mode
+ - tweak: Ballistic projectiles are now the only projectiles capable of emitting
+ dinks.
+ - admin: Panic bunker toggling and bypassing is now logged in admin IRC
+ - tweak: OOC and LOOC now use separate toggles. You can now use LOOC while OOC is
+ globally toggled off, and admins now have the option to toggle LOOC off separately
+ from OOC
+ - code_imp: also revamped and reorganized relevant looc adminverb code
+ - bugfix: The endgame narsie summon rune no longer requires 24 total sacrifices,
+ and will now properly account for cultists that surround it
+ - tweak: The succumb verb is now available in the IC tab
+ - tweak: Lighting now uses a linear algorithm to calculate falloff instead of an
+ inverse-square algorithm.
+ - code_imp: get_hearers_in_view() now actually caches the results of view() instead
+ of calling view() twice
+ - code_imp: Goonchat's JS no longer contains checks related to a completely unused
+ message filtering function, which should improve clientside performance quite
+ a bit
+ - rscadd: The storage hud now properly takes into account the viewer's view size,
+ meaning storage items with a large amount of storage slots will properly stretch
+ across the bottom of the screen when running in widescreen.
+ - rscadd: Action buttons are now able to fill the entire screen in widescreen and
+ other weird view sizes.
+ - rscdel: Omegastation's job changes will no longer be included at compile time.
+ - code_imp: The client update portion of /mob/Login() now double-checks to make
+ sure client.player_details exists and is of the proper type. This should hopefully
+ fix the "cannot read null.player_details" runtimes that can spontaneously cause
+ clients to get kicked out and forced back to the lobby.
+ - rscadd: You can now quickly use unequipped items on objects by simply click-dragging
+ the item onto the object with an empty active hand. Doing so will place the
+ item in your hand, and then use that item on the object.
+ - code_imp: In an attempt to improve the performance of /mob/Stat(), various time-related
+ procs now use defines instead of being procs that call procs that call other
+ procs that call even more procs.
+ - bugfix: If a living mob has vore initialized but doesnt have voreprefs initialized,
+ then client login will force voreprefs to load.
+ - bugfix: 'Hopefully fixed paper crash 2: electric boogaloo'
+ - refactor: Added unomos, which is basically listmos except gas mixtures only use
+ one single list for handling their gasses. This is a significant performance
+ improvement that also offers a mild memory improvement under normal circumstances.
+ - balance: Locomotion circuits are now restricted to jogging speed
+ - balance: MMI circuits and pAI circuits both now have 60 complexity, up from their
+ original 29.
+ - tweak: Biogenerators now have a sane limit for production
+ - bugfix: Fixed a fairly huge server crash exploit
+ - bugfix: Shield blobs no longer become completely invulnerable to all forms of
+ damage after reaching a """weakened""" state
+ - tweak: Taken care of what appeared to have been an oversight where shield blobs
+ don't recover their armor after becoming weakened.
+ - bugfix: Nerfed concatenators by limiting the amount of characters they're able
+ to output
+ - tweak: The timer for stripping an item off of a spaceman is no longer interrupted
+ by your active held item changing. This means you no longer have to worry about
+ filling both of your hands when you're stripping items off of someone.
+ - rscadd: Ported the zulie cloak and blackredgold coat donor items from RP.
+ - balance: Normal mops now only use 2 stamina to mop a tile, nerfed from their previous
+ value of 5 stamina per tile mopped.
+ - balance: Advanced mops now only use 1 stamina to mop turfs, from their former
+ value of 2 stam.
+ - tweak: The femur breaker now uses `*scream` instead of forced speech. This means
+ that the femur breaker will no longer spam deadchat with "AAAAAAAAAHHHHHHHHHH!!"
+ - tweak: The femur breaker will now guarantee that the victim falls into crit, which
+ will make it harder to perform torture scenes with it since the victim can just
+ succumb.
+ - bugfix: Fixed another runtime in warp whistles.
+ - bugfix: Spamming forged packets no longer crashes the server.
+ - bugfix: Things that access job_preferences now explicitly access keys, which means
+ it no longer attempts to access invalid indices and runtimes as a result.
+ - balance: The taser's electrode has been reworked. Instead of being a strong knockdown
+ that deals a heavy amount of stamloss, it now causes a weak knockdown, applies
+ a debilitating status effect for 5 seconds, and deals 35 stamloss on hit up
+ to a maximum 50 total stamloss.
+ - balance: Roundstart turrets now have a nonlethal projectile that gets used when
+ they're set to stun and the target is resting
+ - tweak: Hybrid tasers now have disablers set as their default mode.
+ - rscadd: There is now a 1% chance for the station's announcer to be the medibot
+ voice instead of the classic TG announcer.
+ - rscadd: The map config system has been expanded to allow mappers to specify the
+ map type, announcer voice, ingame year, and how often a given map can be voted
+ at roundend.
+ - bugfix: The map vote system now takes into account map playercount limits properly.
+ - bugfix: Examining a spaceman, and other things that use get_examine_string(),
+ will now actually properly show when an item is blood-stained.
+ - bugfix: Plasmaman tongues no longer have a maxHealth of "alien", and no longer
+ cause the organ's on_life to always runtime.
+ - bugfix: Shooting a simplemob no longer causes runtimes prior to the blood effect
+ being created.
+ - bugfix: Removing a filter from an object that lacks filters no longer causes runtimes.
+ deathride58 (Original PR by actioninja):
+ - rscadd: Disarm pushing (combat mode right click in disarm intent) will now actually
+ push mobs away. Knockdowns from disarm pushing are no longer rng based on the
+ target's staminaloss. Knockdowns from disarm pushing now only happen when you
+ push someone into another mob, a table, or a wall. Pushes will now also temporarily
+ stop targets from using firearms, and will disarm the firearm if performed a
+ second time. Pushes still deal staminaloss to standing targets, and won't deal
+ a single ounce of staminaloss to resting targets.
+ - rscdel: You can no longer displace mobs that are in harm intent by simply walking
+ into them. Mobs that aren't in help intent have to be disarm pushed to actually
+ be moved.
+ dtfe3:
+ - tweak: Increased music maxlines from 300 to 600
+ - tweak: Made it so any oxygen tank can be used instead of only red ones.
+ - tweak: Watcher wing Trophy's effect lasts 1 second instead of 0.5
+ - rscadd: Pink Panties
+ - rscadd: Twintails
+ - rscadd: Schoolgirl outfits for the loadout menu!
+ - tweak: Now the fox ears are located in front of hair meaning they now behave much
+ like cat ears, that being they are on-top of the hair layer.
+ izzyinbox:
+ - rscadd: adds VoG orgasm command using words "orgasm", "cum", "squirt", "climax"
+ - rscadd: adds VoG dab command using words "dab" and "mood"
+ - rscadd: Generic dog body marking sprite
+ - imageadd: colormatrix dog sprites
+ - tweak: lowered the player age for command jobs to 1/3 of their previous setting
+ - rscadd: '*bark emote'
+ jtgsz:
+ - rscadd: ported gang mode
+ kappa-sama:
+ - rscdel: Removed racism
+ - tweak: Teleporter calibration actually matters to all roundstart players
+ - balance: Slows down teleportation with the console/hub/teleporter setup if you
+ care for your species.
+ - balance: Dedicated non-humans can now get hulk without having to become human.
+ - bugfix: seed
+ - tweak: added obj/item/key to wallet whitelist
+ - tweak: blood cult ritual daggers fit in jack/combat boots
+ - tweak: voidcells can now unlock alien tech
+ - balance: rebalanced tech trees (not really)
+ - rscadd: hugbox (/s)
+ - tweak: ashwalker spawn text now tells them "i" "c" not to leave lavaland
+ - bugfix: you can no longer have infinite ebows
+ - bugfix: kevinz forgot to nerf miasma research and cargo value after making it
+ produce like 100x as much lmao
+ kevinz000:
+ - balance: Hierophant now goes sicko mode, but hey, at least you can't be multi-hit
+ by melee waves!
+ - rscadd: Racking shotguns is now more threatening.
+ - balance: Medibots no longer kill slimes when trying to heal their toxins.
+ - rscadd: The Syndicate started selling claymores to their agents.
+ - balance: Nerfed VTEC modules.
+ - bugfix: Neurotoxin no longer stuns non-carbons.
+ - rscadd: peacekeeper cyborgs now get a megaphone
+ - bugfix: Fixes storage bugs regarding reaching into things you shouldn't be able
+ to reach into.
+ - code_imp: BYOND 513 preliminary support added.
+ - balance: 'Trashbags now only allow accessing the first 3 items. 5 for bluespace
+ ones. experimental: Storage now allows for limiting of random access'
+ kiwedespars:
+ - rscadd: regenerative materia to hallucination sting
+ - rscadd: mindbreaker toxin as an actual chemical to hallucination sting
+ lolman360:
+ - rscadd: NT has authorized shipments or Cotton to Megaseed Servitors. It's time
+ to start picking, liggers.
+ - imageadd: missing durathread sprites
+ - rscadd: Added durathread jumpskirt
+ - imageadd: Duraskirt sprites and rolled down jumpsuit sprites.
+ - bugfix: Fixes an undocumented change to the naming of Plasmamen.
+ - tweak: chainsaw kind of weapons and the mecha drill and the CLAMP can now be used
+ with 100% accuracy for surgery
+ - refactor: surgery tools now work on defines
+ - balance: advanced surgerytools can now switch types instead of just being faster
+ - bugfix: fixes bug with new surgerytools examine
+ nicc:
+ - rscadd: Exo-suit
+ - rscadd: SEVA suit
+ - rscadd: Flags for Goliath resistance and weakness
+ - rscadd: suit voucher
+ - rscadd: temp suit sprites
+ - rscadd: '*dab'
+ - balance: teg less gay maybe
+ ninjanomnom and WhoneedSpacee:
+ - rscadd: Some rpg affixes now have special effects
+ - rscadd: 'New RPGLoot modifiers: Vampirism which heals you when you attack, Pyromantic
+ which sets things you hit on fire. Shrapnel which causes projectiles fired from
+ a gun to fire projectiles in a radius when they hit something. Finally, Summoning
+ which summons mobs that sometimes aid you in combat.'
+ original by @randolfthemeh and @twaticus, port by sishen1542:
+ - rscadd: jumpskirts
+ - rscadd: more jumpskirts
+ - rscadd: jumpskirt/suit prefs
+ original by Bumtickley00, port by sishen1542:
+ - tweak: Suit storage units will now also remove radiation from mobs.
+ original by GuyonBroadway, SkowronX, and Arizon5. port by sishen1542 and kerse:
+ - rscadd: Clockwork cultists may now summon forth Neovgre, the ratvrarian super
+ weapon. This powerful mech can be summoned when applications scripture has been
+ unlocked, boasts superior offensive and defensive capabilities, however once
+ a pilot enters he cannot leave and is doomed to die with the mech.
+ - imageadd: Sexy Sprite work courtesy or SkowronX from /tg/
+ - imageadd: brass edits by Arizon5
+ - soundadd: steamy laser by kerse
+ original by Skoglol, port by sishen1542:
+ - balance: Added lots of new virus cures, made cure difficulty scale more consistently.
+ Cures are now picked from a list of possible cures per resistance level, multiple
+ diseases at the same level no longer always share a cure. Looking at you table
+ salt.
+ - admin: Dynamic gamemode now more auto-deadmin friendly.
+ original by TheChosenEvilOne, port by sishen1542:
+ - rscadd: Ported dynamic mode from /vg/, originally made by @DeityLink, @Kurfursten
+ and @ShiftyRail
+ original by Tlaltecuhtli, port by sishen1542:
+ - rscadd: rcd disk that gives rcd computer frame and machine frame designs
+ - rscadd: upgraded rcd in CE lockers
+ - tweak: moved deconstruction to the upgrade disk, ashwalker rcd comes upgraded
+ original by actioninja, port by sishen1542:
+ - tweak: Medical and Security consoles now check access on worn or inhand ID instead
+ of requiring an inserted ID
+ - tweak: mining vendor now reads from ID in hand or on person instead of requiring
+ an inserted ID
+ - bugfix: ORM is functional again (for real this time)
+ - tweak: ORM claim points button transfers points to worn/inhand ID instead of to
+ an inserted ID, no longer accepts insertions
+ - tweak: Same for gulag consoles
+ original by redmoogle, port by sishen1542:
+ - rscadd: Added support for 3 new gasses; Tritium, Pluoxium, and BZ
+ 'original by: WJohnston, Antur, Arcane, plapatin, sprites by cogwerks and edited by mrdoombringer. port by sishen1542':
+ - rscadd: THE GOOSE IS LOOSE
+ r4d6:
+ - rscadd: Added decoratives angel wings for Mammalians only
+ - rscadd: Added blindfolds to the Loadout list
+ - rscadd: Added Decorative Wings for Humans, Felinids, Slimepersons and Lizardpeoples.
+ - tweak: Change the SEVA suit & Exo-suit's descriptions
+ - bugfix: Batteries are now Rad-Proof like the other stock parts
+ tigercat2000@Paradise:
+ - bugfix: fixed invalid characters breaking chat output for that message
+ tinfoil hat wearer:
+ - rscadd: Added a new alien technology disk to scientist and roboticist uplinks
+ that allows them to research the heavily-guarded secrets of the Grays.
+ - tweak: Alientech is now the only Hidden alien research. To compensate for this,
+ alien_bio and alien_engi have had their research costs doubled and now require
+ advanced surgery tools and experimental tools respectively to research. Their
+ export price is also halved.
+ - balance: roboticists now have brainwashing disks AND alien technology added to
+ their role-restricted uplink section. alien technology gives them brainwashing
+ at a much later date, so brainwashing is the much cheaper option for instant
+ power. makes logical sense because doctors get it as well because they do surgery,
+ and roboticists can now either choose to brainwash people for less price but
+ less power or emag borgs for higher prices, limited uses, but higher power.
+ ursamedium:
+ - imageadd: Gas icons changed.
diff --git a/html/changelogs/AutoChangeLog-pr-7451.yml b/html/changelogs/AutoChangeLog-pr-7451.yml
deleted file mode 100644
index ea4ec47b8d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7451.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - admin: "When a gamemode fails pre_setup, it will now send a message in admin IRC and in ingame admin chat, instead of only being viewable in the logs."
diff --git a/html/changelogs/AutoChangeLog-pr-7465.yml b/html/changelogs/AutoChangeLog-pr-7465.yml
deleted file mode 100644
index 4f47fed4e5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7465.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Portal guns now spawn without firing pins."
diff --git a/html/changelogs/AutoChangeLog-pr-7544.yml b/html/changelogs/AutoChangeLog-pr-7544.yml
deleted file mode 100644
index f70a0e0e30..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7544.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Reduced the default/baseline nanite pool amount from 100 nanites to 25 nanites, and reduced the maximum nanite amount from 500 nanites to 125 nanites. The safety threshold was reduced from 50 nanites to 12 nanites."
diff --git a/html/changelogs/AutoChangeLog-pr-7550.yml b/html/changelogs/AutoChangeLog-pr-7550.yml
deleted file mode 100644
index 2bef8d3854..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7550.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Most of Lavaland's mobs are now on crack."
- - balance: "Blood drunk miners now move once every two ticks, rather than once every three ticks."
- - balance: "Bubblegum now has a maximum movement speed of once every three ticks. Buffed from the original value of once per 5 ticks."
- - balance: "The minimum time for the Colossus to attack again after firing a random shot is two deciseconds, Sped up from the original value of three seconds. The minimum time for the Colossus to attack again after performing a blast is now one second, with the original value being two seconds. The minimum time for it to attack again after performing its alternating shot pattern is now two seconds, original value being four seconds."
- - balance: "Ashdrakes now move once every five ticks, rather than once every ten ticks."
- - balance: "Heirophant chasers now move once every two ticks rather than three ticks by default, and the chaser cooldown has been reduced from 10 seconds to 5 seconds. The cooldown for the Heirophant's major attacks has also been sped up to 4 seconds from the original value of 6 seconds."
- - balance: "The Legion (megafauna) now moves at two ticks per second rather than three ticks. It additionally now actually moves faster while charging. The cooldown timer for it's special attacks has been reduced from 2 seconds to 1 second. Additionally, The Legion's view range has been decreased from 13 tiles to 10 tiles."
- - balance: "All megafauna now have a default view range of 4 tiles, decreased from the original of 5 tiles, and an aggro'd view range of 15 tiles, decreased from the original of 18"
- - balance: "Goliaths now move once every ten ticks, sped up from the original value of 40(!!!) ticks. Additionally, their cooldown for their tentacles has been reduced from 12 seconds to 6 seconds. To compensate, their cooldown now only decreases by 5 deciseconds every time they're attacked, rather than 10 deciseconds, their melee damage has been reduced to 18 per hit from 25 per hit, and their vision range has been decreased from 5 tiles unaggroed, 9 tiles when aggroed, to 4 tiles and 7 tiles respectively. Ancient goliaths have a default attack cooldown of 8 seconds, sped up from the original value of 12 seconds."
- - balance: "Legion (the common mob) now has a cooldown of 1.5 seconds on their skull attack, sped up from the original value of 2 seconds. Additionally, their view range has been decreased from 5 tiles, 9 tiles when aggroed, to 4 tiles, 7 tiles when aggroed."
diff --git a/html/changelogs/AutoChangeLog-pr-7592.yml b/html/changelogs/AutoChangeLog-pr-7592.yml
deleted file mode 100644
index 10ba557d76..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7592.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Digitigrade legs are now able to wear shoes and look fancy, Uniforms to come."
- - tweak: "Xenos are only digitigrade now, mammals and aquatics have the option."
diff --git a/html/changelogs/AutoChangeLog-pr-7596.yml b/html/changelogs/AutoChangeLog-pr-7596.yml
deleted file mode 100644
index a0dfbfe151..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7596.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Stamina no longer regenerates at hyper speeds."
- - tweak: "To accommodate for upstream's stamina changes, knockdown() now applies staminaloss only to the chest."
- - tweak: "adjuststaminaloss() now has a new argument that allows you to specify a zone to apply staminaloss to. This defaults to the chest"
- - tweak: "apply_damage() is now capable of healing carbon mobs and human mobs."
- - tweak: "Since the head has the same exact effects as the chest when disabled, and doesn't really make much sense to be affected by stamina, the head no longer has stamina."
- - tweak: "The chest now has a stamina cap of 200 stamina due to the above."
diff --git a/html/changelogs/AutoChangeLog-pr-7598.yml b/html/changelogs/AutoChangeLog-pr-7598.yml
deleted file mode 100644
index 5c15f79f98..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7598.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Footsteps now sound mostly the same as they did before the hard sync"
diff --git a/html/changelogs/AutoChangeLog-pr-7600.yml b/html/changelogs/AutoChangeLog-pr-7600.yml
deleted file mode 100644
index 9e63c069d2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7600.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Fire Alarms are visible in low light situations"
diff --git a/html/changelogs/AutoChangeLog-pr-7604.yml b/html/changelogs/AutoChangeLog-pr-7604.yml
deleted file mode 100644
index 3dcc7c542c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7604.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Jukeboxes now properly remove themselves from the active jukebox list when destroyed"
diff --git a/html/changelogs/AutoChangeLog-pr-7605.yml b/html/changelogs/AutoChangeLog-pr-7605.yml
deleted file mode 100644
index 21d2e882bc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7605.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed vore prefs saving inconsistently, new characters might have a previous slot's prefs tacked on."
- - bugfix: "fixed mammals not having the option for digilegs. Sprites are fucky until body-part related sprites are done."
diff --git a/html/changelogs/AutoChangeLog-pr-7608.yml b/html/changelogs/AutoChangeLog-pr-7608.yml
deleted file mode 100644
index 898cf84d90..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7608.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Server operators and badmins can now make the server play like TG by toggling the stamina buffer on/off using the DISABLE_STAMBUFFER config option."
diff --git a/html/changelogs/AutoChangeLog-pr-7611.yml b/html/changelogs/AutoChangeLog-pr-7611.yml
deleted file mode 100644
index a76e79cf39..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7611.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "nicc"
-delete-after: True
-changes:
- - rscadd: "Exo-suit"
- - rscadd: "SEVA suit"
- - rscadd: "Flags for Goliath resistance and weakness"
- - rscadd: "suit voucher"
- - rscadd: "temp suit sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-7612.yml b/html/changelogs/AutoChangeLog-pr-7612.yml
deleted file mode 100644
index 2e429013ec..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7612.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - code_imp: "default radiation insulation is now handled by atom vars rather than a component, components can still be used."
diff --git a/html/changelogs/AutoChangeLog-pr-7620.yml b/html/changelogs/AutoChangeLog-pr-7620.yml
deleted file mode 100644
index b786b77476..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7620.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Airlock wires now work as they did prior to the hard sync"
diff --git a/html/changelogs/AutoChangeLog-pr-7624.yml b/html/changelogs/AutoChangeLog-pr-7624.yml
deleted file mode 100644
index 34f23f6560..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7624.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "The thing you're currently grabbing is now taken into account when left-click disarming. Things you have grabbed now roughly have a 45% chance to be disarmed."
- - balance: "Disarm push rolls are now determined by the target's staminaloss rather than a flat number."
- - balance: "When you're in combat mode, pushing someone who isn't in combat mode is a guaranteed knockdown. Hard counter to stam regen squeezing in melee combat."
- - balance: "Failed disarm push attempts now deals light staminaloss to the target so long as both the attacker and target are standing. The total stamloss dealt to the target is random, clocking in at a very inefficient 1-5 stamloss per unsuccessful push attempt."
- - tweak: "Disarm pushes now play the thudswoosh sound regardless if they're successful or not. Had it not been for copyright, I would've used L4D's melee sound."
- - tweak: "Disarm push attempts are now logged"
diff --git a/html/changelogs/AutoChangeLog-pr-7625.yml b/html/changelogs/AutoChangeLog-pr-7625.yml
deleted file mode 100644
index a6e72eab8f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7625.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - refactor: "improved vore sound responsiveness to preference choices."
- - balance: "removed morphine from Medihound sleeper chemical list"
- - bugfix: "fixed preference setting being broken"
- - refactor: "Medihound sleepers are Initialized properly, and icons update correctly now on eject"
diff --git a/html/changelogs/AutoChangeLog-pr-7626.yml b/html/changelogs/AutoChangeLog-pr-7626.yml
deleted file mode 100644
index 000c39c0cd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7626.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - tweak: "Air alarm All clear color changed from green to blue"
diff --git a/html/changelogs/AutoChangeLog-pr-7627.yml b/html/changelogs/AutoChangeLog-pr-7627.yml
deleted file mode 100644
index 2490900f6a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7627.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - balance: "APCs are harder to destroy."
diff --git a/html/changelogs/AutoChangeLog-pr-7630.yml b/html/changelogs/AutoChangeLog-pr-7630.yml
deleted file mode 100644
index 4f2d6081a0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7630.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - tweak: "Changes large parts of the nuclear operative base, including the addition of a new barracks where the ops spawn, a personal bedroom for the leader, the rearrangement of numerous rooms, some added fluff, a slightly more roomy bar, a larger hanger, a kitchen, and various other small changes to make the base feel just a bit more alive. This was achieved by completely redoing the base from scratch so there was room to work with, as a result potential bugs could crop, please do report them."
- - bugfix: "The drop pod chamber was airless. This seems like an oversight, and has been filled with air."
diff --git a/html/changelogs/AutoChangeLog-pr-7631.yml b/html/changelogs/AutoChangeLog-pr-7631.yml
deleted file mode 100644
index 4dc1e42bf3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7631.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "nicc"
-delete-after: True
-changes:
- - rscadd: "*dab"
diff --git a/html/changelogs/AutoChangeLog-pr-7632.yml b/html/changelogs/AutoChangeLog-pr-7632.yml
deleted file mode 100644
index 69bac5623f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7632.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added Digitigrade versions of everything appliciable in suit.dmi"
- - imageadd: "Snowflake Icons weren't modified, and were given NO_MUTANTRACE_VARIATION"
diff --git a/html/changelogs/AutoChangeLog-pr-7639.yml b/html/changelogs/AutoChangeLog-pr-7639.yml
deleted file mode 100644
index 8ecd3c4c5c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7639.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - imageadd: "naga and quad Taurs literally don't freeze their ass off in space anymore."
- - bugfix: "Digitigrade legs will toggle on/off properly on character menue"
- - bugfix: "The misleading \"normal\" has been removed from species options"
diff --git a/html/changelogs/AutoChangeLog-pr-7640.yml b/html/changelogs/AutoChangeLog-pr-7640.yml
deleted file mode 100644
index 7360022b33..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7640.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - balance: "Added sanity checks to emag usage"
diff --git a/html/changelogs/AutoChangeLog-pr-7643.yml b/html/changelogs/AutoChangeLog-pr-7643.yml
deleted file mode 100644
index c74534bd34..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7643.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - rscadd: "Medihounds now have rollerbeds for non-vore patient transport"
diff --git a/html/changelogs/AutoChangeLog-pr-7650.yml b/html/changelogs/AutoChangeLog-pr-7650.yml
deleted file mode 100644
index ba84b55d33..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7650.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Autostand no longer makes you invulnerable to dropping items when being knocked down with a force greater than 80"
diff --git a/html/changelogs/AutoChangeLog-pr-7652.yml b/html/changelogs/AutoChangeLog-pr-7652.yml
deleted file mode 100644
index 4695db6186..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7652.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Toriate"
-delete-after: True
-changes:
- - imageadd: "All regular crates are now 3/4ths ToriCrates
-iamgeadd: Unused plastic crate sprite added"
- - rscadd: "Blood freezer crates now have unique sprites."
diff --git a/html/changelogs/AutoChangeLog-pr-7653.yml b/html/changelogs/AutoChangeLog-pr-7653.yml
deleted file mode 100644
index a761e5d393..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7653.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "You can no longer abuse an href exploit to return from the labor camp before obtaining enough points to satisfy your point goal."
diff --git a/html/changelogs/AutoChangeLog-pr-7658.yml b/html/changelogs/AutoChangeLog-pr-7658.yml
deleted file mode 100644
index bcbff333a4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7658.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Norko's donor item is now listed in the right category"
diff --git a/html/changelogs/AutoChangeLog-pr-7659.yml b/html/changelogs/AutoChangeLog-pr-7659.yml
deleted file mode 100644
index 1be7e6d1f3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7659.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "The medihound sleeper now has a non-vore variant. This will be used by default. The old voracious variant will only appear if both the person being sleeper'd and the medihound have the voracious hound sleepers pref enabled. Sprites by Toriate"
- - tweak: "\"Allow medihound sleeper\" is now labelled \"Voracious medihound sleepers\", and is now off by default"
diff --git a/html/changelogs/AutoChangeLog-pr-7660.yml b/html/changelogs/AutoChangeLog-pr-7660.yml
deleted file mode 100644
index 825553bbcb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7660.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - bugfix: "The closed O2 crate now uses the same color scheme as the open one"
diff --git a/html/changelogs/AutoChangeLog-pr-7664.yml b/html/changelogs/AutoChangeLog-pr-7664.yml
deleted file mode 100644
index 47be323084..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7664.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "AOOC no longer prints to players in the lobby"
diff --git a/html/changelogs/AutoChangeLog-pr-7666.yml b/html/changelogs/AutoChangeLog-pr-7666.yml
deleted file mode 100644
index 0b6183b403..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7666.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - rscadd: "Cryo Sleepers have been added to Perma on all four maps in rotation. the bathroom windoor and window have switched places to accommodate this change."
diff --git a/html/changelogs/AutoChangeLog-pr-7667.yml b/html/changelogs/AutoChangeLog-pr-7667.yml
deleted file mode 100644
index c27be81efd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7667.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed vtech, but it still doesn't work because of overriding jog/sprint mechanics from combat reworks."
- - bugfix: "Puppy jaws properly store if you're emagged, they are also toggle-able for stealth like the tongue."
- - bugfix: "Digitigrade legs should properly fucking update for the last fucking time. Fucking snowflake code.
-refractor: Got rid of snowflake sechound cuffs, gave them normal zipties like regular secborgs."
- - bugfix: "dogborg sleepers actually extinguish people who are on fire, in case you don't have time to lick them out."
diff --git a/html/changelogs/AutoChangeLog-pr-7671.yml b/html/changelogs/AutoChangeLog-pr-7671.yml
deleted file mode 100644
index 193bd574e4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7671.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Human tails and human ears now save again. Humans now use mam_tail and mam_ears for their snowflake bits instead of tg's equivalent, just as they did prior to human tail and ear saving breaking"
diff --git a/html/changelogs/AutoChangeLog-pr-7675.yml b/html/changelogs/AutoChangeLog-pr-7675.yml
deleted file mode 100644
index aab21aa377..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7675.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - rscadd: "You can now choose the pre-exisiting \"loader\" sprite as an appearance for your engineering borg."
diff --git a/html/changelogs/AutoChangeLog-pr-7677.yml b/html/changelogs/AutoChangeLog-pr-7677.yml
deleted file mode 100644
index c194004c9c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7677.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - tweak: "A vast majority of references to humans within ion laws have been replaced with crew. AI modules have received similar treatment"
diff --git a/html/changelogs/AutoChangeLog-pr-7681.yml b/html/changelogs/AutoChangeLog-pr-7681.yml
deleted file mode 100644
index 1398a037a1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7681.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Disarm pushes no longer deal staminaloss to resting targets"
diff --git a/html/changelogs/AutoChangeLog-pr-7683.yml b/html/changelogs/AutoChangeLog-pr-7683.yml
deleted file mode 100644
index e092f3d199..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7683.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "You can no longer force a hard stamcritted spaceman to stand by clicking them with help intent. Get more creative if you want to torture someone that's in hard stamcrit."
diff --git a/html/changelogs/AutoChangeLog-pr-7686.yml b/html/changelogs/AutoChangeLog-pr-7686.yml
deleted file mode 100644
index c2dc25894a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7686.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "The revolution gamemode now waits until the 20 minute mark before checking for win conditions."
diff --git a/html/changelogs/AutoChangeLog-pr-7688.yml b/html/changelogs/AutoChangeLog-pr-7688.yml
deleted file mode 100644
index 9098e4f1e1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7688.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "You can no longer resist/move out of grabs while you're resting. Disarming your way out still works, though."
diff --git a/html/changelogs/AutoChangeLog-pr-7689.yml b/html/changelogs/AutoChangeLog-pr-7689.yml
deleted file mode 100644
index 6a8541dba8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7689.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Stamina damage now has diminishing returns on people who are in hard staminacrit with the addition of a new multiplier. When you take staminaloss while in hard staminacrit, you'll be under the effects of the new multiplier, which reduces the amount of staminaloss you take from all sources of staminaloss. The diminishing returns multiplier will steadily return to 1 once you're out of staminacrit."
- - rscadd: "You can now scramble while resting. You can do this by dragging your spaceman onto an adjacent turf. This works even if you're in staminacrit, but the timer depends entirely on your staminaloss."
diff --git a/html/changelogs/AutoChangeLog-pr-7694.yml b/html/changelogs/AutoChangeLog-pr-7694.yml
deleted file mode 100644
index 21949649bb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7694.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "izzyinbox"
-delete-after: True
-changes:
- - rscadd: "adds VoG orgasm command using words \"orgasm\", \"cum\", \"squirt\", \"climax\""
- - rscadd: "adds VoG dab command using words \"dab\" and \"mood\""
diff --git a/html/changelogs/AutoChangeLog-pr-7696.yml b/html/changelogs/AutoChangeLog-pr-7696.yml
deleted file mode 100644
index 09246b01ad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7696.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "ursamedium"
-delete-after: True
-changes:
- - imageadd: "Gas icons changed."
diff --git a/html/changelogs/AutoChangeLog-pr-7699.yml b/html/changelogs/AutoChangeLog-pr-7699.yml
deleted file mode 100644
index dd714ba1de..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7699.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Fully augged cyborg people now heal stamina damage properly."
diff --git a/html/changelogs/AutoChangeLog-pr-7700.yml b/html/changelogs/AutoChangeLog-pr-7700.yml
deleted file mode 100644
index 2893239d8e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7700.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Taur suits should fix themselves properly when worn by other people."
diff --git a/html/changelogs/AutoChangeLog-pr-7703.yml b/html/changelogs/AutoChangeLog-pr-7703.yml
deleted file mode 100644
index 772b45bc8e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7703.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Job EXP is now tracked properly for all roles."
diff --git a/html/changelogs/AutoChangeLog-pr-7712.yml b/html/changelogs/AutoChangeLog-pr-7712.yml
deleted file mode 100644
index 8f1ac6d4c4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7712.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - rscadd: "Adds a syndicate themed emergency shuttle that costs 20000 credits, and can ONLY be purchased when the communications console is emagged. This shuttle features a fully stocked medbay with self serve sleepers, plenty of room that can fit highpop, a fully featured bridge, ballistic auto turrets, and an armory, EVA prep room, and bar, all of which are only accessible by either an agent ID or through hacking.
-
--EVA prep features 2 syndicate hardsuits and 3 syndicate softsuits.
--Armory features 5 stetchkins with spare ammo, and 2 riot c-20r's.
-
-"
diff --git a/html/changelogs/AutoChangeLog-pr-7714.yml b/html/changelogs/AutoChangeLog-pr-7714.yml
deleted file mode 100644
index 2b860f656b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7714.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - balance: "Lone operatives no longer spawn with a syndicate hardsuit and a bulldog. They instead spawn with a black and red EVA suit and an extra 15 TC (40 in total)
-"
diff --git a/html/changelogs/AutoChangeLog-pr-7717.yml b/html/changelogs/AutoChangeLog-pr-7717.yml
deleted file mode 100644
index a3acd0a3ea..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7717.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - rscadd: "The tesla engine has been replaced with a supermatter engine, and pubby engineering has been redesigned to accommodate this change."
- - rscdel: "The tesla engine has been completely removed along with any related components"
- - bugfix: "RD and R&D vents are now actually connected to the air distribution."
diff --git a/html/changelogs/AutoChangeLog-pr-7719.yml b/html/changelogs/AutoChangeLog-pr-7719.yml
deleted file mode 100644
index fec98e6cd0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7719.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Nightmares and shadowpeople have had their light threshold for being considered in darkness reduced. Nightmares can no longer stand unharmed next to a light fixture during a nightshift 100% unharmed. The threshold is high enough so that APC lights on their own won't harm a nightmare, but being on the edge of a light source will."
diff --git a/html/changelogs/AutoChangeLog-pr-7721.yml b/html/changelogs/AutoChangeLog-pr-7721.yml
deleted file mode 100644
index b0060318dd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7721.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - rscadd: "New engineering hivebot. Has a bit more health but otherwise aesthetic."
- - tweak: "Oldstation no longer has an excessive amounts of hivebots within it, however the bots that remain are individually a larger threat."
- - balance: "Hivebots are now more robust, with a higher melee damage output and health."
- - server: "Remove this ruin from the blacklist or this PR is pointless."
diff --git a/html/changelogs/AutoChangeLog-pr-7723.yml b/html/changelogs/AutoChangeLog-pr-7723.yml
deleted file mode 100644
index 2b54faed3e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7723.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "The detective revolver's .38 bullets are now non-lethal again, but now require 3 shots to hard stamcrit"
- - rscadd: "The current lethal variant of the .38 bullets can still be printed at sec protolathes."
diff --git a/html/changelogs/AutoChangeLog-pr-7726.yml b/html/changelogs/AutoChangeLog-pr-7726.yml
deleted file mode 100644
index f777d8db6d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7726.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "You can now access ghost roles from the latejoin menu."
diff --git a/html/changelogs/AutoChangeLog-pr-7727.yml b/html/changelogs/AutoChangeLog-pr-7727.yml
deleted file mode 100644
index cb8337ad94..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7727.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Eyeblur now scales depending on how much actual eyeblur you actually have."
diff --git a/html/changelogs/AutoChangeLog-pr-7728.yml b/html/changelogs/AutoChangeLog-pr-7728.yml
deleted file mode 100644
index bed83efd8e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7728.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Ebows now induce 50 drowsiness on whatever they hit."
diff --git a/html/changelogs/AutoChangeLog-pr-7729.yml b/html/changelogs/AutoChangeLog-pr-7729.yml
deleted file mode 100644
index f57c246d8e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7729.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Telepads have been buffed across the board. T1 parts on a launchpad still grants you a range of 15 tiles, but T4 parts now grant you a pretty large 60 tile range (up from their original 18 tile range). Briefcase launchpads were also buffed, they now have a range of 20 tiles, up from their previous laughable 8 tiles."
diff --git a/html/changelogs/AutoChangeLog-pr-7730.yml b/html/changelogs/AutoChangeLog-pr-7730.yml
deleted file mode 100644
index 1e10b14409..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7730.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "The grace period for the revolution win condition check has been reduced from 20 minutes to 10 minutes. You don't need to wait nearly as long for the round to end if no heads join in."
diff --git a/html/changelogs/AutoChangeLog-pr-7731.yml b/html/changelogs/AutoChangeLog-pr-7731.yml
deleted file mode 100644
index c11a22fb00..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7731.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "You can now select plural and neuter as your gender. They're labelled \"non-binary\" and \"object\" in the character customization menu, respectively."
diff --git a/html/changelogs/AutoChangeLog-pr-7733.yml b/html/changelogs/AutoChangeLog-pr-7733.yml
deleted file mode 100644
index dd28d4840a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7733.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "R3dtail"
-delete-after: True
-changes:
- - rscadd: "Added 16 saltprimaryobject items
-Added 4 saltsecondarysubject items"
diff --git a/html/changelogs/AutoChangeLog-pr-7734.yml b/html/changelogs/AutoChangeLog-pr-7734.yml
deleted file mode 100644
index 0a6064e42a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7734.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "A lot more light sources now use the same nonbinary colored lighting philosophies as flashlights and light fixtures!"
- - tweak: "Flashlights mounted to guns and helmets now retain the same color and power as their original light. Lavaland's caves will reflect a fluorescent blue as you shine your KA around, and sec's helmets are now capable of illuminating maint in that fancy fluorescent blue."
- - tweak: "Cameras now shine a fluorescent blue when lit up by an AI"
- - tweak: "Glowing goo now actually glows green."
- - tweak: "Candles had their power reduced from 1 to 0.8."
- - tweak: "Lighters now shine a little further, and are now properly colored."
- - tweak: "PDAs now shine an incandescent yellow to match their sprite."
- - tweak: "Welding tools now shine an appropriate color"
- - tweak: "Hardhats now shine an incandescent yellow."
- - tweak: "Plasmaman helmets now shine an incandescent yellow."
- - tweak: "Microwaves no longer overpower literally every single light in the game, instead having a power of 0.9."
- - tweak: "Borgs now have incandescent yellow lights to match their sprites"
- - tweak: "Bots now shine a fluorescent blue light"
diff --git a/html/changelogs/AutoChangeLog-pr-7735.yml b/html/changelogs/AutoChangeLog-pr-7735.yml
deleted file mode 100644
index bf5e5bef17..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7735.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Airlock light overlays are now on the above lighting layer. This means airlock lights can actually be seen in the dark now."
diff --git a/html/changelogs/AutoChangeLog-pr-7736.yml b/html/changelogs/AutoChangeLog-pr-7736.yml
deleted file mode 100644
index e3678536a7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7736.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The mob spawners list no longer leaves null entries behind when a spawner has a job description defined. The latejoin menu will no longer show ghost roles that are filled, and the spawners menu actually works again."
diff --git a/html/changelogs/AutoChangeLog-pr-7737.yml b/html/changelogs/AutoChangeLog-pr-7737.yml
deleted file mode 100644
index 9cc206e243..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7737.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "The voting system now actually tracks who voted for what. This means it's now possible to change your vote, and it's possible to see what you voted for."
diff --git a/html/changelogs/AutoChangeLog-pr-7738.yml b/html/changelogs/AutoChangeLog-pr-7738.yml
deleted file mode 100644
index 164906cde8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7738.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Using help intent on someone that's in hard stamcrit will now make them heal 15 stamloss."
diff --git a/html/changelogs/AutoChangeLog-pr-7739.yml b/html/changelogs/AutoChangeLog-pr-7739.yml
deleted file mode 100644
index 0a5f3c5501..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7739.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - bugfix: "the air injectors for the SM engine waste and for toxins waste should now receive power"
diff --git a/html/changelogs/AutoChangeLog-pr-7741.yml b/html/changelogs/AutoChangeLog-pr-7741.yml
deleted file mode 100644
index 19cecfc263..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7741.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Auto fit viewport is now enabled by default for new players. One less question off the FAQ"
diff --git a/html/changelogs/AutoChangeLog-pr-7742.yml b/html/changelogs/AutoChangeLog-pr-7742.yml
deleted file mode 100644
index 94ed23aafa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7742.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "The Khajiit favorite, Skooma, was added as a chemistry recipe that can be produced with cooperation between chemistry and either cargo or service. If you want to spoil the recipe for yourself, take a look at the PR for it!"
diff --git a/html/changelogs/AutoChangeLog-pr-7743.yml b/html/changelogs/AutoChangeLog-pr-7743.yml
deleted file mode 100644
index 623baa0f1d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7743.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "When the shuttle leaves for centcom, a vote will be started to select the next map instead of the map being randomly chosen via biased voting methods"
- - server: "If a server operator wishes to re-enable the biased TG preference voting system, you can do so by toggling the TGSTYLE_MAPROTATION config flag on in the config.txt. Keep in mind that doing so will bring you great misfortune."
diff --git a/html/changelogs/AutoChangeLog-pr-7748.yml b/html/changelogs/AutoChangeLog-pr-7748.yml
deleted file mode 100644
index 34cdf952f5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7748.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Cacti in lavaland now have 6u of vitfro instead of just 4u. This lessens the gap between cacti and first aid kits, the third rarest and second rarest readily available healing methods for ashwalkers, respectively."
diff --git a/html/changelogs/AutoChangeLog-pr-7750.yml b/html/changelogs/AutoChangeLog-pr-7750.yml
deleted file mode 100644
index b835b8b102..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7750.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "the \"genitals use skintone\" option now appears in the character appearance menu when appropriate again."
diff --git a/html/changelogs/AutoChangeLog-pr-7751.yml b/html/changelogs/AutoChangeLog-pr-7751.yml
deleted file mode 100644
index 788f083cf1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7751.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Clicking your stamina bar will now show your exact stamina along with info regarding your stamina buffer"
diff --git a/html/changelogs/AutoChangeLog-pr-7752.yml b/html/changelogs/AutoChangeLog-pr-7752.yml
deleted file mode 100644
index 71fc9feb70..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7752.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "YPOQ"
-delete-after: True
-changes:
- - bugfix: "Stealth implants work again"
diff --git a/html/changelogs/AutoChangeLog-pr-7754.yml b/html/changelogs/AutoChangeLog-pr-7754.yml
deleted file mode 100644
index 2599671fb5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7754.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The bug where ghost role spawners leave null entries in glob.mob_spawners has actually been fixed"
diff --git a/html/changelogs/AutoChangeLog-pr-7756.yml b/html/changelogs/AutoChangeLog-pr-7756.yml
deleted file mode 100644
index 6355b1a6ef..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7756.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The Kitchen Gun (TM) is no longer invisible."
diff --git a/html/changelogs/AutoChangeLog-pr-7765.yml b/html/changelogs/AutoChangeLog-pr-7765.yml
deleted file mode 100644
index 6d7c5c4075..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7765.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "The majority of cult spells no longer have exclamation marks at the end of their invocations. This means they will no longer be bound to the rules of shouting. Which means sec officers will no longer be able to hear culties sacrificing the captain from the complete opposite side of the maintenance tunnel the sacrifice is happening in. However, things like EMP pulses and runeless teleportation still have the effect due to their inherent loud nature."
- - balance: "The stun blood spell now instantly causes hard stamcrit. However, to offset this, it now also only has one charge and has a higher cost."
diff --git a/html/changelogs/AutoChangeLog-pr-7770.yml b/html/changelogs/AutoChangeLog-pr-7770.yml
deleted file mode 100644
index d949f17161..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7770.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "The Gloves of the North Star now restore 2/3 of the stamina used up by punches when harm intent punching. With aggressive play and good stamina buffer management, this makes it entirely plausible to roughly double your stamina regeneration per mob life process tick."
diff --git a/html/changelogs/AutoChangeLog-pr-7771.yml b/html/changelogs/AutoChangeLog-pr-7771.yml
deleted file mode 100644
index f537395993..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7771.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Revs can no longer remember the name of the person who flashed them when deconverted. This brings it in-line with the other conversion antag deconversions."
diff --git a/html/changelogs/AutoChangeLog-pr-7772.yml b/html/changelogs/AutoChangeLog-pr-7772.yml
deleted file mode 100644
index 5aa989cc93..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7772.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - tweak: "Adds a mixed clothing closet to Deltastation Dorms."
- - tweak: "Adds a bottle of unstable mutagen to Botany, on account of its distance from Chemistry."
diff --git a/html/changelogs/AutoChangeLog-pr-7776.yml b/html/changelogs/AutoChangeLog-pr-7776.yml
deleted file mode 100644
index 43660c000a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7776.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - bugfix: "Omegastation should no longer have any turf with missing textures, as those spots have been replaced with playing covered in a sandy turf decal."
diff --git a/html/changelogs/AutoChangeLog-pr-7778.yml b/html/changelogs/AutoChangeLog-pr-7778.yml
deleted file mode 100644
index 75362eca05..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7778.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The bug where you can sometimes get permanently stuck in stamcrit should HOPEFULLY be fixed. I'm unable to reproduce the bug myself, but let's hope."
diff --git a/html/changelogs/AutoChangeLog-pr-7779.yml b/html/changelogs/AutoChangeLog-pr-7779.yml
deleted file mode 100644
index 4202149f90..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7779.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "The night vision trait now grants you darksight for an entire 1:1 screen, but the alpha of the lighting plane with the trait has been increased from 245 to 250 to balance it out"
diff --git a/html/changelogs/AutoChangeLog-pr-7781.yml b/html/changelogs/AutoChangeLog-pr-7781.yml
deleted file mode 100644
index d6f2ca5907..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7781.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "It's now actually possible to click the stamina hud button"
- - bugfix: "The stamina hud button now displays your stamina buffer correctly"
diff --git a/html/changelogs/AutoChangeLog-pr-7782.yml b/html/changelogs/AutoChangeLog-pr-7782.yml
deleted file mode 100644
index 17986ac78f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7782.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Bone spears now have a reach of 2 tiles."
diff --git a/html/changelogs/AutoChangeLog-pr-7783.yml b/html/changelogs/AutoChangeLog-pr-7783.yml
deleted file mode 100644
index 489f7ba055..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7783.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "R3dtail"
-delete-after: True
-changes:
- - rscadd: "Added a new carpet. Red! Also added said carpet to the Premium Carpet crate from the cargo supply console. Trilby said she'd take care of the crafting recipe."
diff --git a/html/changelogs/AutoChangeLog-pr-7791.yml b/html/changelogs/AutoChangeLog-pr-7791.yml
deleted file mode 100644
index d2cde53ae0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7791.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "You can no longer phase through solid objects via scrambling"
diff --git a/html/changelogs/AutoChangeLog-pr-7860.yml b/html/changelogs/AutoChangeLog-pr-7860.yml
deleted file mode 100644
index 140f95aa40..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7860.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The syndicate mask now works properly as intended."
diff --git a/html/changelogs/AutoChangeLog-pr-7865.yml b/html/changelogs/AutoChangeLog-pr-7865.yml
deleted file mode 100644
index a75282b293..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7865.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Stamina is no longer affected by health at all."
diff --git a/html/changelogs/AutoChangeLog-pr-7866.yml b/html/changelogs/AutoChangeLog-pr-7866.yml
deleted file mode 100644
index 17435075e0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7866.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "You can now right-click yourself in help intent in combat mode to instantly get up from resting. This will cost stamina equal to your entire stamina buffer. Manage your stamina well, and you'll be able to shrug off a single stray golden bolt"
diff --git a/html/changelogs/AutoChangeLog-pr-7876.yml b/html/changelogs/AutoChangeLog-pr-7876.yml
deleted file mode 100644
index 649c0cc916..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7876.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "coiax"
-delete-after: True
-changes:
- - admin: "When the nuclear disk stays stationary long enough to trigger an increase for the lone op event chance, admins will be notified every five increments."
diff --git a/html/changelogs/AutoChangeLog-pr-7878.yml b/html/changelogs/AutoChangeLog-pr-7878.yml
deleted file mode 100644
index 6d10310d94..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7878.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - tweak: "Removed all living eggs from the xeno ruin because people self antag. Honk."
diff --git a/html/changelogs/AutoChangeLog-pr-7908.yml b/html/changelogs/AutoChangeLog-pr-7908.yml
deleted file mode 100644
index f6c1fda2ec..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7908.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "The new player panel now displays your currently selected character's name"
diff --git a/html/changelogs/AutoChangeLog-pr-7911.yml b/html/changelogs/AutoChangeLog-pr-7911.yml
deleted file mode 100644
index 0d0d468aa8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7911.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Flashes no longer knockdown. Instead, they deal eyeblur and have increased confusion"
diff --git a/html/changelogs/AutoChangeLog-pr-7912.yml b/html/changelogs/AutoChangeLog-pr-7912.yml
deleted file mode 100644
index 834ad80091..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7912.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - server: "The server's tagline is now a config option. People can now stop confusing us with BR cit"
diff --git a/html/changelogs/AutoChangeLog-pr-7914.yml b/html/changelogs/AutoChangeLog-pr-7914.yml
deleted file mode 100644
index aac983d7ea..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7914.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghom"
-delete-after: True
-changes:
- - code_imp: "minor clean up on hydroponics reagent containers."
diff --git a/html/changelogs/AutoChangeLog-pr-7916.yml b/html/changelogs/AutoChangeLog-pr-7916.yml
deleted file mode 100644
index 888f327f72..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7916.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Skoglol"
-delete-after: True
-changes:
- - rscadd: "You can now alt click storage (bags, boxes, etc) to open it."
diff --git a/html/changelogs/AutoChangeLog-pr-7918.yml b/html/changelogs/AutoChangeLog-pr-7918.yml
deleted file mode 100644
index b2340c2f67..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7918.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Attack animations will now rotate your character slightly, similar to Goon."
diff --git a/html/changelogs/AutoChangeLog-pr-7919.yml b/html/changelogs/AutoChangeLog-pr-7919.yml
deleted file mode 100644
index a62cc838c3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7919.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Throwing items will now perform the attack animation and play a sound"
diff --git a/html/changelogs/AutoChangeLog-pr-7920.yml b/html/changelogs/AutoChangeLog-pr-7920.yml
deleted file mode 100644
index 08b0ec1f13..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7920.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "flashlights will now make sounds when toggled on/off"
diff --git a/html/changelogs/AutoChangeLog-pr-7921.yml b/html/changelogs/AutoChangeLog-pr-7921.yml
deleted file mode 100644
index 66a245257f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7921.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Things in disposals will now emit sounds every single time they hit corners. This increases immersion."
diff --git a/html/changelogs/AutoChangeLog-pr-7922.yml b/html/changelogs/AutoChangeLog-pr-7922.yml
deleted file mode 100644
index 08f06d7053..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7922.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Air alarms now actually emit the proper light color when their status is okay."
diff --git a/html/changelogs/AutoChangeLog-pr-7923.yml b/html/changelogs/AutoChangeLog-pr-7923.yml
deleted file mode 100644
index 5cf6527dad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7923.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Backpacks and other storage items will now jiggle and squish when you interact with them, similar to the animations seen on Goon."
diff --git a/html/changelogs/AutoChangeLog-pr-7930.yml b/html/changelogs/AutoChangeLog-pr-7930.yml
deleted file mode 100644
index 221a2af942..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7930.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "nicc"
-delete-after: True
-changes:
- - balance: "teg less gay maybe"
diff --git a/html/changelogs/AutoChangeLog-pr-7945.yml b/html/changelogs/AutoChangeLog-pr-7945.yml
deleted file mode 100644
index edc2f96dc8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7945.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghom"
-delete-after: True
-changes:
- - bugfix: "fixes the perpetual lack of moisture that has affected genitalia descriptions since, like, forever."
- - rscadd: "implements the arousal state for mammary glands."
diff --git a/html/changelogs/AutoChangeLog-pr-7951.yml b/html/changelogs/AutoChangeLog-pr-7951.yml
deleted file mode 100644
index e05a5a1911..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7951.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes many possible situations of null icons for cit races' bodyparts."
- - imagedel: "Removes duplicate slimepeople' sprites."
- - code_imp: "Purges that draw_citadel_parts()."
diff --git a/html/changelogs/AutoChangeLog-pr-7954.yml b/html/changelogs/AutoChangeLog-pr-7954.yml
deleted file mode 100644
index 8a31b912ad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7954.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Mops no longer have a delay on their cleaning, making them an actually viable alternative to all of the janitor's other cleaning tools"
- - balance: "To balance this, mops now take stamina to clean tiles. Standard mops take 5 stamina to use, while advanced mops take 2 stamina."
- - tweak: "Oh and also mops make fancy new sounds and play animations when used now"
diff --git a/html/changelogs/AutoChangeLog-pr-7964.yml b/html/changelogs/AutoChangeLog-pr-7964.yml
deleted file mode 100644
index 33cfaa453d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7964.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "CydiaButt13"
-delete-after: True
-changes:
- - rscadd: "Lamp Plushie to loadout"
- - imageadd: "added plushie_lamp to plush icons"
- - code_imp: "added Lamp Plush to loadout and icons and items"
diff --git a/html/changelogs/AutoChangeLog-pr-7973.yml b/html/changelogs/AutoChangeLog-pr-7973.yml
deleted file mode 100644
index df9b9e2411..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7973.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Pump-action shotguns now take 2 stamina per pump instead of 5 stamina per pump. This also applies to bolt-action rifles, as bolt racking counts as pumping."
diff --git a/html/changelogs/AutoChangeLog-pr-7976.yml b/html/changelogs/AutoChangeLog-pr-7976.yml
deleted file mode 100644
index 4f334dc4ca..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7976.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - rscadd: "Adds a new security level between Blue and Red (Amber). The shuttle call time at this level is 8 minutes."
- - tweak: "Blue security level now has a shuttle call time of 12 minutes."
- - tweak: "The security level increase/decrease texts have been modified to accommodate the change."
- - imageadd: "Adds a code Amber sprite for the fire alarms"
diff --git a/html/changelogs/AutoChangeLog-pr-7977.yml b/html/changelogs/AutoChangeLog-pr-7977.yml
deleted file mode 100644
index ca43ddbbf0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7977.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Zargserg"
-delete-after: True
-changes:
- - balance: "Lungs maximum toxin threshold is 0.5% of the atmosphere."
- - bugfix: "Permanently contaminated atmosphere does not murder crew anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-7978.yml b/html/changelogs/AutoChangeLog-pr-7978.yml
deleted file mode 100644
index b35ea975c3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7978.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added the Yogs/Oracle ported latejoin menu"
diff --git a/html/changelogs/AutoChangeLog-pr-7979.yml b/html/changelogs/AutoChangeLog-pr-7979.yml
deleted file mode 100644
index ed06d73ac1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7979.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Anonymous"
-delete-after: True
-changes:
- - imageadd: "More crusader armor variants to pick from armament: Teutonic and Hospitaller."
diff --git a/html/changelogs/AutoChangeLog-pr-7980.yml b/html/changelogs/AutoChangeLog-pr-7980.yml
deleted file mode 100644
index a0b3b09fb5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7980.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "MediHound"
-delete-after: True
-changes:
- - rscadd: "Made Cyborgs be affected by Ion Storm Law Changes like AIs"
diff --git a/html/changelogs/AutoChangeLog-pr-7981.yml b/html/changelogs/AutoChangeLog-pr-7981.yml
deleted file mode 100644
index e36dd711fa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7981.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - tweak: "Removed the plushes from the toy crate, giving them their own."
- - tweak: "Plushes are now less likely to spawn out of arcades"
diff --git a/html/changelogs/AutoChangeLog-pr-7982.yml b/html/changelogs/AutoChangeLog-pr-7982.yml
deleted file mode 100644
index 7255219c9e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7982.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Coolgat3 / Avunia"
-delete-after: True
-changes:
- - rscadd: "Made kindle put the target into stamcrit, which makes it an actually working, useful stun."
- - rscadd: "Added a stamina loss modifier to the vanguard spell which makes the user's stamina drain at a way slower rate. This doesn't make them immune to tasers, but it takes a few hits to actually get them to fall down."
- - tweak: "Made it so that clock culties don't start with a chameleon suit. Instead they start with an engineer suit which is pretty much the same sprite and looks. If this is not perfect, then I am willing to make a slightly more brass-colored version of the engineer suit sprite and call it a ratvarian engineer jumpsuit."
- - balance: "Increased the cost of vanguard, as it is now a spell that works somewhat like adrenals, minus the move speed, making your stamina drain really slow and making you unable to get knocked onto the ground by just a single taser shot."
- - balance: "Lowered the charge time of kindle, reason being that you can usually have only one active spell on you, or two at max if you decide to run two slabs, but the fact that kindle silences people for such a small amount of time makes up for it, in my opinion."
- - server: "Figured out that the consoles and their warp function actually work with the current code. The thing that makes them not work is when the gamemode is ran on debug mode, without the required players to actually support it. It also breaks the ark timer which is stuck on -1 seconds until activation. Whenever the gamemode starts properly, like any other gamemode, with player checks and all, everything seems to work just fine."
diff --git a/html/changelogs/AutoChangeLog-pr-7983.yml b/html/changelogs/AutoChangeLog-pr-7983.yml
deleted file mode 100644
index 46e0a14f96..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7983.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - code_imp: "Fixes ISINRANGE_EX using the wrong relational operator."
diff --git a/html/changelogs/AutoChangeLog-pr-7987.yml b/html/changelogs/AutoChangeLog-pr-7987.yml
deleted file mode 100644
index e525b1668e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7987.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "All markings, tails, ears, and snouts for Citadel races are color matrixed!"
- - imageadd: "all markings are on a per-limb basis, including Digitigrade legs!"
- - imageadd: "a bunch of tails were blessed with tail wagging sprites, Fish, Sharks, Fennecs, Wahs, raccoons, and others."
- - imageadd: "Tiger markings + tail added, skunk tails improved via sprites from Virgo"
- - tweak: "tweaked some sprites to look better, but they absolutely could use a few extra passes for quality"
- - rscadd: "HumanScissors in the Tools folder will permit anyone to contribute matrix'd markings to the sprite sheet, however Mam_markings is very, very full. Be careful."
- - tweak: "Character preview was both optimized for taurs and bad-touched for better updating. I don't know if it'll be bad, but hey its better."
diff --git a/html/changelogs/AutoChangeLog-pr-7990.yml b/html/changelogs/AutoChangeLog-pr-7990.yml
deleted file mode 100644
index b05eca84d2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7990.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Coolgat3"
-delete-after: True
-changes:
- - tweak: "Changed player number checks to 20 from 24 for cult and clockcult, also made nukeops 28 required players instead of 30."
- - tweak: "Changed enemy minimum age from 14 to 7"
diff --git a/html/changelogs/AutoChangeLog-pr-7993.yml b/html/changelogs/AutoChangeLog-pr-7993.yml
deleted file mode 100644
index f1e0db178f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7993.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Improving and Balancing Cyborgs"
-delete-after: True
-changes:
- - rscadd: "Added Crew Pinpointer to Security Borg"
- - rscadd: "Added Crew Monitor to Medical Borg"
- - rscadd: "Added Crew Pinpointer to MediHound Borg"
- - tweak: "Made the Disabler_Cooler compatible with both Security Borg and K9 Borg"
- - tweak: "Changed the Warning Text upon selecting Security or K9 module"
diff --git a/html/changelogs/AutoChangeLog-pr-7994.yml b/html/changelogs/AutoChangeLog-pr-7994.yml
deleted file mode 100644
index 703dcf31e1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7994.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Pickpocketing items will now place them in your hands if possible"
diff --git a/html/changelogs/AutoChangeLog-pr-7995.yml b/html/changelogs/AutoChangeLog-pr-7995.yml
deleted file mode 100644
index 9d118ebbff..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7995.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Combat mode is now displayed in examine text"
- - rscadd: "Combat mode now makes a visible message when enabled if you haven't touched your combat mode button in the last ten seconds. It's done this way to avoid chat spam from those who know how to pull off stam regen squeezing."
diff --git a/html/changelogs/AutoChangeLog-pr-7996.yml b/html/changelogs/AutoChangeLog-pr-7996.yml
deleted file mode 100644
index 518feae251..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7996.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "All knockdown sources will now force people to be dismounted from ridden vehicles."
diff --git a/html/changelogs/AutoChangeLog-pr-7997.yml b/html/changelogs/AutoChangeLog-pr-7997.yml
deleted file mode 100644
index 7b3db7fb44..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7997.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "When an item is thrown, it will now be rotated and displaced."
- - rscadd: "Shards of glass will now be rotated when spawned."
- - rscadd: "Bullet casings will now be rotated when they're ejected from a gun."
- - rscadd: "Bottles now have random rotations and pixel offsets when smashed via throwing."
- - rscadd: "Picking up an item will now reset its rotation."
- - rscadd: "Glasses thrown onto tables by bartenders will now have their rotation reset."
diff --git a/html/changelogs/AutoChangeLog-pr-7999.yml b/html/changelogs/AutoChangeLog-pr-7999.yml
deleted file mode 100644
index 516f304f98..0000000000
--- a/html/changelogs/AutoChangeLog-pr-7999.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "The kindle status effect stun duration now properly proportional to the owner's remaining health."
- - tweak: "Clockwork cult's kindle now affects silicons."
diff --git a/html/changelogs/AutoChangeLog-pr-8008.yml b/html/changelogs/AutoChangeLog-pr-8008.yml
deleted file mode 100644
index 5845bd1b87..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8008.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Slime speed potions can now only increase the speed of vehicles to be on par with sprinting speed. They can no longer make a scooter roll around ten times faster than a speeding blue hedgehog."
diff --git a/html/changelogs/AutoChangeLog-pr-8010.yml b/html/changelogs/AutoChangeLog-pr-8010.yml
deleted file mode 100644
index 9694674b7c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8010.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscdel: "Changelings will no longer recieve team objectives"
diff --git a/html/changelogs/AutoChangeLog-pr-8011.yml b/html/changelogs/AutoChangeLog-pr-8011.yml
deleted file mode 100644
index 9d0db00db4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8011.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Changelings no longer start off with hivemind communication as an innate ability. Hivemind communication now requires 1 dna point, on par with syndicate encryption keys, which are 2 TC."
- - code_imp: "Hivemind link now relies on hivemind communication just like the hivemind download/upload abilities."
diff --git a/html/changelogs/AutoChangeLog-pr-8012.yml b/html/changelogs/AutoChangeLog-pr-8012.yml
deleted file mode 100644
index 212f252a7d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8012.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "It's now only possible to zoom a gun if it's in one of your hands"
diff --git a/html/changelogs/AutoChangeLog-pr-8021.yml b/html/changelogs/AutoChangeLog-pr-8021.yml
deleted file mode 100644
index fca715cd3d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8021.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Mobs without clients no longer cause runtimes when their eyeblur updates"
diff --git a/html/changelogs/AutoChangeLog-pr-8023.yml b/html/changelogs/AutoChangeLog-pr-8023.yml
deleted file mode 100644
index 1b30435bda..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8023.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Blood tests have been added. If a changeling has a sufficient number of loud abilities, you will be able to test their blood by heating up a sample of it. However, if the changeling has a large amount of loud abilities, attempts to test their blood will have explosive results."
- - rscadd: "Changelings now make a very obvious noise when readapting. This is to prevent the cheese strat of simply readapting when you get caught to avoid detection."
diff --git a/html/changelogs/AutoChangeLog-pr-8024.yml b/html/changelogs/AutoChangeLog-pr-8024.yml
deleted file mode 100644
index 1aa5f1b09f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8024.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "The blood splatter effect that happens when you get attacked will now always make you lose blood depending on the damage you've taken. The effect now also scales with item damage, meaning tiny little papercuts will no longer be able to cause a massive blood splatter."
- - rscadd: "The blood reagent will now cover items and spacemen in blood when applied to objects and mobs."
- - tweak: "Helmets, masks, and neck items are all now valid targets to get splattered when you get covered in blood. Groovy."
diff --git a/html/changelogs/AutoChangeLog-pr-8025.yml b/html/changelogs/AutoChangeLog-pr-8025.yml
deleted file mode 100644
index ee60aab630..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8025.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "The temperature notification will now take into consideration both the ambient temperature and your body temperature, increasing the responsiveness of the temperature notification and making it much more realistic."
diff --git a/html/changelogs/AutoChangeLog-pr-8030.yml b/html/changelogs/AutoChangeLog-pr-8030.yml
deleted file mode 100644
index c82325b394..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8030.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Multicam Config"
-delete-after: True
-changes:
- - config: "removed whether or not the stuff for multicam was checking the useless var and instead now checks the CONFIG_GET flag."
- - admin: "Admins now have a verb in the Server tab to turn AI multicam on and off."
diff --git a/html/changelogs/AutoChangeLog-pr-8031.yml b/html/changelogs/AutoChangeLog-pr-8031.yml
deleted file mode 100644
index 16ce735811..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8031.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Shuttle transit borders are now 10 tiles wide instead of 8 tiles, hopefully repairing the immersions that get shattered by the ability to see normal space where the transit areas end."
diff --git a/html/changelogs/AutoChangeLog-pr-8032.yml b/html/changelogs/AutoChangeLog-pr-8032.yml
deleted file mode 100644
index 87a65ac9d7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8032.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Instead of transit turfs simply teleporting things to space, transit is now handled in a somewhat realistic manner. Transit turfs now act like normal space turfs, though exiting the transit area or being present in the transit area after the shuttle moves out of transit will teleport you to space and throw you in the direction the shuttle was moving in."
- - tweak: "Reservation areas are now able to designate a border turf."
diff --git a/html/changelogs/AutoChangeLog-pr-8033.yml b/html/changelogs/AutoChangeLog-pr-8033.yml
deleted file mode 100644
index e4a77766f1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8033.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The sprint hotkey will no longer cause you to get permanently stuck sprinting if the server lags. Just tap shift again if you get stuck"
diff --git a/html/changelogs/AutoChangeLog-pr-8034.yml b/html/changelogs/AutoChangeLog-pr-8034.yml
deleted file mode 100644
index c9fabf1874..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8034.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "You can now hear sounds in the real world while inside of a VR sleeper."
diff --git a/html/changelogs/AutoChangeLog-pr-8035.yml b/html/changelogs/AutoChangeLog-pr-8035.yml
deleted file mode 100644
index 82d1a18a1b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8035.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "You can now make nameless characters. Nameless characters will spawn in with their name set as their job title followed by a unique five digit number. The \"Name\" option in the character setup menu will be replaced with a \"Default designation\" option for nameless characters, and the default designation will be used in place of a job title for assistants and other jobs that don't require dress codes."
diff --git a/html/changelogs/AutoChangeLog-pr-8037.yml b/html/changelogs/AutoChangeLog-pr-8037.yml
deleted file mode 100644
index 340b8e006e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8037.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "Cyborg mounted disablers/tasers/lasers now slowly self-recharge off the cyborg user's power cell instead of draining from it directly."
- - tweak: "Borg rechargers now properly recharge the borg module's energy guns."
- - bugfix: "Prevents a couple more special/mounted guns from being preserved on cryo"
diff --git a/html/changelogs/AutoChangeLog-pr-8038.yml b/html/changelogs/AutoChangeLog-pr-8038.yml
deleted file mode 100644
index 64fbb5c4b2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8038.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - admin: "The out-of-game round end notification is now a little more verbose. It'll now display the round type, end result of the round, and the survival rate."
diff --git a/html/changelogs/AutoChangeLog-pr-8039.yml b/html/changelogs/AutoChangeLog-pr-8039.yml
deleted file mode 100644
index 4445a86991..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8039.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Xenos can no longer strip items off of people to be capable of using any item in the game."
- - bugfix: "also, items from pockets get placed into your hands properly now"
diff --git a/html/changelogs/AutoChangeLog-pr-8041.yml b/html/changelogs/AutoChangeLog-pr-8041.yml
deleted file mode 100644
index 477b513368..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8041.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "A mob's last words are now properly tracked and recorded on death. The first death of the round will now actually display the victim's last words on the round end screen."
diff --git a/html/changelogs/AutoChangeLog-pr-8042.yml b/html/changelogs/AutoChangeLog-pr-8042.yml
deleted file mode 100644
index 4df2d178df..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8042.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "izzyinbox"
-delete-after: True
-changes:
- - rscadd: "Generic dog body marking sprite"
- - imageadd: "colormatrix dog sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-8043.yml b/html/changelogs/AutoChangeLog-pr-8043.yml
deleted file mode 100644
index b3beb4c4cb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8043.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Coolgat3"
-delete-after: True
-changes:
- - rscadd: "Added the code for the semen donut and made it craftable"
- - imageadd: "Added the donut sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-8044.yml b/html/changelogs/AutoChangeLog-pr-8044.yml
deleted file mode 100644
index e4fe14ac84..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8044.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Divine shenanigans can no longer result in someone becoming immune to staminaloss"
diff --git a/html/changelogs/AutoChangeLog-pr-8047.yml b/html/changelogs/AutoChangeLog-pr-8047.yml
deleted file mode 100644
index 6a11895b0f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8047.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Fixed body_markings in bodyparts being assigned as a list when in reality, it's a string and literally everything expects it to be a string and uses it as a string. This should mean that markings no longer have completely fucked up caches for character preview and other things."
diff --git a/html/changelogs/AutoChangeLog-pr-8051.yml b/html/changelogs/AutoChangeLog-pr-8051.yml
deleted file mode 100644
index 51c2d438ab..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8051.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Since apparently the game is literally unplayable if items are not in the exact center of a turf, the maximum pixel variance of thrown objects has been reduced by four pixels to make things a smidge more clearer for those that dont know what a turf is."
- - bugfix: "Bartender glasses should HOPEFULLY no longer be tilted when landing on a table. Why the fuck is after_throw called via a timer."
diff --git a/html/changelogs/AutoChangeLog-pr-8052.yml b/html/changelogs/AutoChangeLog-pr-8052.yml
deleted file mode 100644
index 4ad9af8ef0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8052.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Changeling screeches now have their own unique sounds, and are much easier to recognize."
diff --git a/html/changelogs/AutoChangeLog-pr-8053.yml b/html/changelogs/AutoChangeLog-pr-8053.yml
deleted file mode 100644
index 706166a9d1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8053.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Most synthetic emotes are now available to humans. *ping"
diff --git a/html/changelogs/AutoChangeLog-pr-8054.yml b/html/changelogs/AutoChangeLog-pr-8054.yml
deleted file mode 100644
index a674371a3a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8054.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "You can now merp"
diff --git a/html/changelogs/AutoChangeLog-pr-8055.yml b/html/changelogs/AutoChangeLog-pr-8055.yml
deleted file mode 100644
index e06f03e1ef..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8055.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added Dark Medihound and Pup Dozer from Virgo"
diff --git a/html/changelogs/AutoChangeLog-pr-8056.yml b/html/changelogs/AutoChangeLog-pr-8056.yml
deleted file mode 100644
index 0953743ae4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8056.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "The TEG will now only produce a meaningful amount of power if the hot pipe contains gas that's actively combusting"
diff --git a/html/changelogs/AutoChangeLog-pr-8057.yml b/html/changelogs/AutoChangeLog-pr-8057.yml
deleted file mode 100644
index adb48e0ee0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8057.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - admin: "Added the \"add PB bypass\" and \"revoke PB bypass\" verbs, which allow admins to let a specific ckey to bypass the panic bunker for the rest of the round"
diff --git a/html/changelogs/AutoChangeLog-pr-8058.yml b/html/changelogs/AutoChangeLog-pr-8058.yml
deleted file mode 100644
index a484cc8ce1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8058.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Jogging is no longer treated exactly the same as sprinting for water slips. When you're jogging, you will only slip on water if you have more than 20% staminaloss."
diff --git a/html/changelogs/AutoChangeLog-pr-8062.yml b/html/changelogs/AutoChangeLog-pr-8062.yml
deleted file mode 100644
index 2f1bc9b312..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8062.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "The atmospherics turf subsystem now has double the wait time, which should free up server processing power for other tasks."
diff --git a/html/changelogs/AutoChangeLog-pr-8064.yml b/html/changelogs/AutoChangeLog-pr-8064.yml
deleted file mode 100644
index 512095f583..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8064.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The IRC now actually displays the actual survival rate"
diff --git a/html/changelogs/AutoChangeLog-pr-8070.yml b/html/changelogs/AutoChangeLog-pr-8070.yml
deleted file mode 100644
index a2ebab9068..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8070.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Bloodcult conversions are now consensual. Convertees are given a ten second timer to accept or wait out. This should drastically improve the quality of those that get converted into bloodcult."
- - rscadd: "All sacrifices now count as a third of a cultist for the end-game narsie summon."
diff --git a/html/changelogs/AutoChangeLog-pr-8071.yml b/html/changelogs/AutoChangeLog-pr-8071.yml
deleted file mode 100644
index 040aa8b2cc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8071.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Nameless captains will no longer proc a \"Captain Captain on deck!\" message. Instead, it'll be a much more boring but much more sensical \"Captain on deck!\" message."
diff --git a/html/changelogs/AutoChangeLog-pr-8080.yml b/html/changelogs/AutoChangeLog-pr-8080.yml
deleted file mode 100644
index 9abd9e6f50..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8080.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "Halved borg energy guns self-recharge delay and increased their cell capacity by 3/4"
diff --git a/html/changelogs/AutoChangeLog-pr-8084.yml b/html/changelogs/AutoChangeLog-pr-8084.yml
deleted file mode 100644
index fbec9cfe1f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8084.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - tweak: "Clone pods no longer announce the name of the clone"
diff --git a/html/changelogs/AutoChangeLog-pr-8090.yml b/html/changelogs/AutoChangeLog-pr-8090.yml
deleted file mode 100644
index b314fde12b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8090.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58 (Original PR by actioninja)"
-delete-after: True
-changes:
- - rscadd: "Disarm pushing (combat mode right click in disarm intent) will now actually push mobs away. Knockdowns from disarm pushing are no longer rng based on the target's staminaloss. Knockdowns from disarm pushing now only happen when you push someone into another mob, a table, or a wall. Pushes will now also temporarily stop targets from using firearms, and will disarm the firearm if performed a second time. Pushes still deal staminaloss to standing targets, and won't deal a single ounce of staminaloss to resting targets."
- - rscdel: "You can no longer displace mobs that are in harm intent by simply walking into them. Mobs that aren't in help intent have to be disarm pushed to actually be moved."
diff --git a/html/changelogs/AutoChangeLog-pr-8091.yml b/html/changelogs/AutoChangeLog-pr-8091.yml
deleted file mode 100644
index e98b7df89c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8091.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Transit turfs on the centcom z-level now function properly again at keeping mobs within the areas defined by their boundaries."
- - bugfix: "The title screen is also positioned correctly again."
diff --git a/html/changelogs/AutoChangeLog-pr-8098.yml b/html/changelogs/AutoChangeLog-pr-8098.yml
deleted file mode 100644
index 956b83d223..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8098.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Coolgat3"
-delete-after: True
-changes:
- - bugfix: "Made the sec and warden berret offer as much protection like the helmet"
diff --git a/html/changelogs/AutoChangeLog-pr-8104.yml b/html/changelogs/AutoChangeLog-pr-8104.yml
deleted file mode 100644
index 61bf66a0c2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8104.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes chemical patches always checking the suit slot even if the targetted limb was the head."
- - bugfix: "Skeleton, nightmare and golem races are once again available to get chemical patches applied onto."
diff --git a/html/changelogs/AutoChangeLog-pr-8108.yml b/html/changelogs/AutoChangeLog-pr-8108.yml
deleted file mode 100644
index fea83213be..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8108.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Adds two cartons of space milk to the space skellie pirates cutter's fridge."
diff --git a/html/changelogs/AutoChangeLog-pr-8114.yml b/html/changelogs/AutoChangeLog-pr-8114.yml
deleted file mode 100644
index 96e6914e6b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8114.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "izzyinbox"
-delete-after: True
-changes:
- - tweak: "lowered the player age for command jobs to 1/3 of their previous setting"
diff --git a/html/changelogs/AutoChangeLog-pr-8118.yml b/html/changelogs/AutoChangeLog-pr-8118.yml
deleted file mode 100644
index be5c0871ab..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8118.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Ghost role eligibility for both event and spawner ghost roles is now affected by DNR status. If you suicide, ghost, or cryo out, you will be unable to qualify for any ghost roles"
- - tweak: "Cryo now applies DNR status no matter how long the round has been going on"
- - tweak: "Suicide is now properly admin logged as it is supposed to be. Ghosting while alive is now also logged."
diff --git a/html/changelogs/AutoChangeLog-pr-8119.yml b/html/changelogs/AutoChangeLog-pr-8119.yml
deleted file mode 100644
index 6e282e2a8d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8119.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Sparks and igniters will now actually heat areas rather than cooling them, as was intended."
- - tweak: "To alleviate some potential complaints, RPDs now have a cooldown before they can create sparks, and both RPDs and emitters produce less sparks."
diff --git a/html/changelogs/AutoChangeLog-pr-8121.yml b/html/changelogs/AutoChangeLog-pr-8121.yml
deleted file mode 100644
index 27ce1ee0a1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8121.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Conversion runes will now mute the victim temporarily while they're deciding whether to convert or be sacrificed."
- - bugfix: "Conversion runes no longer require a third cultist to sacrifice if the victim refuses conversion"
diff --git a/html/changelogs/AutoChangeLog-pr-8122.yml b/html/changelogs/AutoChangeLog-pr-8122.yml
deleted file mode 100644
index 2b9d091601..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8122.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Staminaloss targeted at the head now properly redirects to the chest."
diff --git a/html/changelogs/AutoChangeLog-pr-8123.yml b/html/changelogs/AutoChangeLog-pr-8123.yml
deleted file mode 100644
index 56b2f82ad6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8123.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Sprinting no longer takes stam when you're being pulled or when you're in zero gravity. Other sources of involuntary movement are not affected."
diff --git a/html/changelogs/AutoChangeLog-pr-8130.yml b/html/changelogs/AutoChangeLog-pr-8130.yml
deleted file mode 100644
index ac1dd56028..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8130.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed flavor text appearing when your face is hidden but you're not an Unknown"
diff --git a/html/changelogs/AutoChangeLog-pr-8132.yml b/html/changelogs/AutoChangeLog-pr-8132.yml
deleted file mode 100644
index 05e27044be..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8132.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Tauric suits now apply an (placeholder) blood overlay, as well as their shield overlay."
diff --git a/html/changelogs/AutoChangeLog-pr-8140.yml b/html/changelogs/AutoChangeLog-pr-8140.yml
deleted file mode 100644
index ae21917771..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8140.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - code_imp: "In an attempt to improve performance during highpop, mouse movements will now only call onmousemove() while a user is in combat mode"
diff --git a/html/changelogs/AutoChangeLog-pr-8141.yml b/html/changelogs/AutoChangeLog-pr-8141.yml
deleted file mode 100644
index 2a465b21e5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8141.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Ballistic projectiles are now the only projectiles capable of emitting dinks."
diff --git a/html/changelogs/AutoChangeLog-pr-8145.yml b/html/changelogs/AutoChangeLog-pr-8145.yml
deleted file mode 100644
index 55cd6c378b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8145.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - admin: "Panic bunker toggling and bypassing is now logged in admin IRC"
diff --git a/html/changelogs/AutoChangeLog-pr-8146.yml b/html/changelogs/AutoChangeLog-pr-8146.yml
deleted file mode 100644
index 566532fdd3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8146.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "OOC and LOOC now use separate toggles. You can now use LOOC while OOC is globally toggled off, and admins now have the option to toggle LOOC off separately from OOC"
- - code_imp: "also revamped and reorganized relevant looc adminverb code"
diff --git a/html/changelogs/AutoChangeLog-pr-8159.yml b/html/changelogs/AutoChangeLog-pr-8159.yml
deleted file mode 100644
index da0f13e28a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8159.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - balance: "Ashwalkers now have lungs. They cannot breath station air without suffocation effects, but are completely fine on their homeworld."
- - balance: "Carbon mobs now have a maximum tolerance to oxygen of 50kPa."
- - balance: "Deluxe synthetic lungs have a very high bonus to O2 tolerance."
diff --git a/html/changelogs/AutoChangeLog-pr-8160.yml b/html/changelogs/AutoChangeLog-pr-8160.yml
deleted file mode 100644
index 33d2445f48..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8160.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Digitigrade legs returned to normal, since digi leg markings overlay them anyway."
- - bugfix: "commented out lizard mam_snout entries, because too many abominations"
diff --git a/html/changelogs/AutoChangeLog-pr-8164.yml b/html/changelogs/AutoChangeLog-pr-8164.yml
deleted file mode 100644
index 5d00b5b9ba..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8164.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Vore Panel restored to have various interactions available again. Semi-untested but should work as advertised."
- - tweak: "Vore Panel has more feedback."
- - rscadd: "is_wet var to bellies, toggled in the panel, will remove flesh sounding struggles and the internal loop. JSON version updated."
- - rscadd: "Feeding var. You will need to enable feeding to recieve any feed vore actions, but you can now feed yourself to mobs that have this set. TODO, Dogborg sleeper feeding."
- - rscadd: "vore mode button now required to be enabled to perform vore actions. It's the mouth icon!"
- - bugfix: "Ash Drake vore fixed for actual reals this time"
- - bugfix: "Mobs shouldn't spam the released contents announcement anymore on qdel or death. Only if triggered"
- - tweak: "Hostile mob code now properly ignores targets in bellies"
- - rscadd: "Your belly can quietly growl if you're starving now."
diff --git a/html/changelogs/AutoChangeLog-pr-8167.yml b/html/changelogs/AutoChangeLog-pr-8167.yml
deleted file mode 100644
index 105e5c34b8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8167.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "The endgame narsie summon rune no longer requires 24 total sacrifices, and will now properly account for cultists that surround it"
diff --git a/html/changelogs/AutoChangeLog-pr-8169.yml b/html/changelogs/AutoChangeLog-pr-8169.yml
deleted file mode 100644
index 5c50eac652..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8169.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Normal blood splattering isn't offset due to tauric mode"
diff --git a/html/changelogs/AutoChangeLog-pr-8172.yml b/html/changelogs/AutoChangeLog-pr-8172.yml
deleted file mode 100644
index 87c4b5baf7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8172.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "The succumb verb is now available in the IC tab"
diff --git a/html/changelogs/AutoChangeLog-pr-8175.yml b/html/changelogs/AutoChangeLog-pr-8175.yml
deleted file mode 100644
index 00e8ea4ee3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8175.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Lighting now uses a linear algorithm to calculate falloff instead of an inverse-square algorithm."
diff --git a/html/changelogs/AutoChangeLog-pr-8182.yml b/html/changelogs/AutoChangeLog-pr-8182.yml
deleted file mode 100644
index 8247409f1b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8182.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - code_imp: "get_hearers_in_view() now actually caches the results of view() instead of calling view() twice"
diff --git a/html/changelogs/AutoChangeLog-pr-8183.yml b/html/changelogs/AutoChangeLog-pr-8183.yml
deleted file mode 100644
index 01b3cd4b2b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8183.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "bluespace bio bags"
-delete-after: True
-changes:
- - rscadd: "Added bluespace bio bags and put it in the tech web, in the node applied bluespace"
- - imageadd: "added a crappy icon for bluespace bio bags"
diff --git a/html/changelogs/AutoChangeLog-pr-8184.yml b/html/changelogs/AutoChangeLog-pr-8184.yml
deleted file mode 100644
index 6a55b6468b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8184.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - code_imp: "Goonchat's JS no longer contains checks related to a completely unused message filtering function, which should improve clientside performance quite a bit"
diff --git a/html/changelogs/AutoChangeLog-pr-8185.yml b/html/changelogs/AutoChangeLog-pr-8185.yml
deleted file mode 100644
index eec6e7c3b2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8185.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "The storage hud now properly takes into account the viewer's view size, meaning storage items with a large amount of storage slots will properly stretch across the bottom of the screen when running in widescreen."
diff --git a/html/changelogs/AutoChangeLog-pr-8189.yml b/html/changelogs/AutoChangeLog-pr-8189.yml
deleted file mode 100644
index 2a2fb9cbbf..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8189.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Action buttons are now able to fill the entire screen in widescreen and other weird view sizes."
diff --git a/html/changelogs/AutoChangeLog-pr-8190.yml b/html/changelogs/AutoChangeLog-pr-8190.yml
deleted file mode 100644
index d2b05015e4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8190.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscdel: "Omegastation's job changes will no longer be included at compile time."
diff --git a/html/changelogs/AutoChangeLog-pr-8192.yml b/html/changelogs/AutoChangeLog-pr-8192.yml
deleted file mode 100644
index 28d8f00814..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8192.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - code_imp: "The client update portion of /mob/Login() now double-checks to make sure client.player_details exists and is of the proper type. This should hopefully fix the \"cannot read null.player_details\" runtimes that can spontaneously cause clients to get kicked out and forced back to the lobby."
diff --git a/html/changelogs/AutoChangeLog-pr-8194.yml b/html/changelogs/AutoChangeLog-pr-8194.yml
deleted file mode 100644
index d7a8b0b540..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8194.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Hippie Circuit Port"
-delete-after: True
-changes:
- - rscadd: "Added all Atmospheric Circuits"
- - rscadd: "Added the ability to color data disks"
- - rscadd: "Added Selection and Storage Examiner Circuits"
- - rscadd: "Added Smoke, Extinguisher, and Beaker Connector Circuits"
- - rscadd: "Added Inserter, Renamer, Redescriber, and Repaint Circuits"
- - rscadd: "Added MMI Tank and pAI Connector Circuits (The possibilities are endless!)"
diff --git a/html/changelogs/AutoChangeLog-pr-8195.yml b/html/changelogs/AutoChangeLog-pr-8195.yml
deleted file mode 100644
index b9e9346c95..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8195.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "You can now quickly use unequipped items on objects by simply click-dragging the item onto the object with an empty active hand. Doing so will place the item in your hand, and then use that item on the object."
diff --git a/html/changelogs/AutoChangeLog-pr-8196.yml b/html/changelogs/AutoChangeLog-pr-8196.yml
deleted file mode 100644
index 631ccb6728..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8196.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - code_imp: "In an attempt to improve the performance of /mob/Stat(), various time-related procs now use defines instead of being procs that call procs that call other procs that call even more procs."
diff --git a/html/changelogs/AutoChangeLog-pr-8197.yml b/html/changelogs/AutoChangeLog-pr-8197.yml
deleted file mode 100644
index cdd2b4e877..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8197.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Naksu"
-delete-after: True
-changes:
- - code_imp: "squeezed a little bit more perf out of atmos"
diff --git a/html/changelogs/AutoChangeLog-pr-8198.yml b/html/changelogs/AutoChangeLog-pr-8198.yml
deleted file mode 100644
index 46caa5da07..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8198.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added plasma man suit icons for taurs"
- - rscadd: "Added bee butt for insects to have stripes"
- - tweak: "adjusted random spawn sprite accessories, humans won't be demi by default and lizard/mammal spawns will randomly get digitigrade legs"
- - bugfix: "sprite adjustments for tentacles, as well as a misspelling."
- - bugfix: "Humans once again use ears and tail_human, as intended. This is to prevent garish randomness"
- - bugfix: "istype for species is actually correct and usable now, it'll be a factor for monkey form expansions."
- - bugfix: "Hair functions are de-gendered and more easily selectable now."
- - bugfix: "Slimes can *wag, select markings and snouts, and yes it works."
- - bugfix: "Slimepeople extra parts now respect their hair_alpha in terms of being somewhat see-through. it shouldn't stand out as badly now!"
diff --git a/html/changelogs/AutoChangeLog-pr-8199.yml b/html/changelogs/AutoChangeLog-pr-8199.yml
deleted file mode 100644
index d3bf5a07e5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8199.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Hunger noises are now toggled per character"
diff --git a/html/changelogs/AutoChangeLog-pr-8200.yml b/html/changelogs/AutoChangeLog-pr-8200.yml
deleted file mode 100644
index db6787ff02..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8200.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Ashwalker den is habitable by ashwalkers again"
diff --git a/html/changelogs/AutoChangeLog-pr-8207.yml b/html/changelogs/AutoChangeLog-pr-8207.yml
deleted file mode 100644
index 22b31a834c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8207.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "If a living mob has vore initialized but doesnt have voreprefs initialized, then client login will force voreprefs to load."
diff --git a/html/changelogs/AutoChangeLog-pr-8211.yml b/html/changelogs/AutoChangeLog-pr-8211.yml
deleted file mode 100644
index bdfcdbf007..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8211.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Medical belts now have overlays! Now you can see if a belt is useful or just flatout empty."
- - bugfix: "fixed hypo MK IIs not being able to be put on medical belts"
diff --git a/html/changelogs/AutoChangeLog-pr-8214.yml b/html/changelogs/AutoChangeLog-pr-8214.yml
deleted file mode 100644
index 96f835d2f5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8214.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed Navy officer uniforms that failed to spawn"
- - code_imp: "Loadout items will be forcefully added to backpacks or at your feet instead of left behind at title screen"
diff --git a/html/changelogs/AutoChangeLog-pr-8219.yml b/html/changelogs/AutoChangeLog-pr-8219.yml
deleted file mode 100644
index b0d77cdec0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8219.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Coolgat3"
-delete-after: True
-changes:
- - rscadd: "Added berets for all the heads."
- - imageadd: "Added sprites for the berets."
- - code_imp: "Coded the berets to spawn in appropiate lockers."
diff --git a/html/changelogs/AutoChangeLog-pr-8228.yml b/html/changelogs/AutoChangeLog-pr-8228.yml
deleted file mode 100644
index bcfae35a3c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8228.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Coolgat3"
-delete-after: True
-changes:
- - tweak: "Raised the ripley's movement speed and lights range by 1, also lowered its armor to compensate."
diff --git a/html/changelogs/AutoChangeLog-pr-8229.yml b/html/changelogs/AutoChangeLog-pr-8229.yml
deleted file mode 100644
index c22f1dab3d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8229.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Hopefully fixed paper crash 2: electric boogaloo"
diff --git a/html/changelogs/AutoChangeLog-pr-8231.yml b/html/changelogs/AutoChangeLog-pr-8231.yml
deleted file mode 100644
index f71ec3fd52..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8231.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - tweak: "hypospray kits hold 12 now, but only vials and sprays themselves"
- - bugfix: "labcoats can carry MK II hyposprays on them now."
diff --git a/html/changelogs/AutoChangeLog-pr-8232.yml b/html/changelogs/AutoChangeLog-pr-8232.yml
deleted file mode 100644
index 00d319dfe5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8232.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Vore Mobs are a thing now, not just ash drakes"
- - rscdel: "Removed hunger sound stuff. never taking requests from Coolgat3 ever again.
-refractor: Simple Mobs use the same system regular human mobs do, itjustworks.png"
diff --git a/html/changelogs/AutoChangeLog-pr-8233.yml b/html/changelogs/AutoChangeLog-pr-8233.yml
deleted file mode 100644
index d9d827df4b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8233.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - tweak: "Character Window settings unsnowflaked and normalized. I have no fucking clue how to make them work with taurs still tho, sorry."
- - imageadd: "added rotating background images for better clarity and contrast than just SOLID FUCKING BLACK. Images from Virgo/Polaris/Eris"
diff --git a/html/changelogs/AutoChangeLog-pr-8235.yml b/html/changelogs/AutoChangeLog-pr-8235.yml
deleted file mode 100644
index ab5aef0b8d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8235.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - balance: "Defib users automatically stop pulling when they attempt to perform a defib shock"
diff --git a/html/changelogs/AutoChangeLog-pr-8236.yml b/html/changelogs/AutoChangeLog-pr-8236.yml
deleted file mode 100644
index 3e266fb6fc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8236.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - refactor: "Added unomos, which is basically listmos except gas mixtures only use one single list for handling their gasses. This is a significant performance improvement that also offers a mild memory improvement under normal circumstances."
diff --git a/html/changelogs/AutoChangeLog-pr-8237.yml b/html/changelogs/AutoChangeLog-pr-8237.yml
deleted file mode 100644
index 7618d0ebd2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8237.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - imageadd: "added muzzled varients of space helmets and full masks"
- - imageadd: "added knight_grey to taur suits, all paranormal ERT now have tauric versions enabled"
- - bugfix: "Lava knights have digitigrade and tauric versions now"
- - rscadd: "Added a glass version of the gas mask, because it was in the files and looked nice. does everything regular ones do except make you an unknown"
diff --git a/html/changelogs/AutoChangeLog-pr-8247.yml b/html/changelogs/AutoChangeLog-pr-8247.yml
deleted file mode 100644
index 1ab08ece4d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8247.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added custom species names! Examining people will now display their species name unless they're an Unknown or have their face hidden. like flavor text. Set it in your character window!"
- - code_imp: "changed how health scanners print messages, wrapping it in msg for one to_chat instead of printing every line to_chat."
diff --git a/html/changelogs/AutoChangeLog-pr-8252.yml b/html/changelogs/AutoChangeLog-pr-8252.yml
deleted file mode 100644
index c86d0b5aa0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8252.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds the bonermeter; a device that measures arousal based statistics."
- - refactor: "Added a new input to the electrostimulator that controls the strength of the shock. It accepts negative inputs which reduce arousal. Added a new output to the electrostimulator that displays the amount of arousal gained."
- - balance: "Rebalanced the electro-stimulator to be less spammy by giving it a 2.5 second enforced cooldown per circuit contraption. Increased the complexity of electro stimulator from 10 to 15."
diff --git a/html/changelogs/AutoChangeLog-pr-8255.yml b/html/changelogs/AutoChangeLog-pr-8255.yml
deleted file mode 100644
index 1b2e81f5bd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8255.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerB"
-delete-after: True
-changes:
- - tweak: "Tweaked the UI of the loadout to be less cluttered due to an issue with formatting."
diff --git a/html/changelogs/AutoChangeLog-pr-8258.yml b/html/changelogs/AutoChangeLog-pr-8258.yml
deleted file mode 100644
index 2d1f75603f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8258.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - refactor: "Reworked the Vent Clog event to spray smoke instead of foam, also made it shoot smoke over time instead through each vent instead of all at once."
diff --git a/html/changelogs/AutoChangeLog-pr-8259.yml b/html/changelogs/AutoChangeLog-pr-8259.yml
deleted file mode 100644
index 54a1dd6a4b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8259.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Locomotion circuits are now restricted to jogging speed"
- - balance: "MMI circuits and pAI circuits both now have 60 complexity, up from their original 29."
diff --git a/html/changelogs/AutoChangeLog-pr-8260.yml b/html/changelogs/AutoChangeLog-pr-8260.yml
deleted file mode 100644
index e6ef697917..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8260.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "cakes!"
- - imageadd: "Made some sprites! -Love them really came out well"
diff --git a/html/changelogs/AutoChangeLog-pr-8261.yml b/html/changelogs/AutoChangeLog-pr-8261.yml
deleted file mode 100644
index e7624aec73..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8261.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "new economics"
- - tweak: "cargo and robotics relationships"
- - balance: "unbalanced something"
- - bugfix: "fixed a maybe oversight"
diff --git a/html/changelogs/AutoChangeLog-pr-8264.yml b/html/changelogs/AutoChangeLog-pr-8264.yml
deleted file mode 100644
index 15e525c581..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8264.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscdel: "Fun"
- - tweak: "costs of suit voucher"
- - balance: "Unblances miner vender"
- - bugfix: "spare cheaper brute kit"
diff --git a/html/changelogs/AutoChangeLog-pr-8265.yml b/html/changelogs/AutoChangeLog-pr-8265.yml
deleted file mode 100644
index e581a93315..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8265.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "harm from hentie"
- - balance: "rebalanced goliaths stun to be less auto death"
diff --git a/html/changelogs/AutoChangeLog-pr-8274.yml b/html/changelogs/AutoChangeLog-pr-8274.yml
deleted file mode 100644
index 41b2de1d9e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8274.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - tweak: "Increased the spawn area of the City of Cogs (Reebe). This does not affect the area in which builders can build."
diff --git a/html/changelogs/AutoChangeLog-pr-8277.yml b/html/changelogs/AutoChangeLog-pr-8277.yml
deleted file mode 100644
index 2a663ea2a4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8277.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - balance: "Significantly tweaks the Wizard race transformation event to be less unreasonably troublesome."
diff --git a/html/changelogs/AutoChangeLog-pr-8278.yml b/html/changelogs/AutoChangeLog-pr-8278.yml
deleted file mode 100644
index 57655b8ace..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8278.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Armor to blob shields"
- - tweak: "block weaken state to 70% from 75%"
diff --git a/html/changelogs/AutoChangeLog-pr-8279.yml b/html/changelogs/AutoChangeLog-pr-8279.yml
deleted file mode 100644
index 7ed141640a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8279.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "restores the deathriplys missing armor"
diff --git a/html/changelogs/AutoChangeLog-pr-8283.yml b/html/changelogs/AutoChangeLog-pr-8283.yml
deleted file mode 100644
index 7a614e2e82..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8283.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds a new 0 cost trait that makes you immune* to Crocin and Hexacrocin"
diff --git a/html/changelogs/AutoChangeLog-pr-8286.yml b/html/changelogs/AutoChangeLog-pr-8286.yml
deleted file mode 100644
index d59a8dad66..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8286.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - tweak: "Tweaks how slurring works so it's more of a gradual change into slurring instead of immediate."
- - balance: "Slurring is now directly proportional to your drunkenness, with other sources of slur being added on top of it."
diff --git a/html/changelogs/AutoChangeLog-pr-8287.yml b/html/changelogs/AutoChangeLog-pr-8287.yml
deleted file mode 100644
index aafba03474..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8287.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "new lockable colalr"
diff --git a/html/changelogs/AutoChangeLog-pr-8288.yml b/html/changelogs/AutoChangeLog-pr-8288.yml
deleted file mode 100644
index 6b3fbadbd8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8288.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - tweak: "Bras are now separate from underwear, meaning you can mix and match bras if you're into that."
- - tweak: "Men can wear female accessory clothing, and females can wear men accessory clothing. It's not a fetish, mom, it's PROGRESSIVE."
- - code_imp: "Reorganized accessories into their own files to prevent a massive 1000 line file."
- - server: "i'm 10% sure that merging this PR will cause preference corruption sooooooooooo I just need to hear from @deathride58 or perhaps someone else on how much damage this could possibly do."
diff --git a/html/changelogs/AutoChangeLog-pr-8290.yml b/html/changelogs/AutoChangeLog-pr-8290.yml
deleted file mode 100644
index 553bfbf4f9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8290.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "missing hopes and dreams"
- - code_imp: "orgized the weapon file to be more cat brain friendly"
diff --git a/html/changelogs/AutoChangeLog-pr-8294.yml b/html/changelogs/AutoChangeLog-pr-8294.yml
deleted file mode 100644
index bce0031c2b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8294.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - imageadd: "This means sprite right?"
diff --git a/html/changelogs/AutoChangeLog-pr-8295.yml b/html/changelogs/AutoChangeLog-pr-8295.yml
deleted file mode 100644
index 833474e9af..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8295.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscdel: "Many engi flags on non-engi things"
- - code_imp: "changed some code to be organized at a glance"
diff --git a/html/changelogs/AutoChangeLog-pr-8296.yml b/html/changelogs/AutoChangeLog-pr-8296.yml
deleted file mode 100644
index 78db7ccb0d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8296.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - balance: "25% < --- 50% For NPC blocking bullshit
-ided: Yes"
diff --git a/html/changelogs/AutoChangeLog-pr-8301.yml b/html/changelogs/AutoChangeLog-pr-8301.yml
deleted file mode 100644
index 90e893bdf2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8301.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "mag gun uses cells"
- - balance: "kev things their to op"
diff --git a/html/changelogs/AutoChangeLog-pr-8302.yml b/html/changelogs/AutoChangeLog-pr-8302.yml
deleted file mode 100644
index e2b535c40f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8302.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - tweak: "Tweaked penis."
- - balance: "Rebalanced penis."
diff --git a/html/changelogs/AutoChangeLog-pr-8303.yml b/html/changelogs/AutoChangeLog-pr-8303.yml
deleted file mode 100644
index 8c3742ca8a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8303.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Added the following reagents to the common list of vent clog reagents: ~~Cooking Oil~~, ~~Frost Oil~~, Sodium Chloride, Corn Oil, Uranium, Carpet, Firefighting Foam, semen, femcum, tear juice, strange reagent, ~~spraytan~~."
- - balance: "Vent Clog smoke emits the same transparent smoke as a smoke machine, including how much it transfers. Vent Clogs also do not trigger in areas deemed \"Safe\" in code, such as in the dorms or trusted areas where dangerous things shouldn't occur."
diff --git a/html/changelogs/AutoChangeLog-pr-8305.yml b/html/changelogs/AutoChangeLog-pr-8305.yml
deleted file mode 100644
index 2293fa9163..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8305.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - server: "Discord bot will now report when a round ends and give the vague news ticker that a sister-station would have received for the game mode and result of the round."
diff --git a/html/changelogs/AutoChangeLog-pr-8306.yml b/html/changelogs/AutoChangeLog-pr-8306.yml
deleted file mode 100644
index 95ceb32968..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8306.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed medical hardsuit overlay issue. I thought it was going to work well but fuck byond."
- - bugfix: "None body markings shouldn't give rgb hell, but it also should reset properly anyway. ree."
- - bugfix: "Sorted some sprites to better sooth my byond icon limit anxiety."
diff --git a/html/changelogs/AutoChangeLog-pr-8311.yml b/html/changelogs/AutoChangeLog-pr-8311.yml
deleted file mode 100644
index 6ec7aae071..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8311.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "syndicate phobia"
- - tweak: "other phobia's"
diff --git a/html/changelogs/AutoChangeLog-pr-8315.yml b/html/changelogs/AutoChangeLog-pr-8315.yml
deleted file mode 100644
index 5d0b85e162..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8315.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "laser carbine"
diff --git a/html/changelogs/AutoChangeLog-pr-8316.yml b/html/changelogs/AutoChangeLog-pr-8316.yml
deleted file mode 100644
index b51a40c846..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8316.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "makes collars only locked via key"
diff --git a/html/changelogs/AutoChangeLog-pr-8317.yml b/html/changelogs/AutoChangeLog-pr-8317.yml
deleted file mode 100644
index 0fd31c3c52..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8317.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "Biogenerators now have a sane limit for production"
diff --git a/html/changelogs/AutoChangeLog-pr-8318.yml b/html/changelogs/AutoChangeLog-pr-8318.yml
deleted file mode 100644
index 0c0a5c06c4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8318.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds additional random brain damage text"
diff --git a/html/changelogs/AutoChangeLog-pr-8319.yml b/html/changelogs/AutoChangeLog-pr-8319.yml
deleted file mode 100644
index e46b83c121..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8319.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds penis enlargement pills."
diff --git a/html/changelogs/AutoChangeLog-pr-8322.yml b/html/changelogs/AutoChangeLog-pr-8322.yml
deleted file mode 100644
index 188c988021..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8322.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "charging"
diff --git a/html/changelogs/AutoChangeLog-pr-8323.yml b/html/changelogs/AutoChangeLog-pr-8323.yml
deleted file mode 100644
index 0c4fc13b48..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8323.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Combat inducers for COMBAT!"
diff --git a/html/changelogs/AutoChangeLog-pr-8325.yml b/html/changelogs/AutoChangeLog-pr-8325.yml
deleted file mode 100644
index 1e665e7917..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8325.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - code_imp: "made it look nice"
diff --git a/html/changelogs/AutoChangeLog-pr-8334.yml b/html/changelogs/AutoChangeLog-pr-8334.yml
deleted file mode 100644
index 3c9152c257..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8334.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "dtfe3"
-delete-after: True
-changes:
- - tweak: "Increased music maxlines from 300 to 600"
diff --git a/html/changelogs/AutoChangeLog-pr-8336.yml b/html/changelogs/AutoChangeLog-pr-8336.yml
deleted file mode 100644
index 25a14e5d1f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8336.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds Stun Circuit and Pneumatic Cannon Integrated Circuits"
- - bugfix: "Fixed extinguisher and smoke circuits not accepting any reagents."
diff --git a/html/changelogs/AutoChangeLog-pr-8341.yml b/html/changelogs/AutoChangeLog-pr-8341.yml
deleted file mode 100644
index 50dedb7374..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8341.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "golden swag boxes"
diff --git a/html/changelogs/AutoChangeLog-pr-8342.yml b/html/changelogs/AutoChangeLog-pr-8342.yml
deleted file mode 100644
index a159f3240f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8342.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds a few important clockcult tips."
- - rscadd: "Added Mech Sensors, a brass-created trap that activates when a mech not controlled by a cultist crosses it."
- - rscadd: "Added power nullifiers, an emp trap that emps everything in a 3x3 area, with the center suffering a heavy EMP."
- - tweak: "Brass Skewers now deal 50 damage to mechs."
diff --git a/html/changelogs/AutoChangeLog-pr-8348.yml b/html/changelogs/AutoChangeLog-pr-8348.yml
deleted file mode 100644
index b4272de0a5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8348.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Crafting suitcases"
diff --git a/html/changelogs/AutoChangeLog-pr-8349.yml b/html/changelogs/AutoChangeLog-pr-8349.yml
deleted file mode 100644
index de4c08624a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8349.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "more bountys"
- - rscdel: "Nitryl bounty"
diff --git a/html/changelogs/AutoChangeLog-pr-8352.yml b/html/changelogs/AutoChangeLog-pr-8352.yml
deleted file mode 100644
index ff9e9130db..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8352.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Fixed a fairly huge server crash exploit"
diff --git a/html/changelogs/AutoChangeLog-pr-8362.yml b/html/changelogs/AutoChangeLog-pr-8362.yml
deleted file mode 100644
index 29a840e22f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8362.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "dtfe3"
-delete-after: True
-changes:
- - tweak: "Made it so any oxygen tank can be used instead of only red ones."
diff --git a/html/changelogs/AutoChangeLog-pr-8366.yml b/html/changelogs/AutoChangeLog-pr-8366.yml
deleted file mode 100644
index c7c16a8e7d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8366.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Box Cryopods expanded to 6 public. Permabrig cryo fixed."
- - bugfix: "Delta Cryopods expanded to 6 public. Permabrig cryo fixed."
- - bugfix: "MetaStation Crypods expanded to 6 public, relocated above sparring ring. Permabrig cryo fixed"
- - bugfix: "PubbyStation gained one more cryopod, Permabrig's cryo fixed."
- - rscadd: "Omega given one more crypod as well."
- - rscadd: "Gulag was given a cryopod."
- - tweak: "Box and Meta's cryo rooms are now a new room entirely."
diff --git a/html/changelogs/AutoChangeLog-pr-8367.yml b/html/changelogs/AutoChangeLog-pr-8367.yml
deleted file mode 100644
index b5e3a87cc5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8367.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added erect states for all phallic bodyparts"
- - bugfix: "YOUR DICK ACTUALLY STANDS UP NOW, YOU'RE WELCOME."
- - bugfix: "skintone locked genitals match the new skintone colorations."
- - rscadd: "added two new vaginal types and descriptions."
diff --git a/html/changelogs/AutoChangeLog-pr-8368.yml b/html/changelogs/AutoChangeLog-pr-8368.yml
deleted file mode 100644
index cffcd2208e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8368.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "better stocks"
diff --git a/html/changelogs/AutoChangeLog-pr-8369.yml b/html/changelogs/AutoChangeLog-pr-8369.yml
deleted file mode 100644
index ca13347288..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8369.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "more evil blood fluff text"
diff --git a/html/changelogs/AutoChangeLog-pr-8370.yml b/html/changelogs/AutoChangeLog-pr-8370.yml
deleted file mode 100644
index 1ff275b762..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8370.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Added more mime names"
diff --git a/html/changelogs/AutoChangeLog-pr-8372.yml b/html/changelogs/AutoChangeLog-pr-8372.yml
deleted file mode 100644
index 88ebc9854c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8372.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed borg defib runtimes"
diff --git a/html/changelogs/AutoChangeLog-pr-8374.yml b/html/changelogs/AutoChangeLog-pr-8374.yml
deleted file mode 100644
index e86e591827..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8374.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed heart attacks being nonlethal"
diff --git a/html/changelogs/AutoChangeLog-pr-8376.yml b/html/changelogs/AutoChangeLog-pr-8376.yml
deleted file mode 100644
index 8ab3b8b8bc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8376.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Ported Oracle's cloning set up, you're now visible like cryo when being cloned, though it's a mystery until you have skin on your meat puppet existance"
diff --git a/html/changelogs/AutoChangeLog-pr-8377.yml b/html/changelogs/AutoChangeLog-pr-8377.yml
deleted file mode 100644
index b6265b3bff..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8377.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - balance: "Recyclers are unable to destroy the indestructible any longer."
diff --git a/html/changelogs/AutoChangeLog-pr-8384.yml b/html/changelogs/AutoChangeLog-pr-8384.yml
deleted file mode 100644
index f98b473e6c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8384.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Nero1024"
-delete-after: True
-changes:
- - soundadd: "Bare feet will now make the correct footstep sounds."
- - soundadd: "Other mobs will make the correct footstep sounds."
- - soundadd: "Crawling/dragging sounds for downed/incapacitated mobs"
diff --git a/html/changelogs/AutoChangeLog-pr-8387.yml b/html/changelogs/AutoChangeLog-pr-8387.yml
deleted file mode 100644
index 4770fe08fc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8387.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "jtgsz"
-delete-after: True
-changes:
- - rscadd: "ported gang mode"
diff --git a/html/changelogs/AutoChangeLog-pr-8388.yml b/html/changelogs/AutoChangeLog-pr-8388.yml
deleted file mode 100644
index 570b30448a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8388.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Useroth"
-delete-after: True
-changes:
- - bugfix: "the collars are now aware of their proper overlay sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-8391.yml b/html/changelogs/AutoChangeLog-pr-8391.yml
deleted file mode 100644
index 32e837a0a6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8391.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "replaces a sink with a autolathen"
diff --git a/html/changelogs/AutoChangeLog-pr-8392.yml b/html/changelogs/AutoChangeLog-pr-8392.yml
deleted file mode 100644
index 986bb0a6fa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8392.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Kiara's toy sabre now actually is the correct item + icon states"
- - bugfix: "Generic armor for taurs fixed, there isn't actually any sprites for 'em, so. Full sprites overlay over bodies, but I really can't be bothered to do all the offset fixes otherwise."
diff --git a/html/changelogs/AutoChangeLog-pr-8393.yml b/html/changelogs/AutoChangeLog-pr-8393.yml
deleted file mode 100644
index 4bc0472560..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8393.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "WhiteHusky"
-delete-after: True
-changes:
- - rscadd: "Sleepers now show blood level and type."
diff --git a/html/changelogs/AutoChangeLog-pr-8397.yml b/html/changelogs/AutoChangeLog-pr-8397.yml
deleted file mode 100644
index 28ed98666f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8397.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "WhiteHusky"
-delete-after: True
-changes:
- - tweak: "Changed the styling of arousal messages to use pink-ish colors."
- - bugfix: "The orgasm moodlet message new-lines properly."
diff --git a/html/changelogs/AutoChangeLog-pr-8398.yml b/html/changelogs/AutoChangeLog-pr-8398.yml
deleted file mode 100644
index a7ce2fbe2d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8398.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - balance: "Ass slapping only works if you're actually behind the target. Ass slapping now respects disarm blocking. You can no longer face/ass slap someone on an intent other than help, unless they are also face/ass slapping."
- - bugfix: "Fixed ass and face slapping grammar."
- - rscadd: "Adds meh effects for ass and face slapping."
diff --git a/html/changelogs/AutoChangeLog-pr-8399.yml b/html/changelogs/AutoChangeLog-pr-8399.yml
deleted file mode 100644
index 5c71d19faa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8399.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Large maps have had a patient room transformed into micro chemistry stations with nothing else in them. They've been labelled 'Apothecary' rooms and are accessible by doctors."
diff --git a/html/changelogs/AutoChangeLog-pr-8400.yml b/html/changelogs/AutoChangeLog-pr-8400.yml
deleted file mode 100644
index 485e4c4812..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8400.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "dtfe3"
-delete-after: True
-changes:
- - tweak: "Watcher wing Trophy's effect lasts 1 second instead of 0.5"
diff --git a/html/changelogs/AutoChangeLog-pr-8404.yml b/html/changelogs/AutoChangeLog-pr-8404.yml
deleted file mode 100644
index c230977a44..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8404.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "WhiteHusky"
-delete-after: True
-changes:
- - bugfix: "Flavor text with special characters will not get partially unescaped."
- - bugfix: "Canceling when setting flavor text does not clear it anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-8407.yml b/html/changelogs/AutoChangeLog-pr-8407.yml
deleted file mode 100644
index 5f1d9d0729..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8407.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "females now have female defined sprites"
- - bugfix: "Slime legs have had their excess pixels adjusted"
- - bugfix: "Mammal normal legs are more in line with human legs now"
diff --git a/html/changelogs/AutoChangeLog-pr-8408.yml b/html/changelogs/AutoChangeLog-pr-8408.yml
deleted file mode 100644
index 548e4947be..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8408.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes cult potentially stalling if the target is erased from existence without being sacced."
diff --git a/html/changelogs/AutoChangeLog-pr-8409.yml b/html/changelogs/AutoChangeLog-pr-8409.yml
deleted file mode 100644
index 01f69bf437..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8409.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed species like abductors and golems getting the fat tiddy or pingas"
diff --git a/html/changelogs/AutoChangeLog-pr-8411.yml b/html/changelogs/AutoChangeLog-pr-8411.yml
deleted file mode 100644
index 4d4a122cf2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8411.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - balance: "2 -> 3"
diff --git a/html/changelogs/AutoChangeLog-pr-8413.yml b/html/changelogs/AutoChangeLog-pr-8413.yml
deleted file mode 100644
index 01de909a3b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8413.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Useroth"
-delete-after: True
-changes:
- - bugfix: "The space hotel dorms are now properly boltable with the buttons inside."
- - bugfix: "Makes the booze-o-mat hacked by default. Alternative to https://github.com/Citadel-Station-13/Citadel-Station-13/pull/8350."
diff --git a/html/changelogs/AutoChangeLog-pr-8414.yml b/html/changelogs/AutoChangeLog-pr-8414.yml
deleted file mode 100644
index eaec60b3a9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8414.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "MASON SUIT!"
diff --git a/html/changelogs/AutoChangeLog-pr-8416.yml b/html/changelogs/AutoChangeLog-pr-8416.yml
deleted file mode 100644
index 34bac362be..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8416.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "adds the sec jetpack to sec hardsuit storge"
diff --git a/html/changelogs/AutoChangeLog-pr-8417.yml b/html/changelogs/AutoChangeLog-pr-8417.yml
deleted file mode 100644
index 2a6eaa6237..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8417.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Added a few jet packs to the space queens men"
- - tweak: "volume of jet packs"
diff --git a/html/changelogs/AutoChangeLog-pr-8419.yml b/html/changelogs/AutoChangeLog-pr-8419.yml
deleted file mode 100644
index 037dba41ad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8419.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "UntoldTactics"
-delete-after: True
-changes:
- - tweak: "Rewords the click here prompt given when an attempted conversion is done on an offer rune (for blood cult)"
diff --git a/html/changelogs/AutoChangeLog-pr-8420.yml b/html/changelogs/AutoChangeLog-pr-8420.yml
deleted file mode 100644
index 60c8543647..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8420.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Shield blobs no longer become completely invulnerable to all forms of damage after reaching a \"\"\"weakened\"\"\" state"
- - tweak: "Taken care of what appeared to have been an oversight where shield blobs don't recover their armor after becoming weakened."
diff --git a/html/changelogs/AutoChangeLog-pr-8424.yml b/html/changelogs/AutoChangeLog-pr-8424.yml
deleted file mode 100644
index 12295e8a82..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8424.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - rscadd: "You can now use CTRL and ALT click on pumps and filters to toggle them on and off and max their output respectively"
diff --git a/html/changelogs/AutoChangeLog-pr-8429.yml b/html/changelogs/AutoChangeLog-pr-8429.yml
deleted file mode 100644
index 0769af85aa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8429.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Nerfed concatenators by limiting the amount of characters they're able to output"
diff --git a/html/changelogs/AutoChangeLog-pr-8430.yml b/html/changelogs/AutoChangeLog-pr-8430.yml
deleted file mode 100644
index e59f61821a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8430.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Bad Idea"
diff --git a/html/changelogs/AutoChangeLog-pr-8432.yml b/html/changelogs/AutoChangeLog-pr-8432.yml
deleted file mode 100644
index e65bfd68d3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8432.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "Nukes the stunprod's 3 seconds delay."
- - bugfix: "Fixes teleprods."
diff --git a/html/changelogs/AutoChangeLog-pr-8434.yml b/html/changelogs/AutoChangeLog-pr-8434.yml
deleted file mode 100644
index d01858d2b4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8434.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Stops pulls of resting mobs breaking off whenever you swap turfs with someone else because of crawling delays."
diff --git a/html/changelogs/AutoChangeLog-pr-8435.yml b/html/changelogs/AutoChangeLog-pr-8435.yml
deleted file mode 100644
index 3c2caeb994..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8435.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "fixes IAA."
diff --git a/html/changelogs/AutoChangeLog-pr-8436.yml b/html/changelogs/AutoChangeLog-pr-8436.yml
deleted file mode 100644
index 6d626bf357..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8436.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "bio mass meat"
diff --git a/html/changelogs/AutoChangeLog-pr-8437.yml b/html/changelogs/AutoChangeLog-pr-8437.yml
deleted file mode 100644
index 4257a801c9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8437.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "more box options"
- - bugfix: "a lack of replaceable boxes"
diff --git a/html/changelogs/AutoChangeLog-pr-8439.yml b/html/changelogs/AutoChangeLog-pr-8439.yml
deleted file mode 100644
index 1e4bd2efae..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8439.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "EMPs now flick off stunbatons, they can be turned back on immediately by the user anyway."
- - balance: "Stunbatons now very slowly consume charge whilst kept on, at a rate of 4/1000th of a standard batoning charge cost per tick."
- - balance: "Softened up the charge cost checks to stop the above update from practically reducing the maximum uses of a stun baton by one. Now, should the remaining charge be lower than the hit cost, the resulting stun will be be proportional to the remaining charge divided by the hitcost, within a limit under which the stun batoning just won't happen."
diff --git a/html/changelogs/AutoChangeLog-pr-8442.yml b/html/changelogs/AutoChangeLog-pr-8442.yml
deleted file mode 100644
index e73c67c6dc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8442.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "clothing needing a emag"
diff --git a/html/changelogs/AutoChangeLog-pr-8443.yml b/html/changelogs/AutoChangeLog-pr-8443.yml
deleted file mode 100644
index 1b1f82977b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8443.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "The timer for stripping an item off of a spaceman is no longer interrupted by your active held item changing. This means you no longer have to worry about filling both of your hands when you're stripping items off of someone."
diff --git a/html/changelogs/AutoChangeLog-pr-8448.yml b/html/changelogs/AutoChangeLog-pr-8448.yml
deleted file mode 100644
index e670ffc0f4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8448.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "4 - > 5"
diff --git a/html/changelogs/AutoChangeLog-pr-8449.yml b/html/changelogs/AutoChangeLog-pr-8449.yml
deleted file mode 100644
index c2c397cdd0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8449.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "5->6"
diff --git a/html/changelogs/AutoChangeLog-pr-8450.yml b/html/changelogs/AutoChangeLog-pr-8450.yml
deleted file mode 100644
index 8afa74c68c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8450.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "4tc - > 2tc"
diff --git a/html/changelogs/AutoChangeLog-pr-8452.yml b/html/changelogs/AutoChangeLog-pr-8452.yml
deleted file mode 100644
index 2b4e430757..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8452.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "mulligan costs 4 - > 3"
diff --git a/html/changelogs/AutoChangeLog-pr-8453.yml b/html/changelogs/AutoChangeLog-pr-8453.yml
deleted file mode 100644
index cda1843779..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8453.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "Tuberculosis 12tc - > 8tc"
diff --git a/html/changelogs/AutoChangeLog-pr-8454.yml b/html/changelogs/AutoChangeLog-pr-8454.yml
deleted file mode 100644
index 4cc6d98df1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8454.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "15 - >10"
- - bugfix: "both bags have the same name"
diff --git a/html/changelogs/AutoChangeLog-pr-8455.yml b/html/changelogs/AutoChangeLog-pr-8455.yml
deleted file mode 100644
index e7944f5869..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8455.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "5 - > 2"
diff --git a/html/changelogs/AutoChangeLog-pr-8456.yml b/html/changelogs/AutoChangeLog-pr-8456.yml
deleted file mode 100644
index 3ff35b1c09..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8456.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "3 -> 1"
diff --git a/html/changelogs/AutoChangeLog-pr-8459.yml b/html/changelogs/AutoChangeLog-pr-8459.yml
deleted file mode 100644
index ebce2f0db1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8459.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "2 < - 4"
diff --git a/html/changelogs/AutoChangeLog-pr-8460.yml b/html/changelogs/AutoChangeLog-pr-8460.yml
deleted file mode 100644
index 39af97ef12..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8460.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "1->2 and ultra"
diff --git a/html/changelogs/AutoChangeLog-pr-8463.yml b/html/changelogs/AutoChangeLog-pr-8463.yml
deleted file mode 100644
index a6c8d05522..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8463.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "shield + crafting"
diff --git a/html/changelogs/AutoChangeLog-pr-8465.yml b/html/changelogs/AutoChangeLog-pr-8465.yml
deleted file mode 100644
index 91556b4afc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8465.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Useroth"
-delete-after: True
-changes:
- - bugfix: "After the PR which raised the ammo capacity of said magazines, due to the code, they ended up with an invalid icon state. Fixed through changing the icon state name in the icon file."
diff --git a/html/changelogs/AutoChangeLog-pr-8466.yml b/html/changelogs/AutoChangeLog-pr-8466.yml
deleted file mode 100644
index a3cffc8f59..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8466.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "Atmos and Station alerts should be more alerting."
diff --git a/html/changelogs/AutoChangeLog-pr-8470.yml b/html/changelogs/AutoChangeLog-pr-8470.yml
deleted file mode 100644
index 39399c0724..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8470.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "Buffs condensed capsaicin, a yet another feature previously dunked by stam combat."
- - balance: "speeds up pepper spray puffs."
diff --git a/html/changelogs/AutoChangeLog-pr-8473.yml b/html/changelogs/AutoChangeLog-pr-8473.yml
deleted file mode 100644
index a4743c9a39..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8473.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-author: "Useroth"
-delete-after: True
-changes:
- - rscadd: "Taeclowndo shoes which grant the four following abilities:
-- Conjuring a cream pie right into their hand. Every three seconds.
-- Making a banana peel appear out of thin air at the tile of the clown's choice. Every ten seconds.
-- Mega HoNk. A touch-ranged, very small AOE ability, with effect equal to being honked by a Honkerblast on a clown mech, with the effects halved for anyone who isn't its direct target. Every ten seconds.
-- Bluespace Banana Pie. You don't throw this one... not right away at least. This baby can fit an entire body inside. Good for disposal of evidence. 25 second-long action, 45 second cooldown. Also produces a \"[victim's name] cream pie\". The body drops out of the pie if you splat it somewhere or destroy the pie. If you eat it, it will chestburst out of you a'la monkey cube.
-
-It's a 14 TC item for traitor clowns and a 12 TC item for clown-ops."
diff --git a/html/changelogs/AutoChangeLog-pr-8476.yml b/html/changelogs/AutoChangeLog-pr-8476.yml
deleted file mode 100644
index 551a443f94..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8476.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "hierophant movment and melee attack"
diff --git a/html/changelogs/AutoChangeLog-pr-8477.yml b/html/changelogs/AutoChangeLog-pr-8477.yml
deleted file mode 100644
index f5478ed178..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8477.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - rscadd: "Ported the zulie cloak and blackredgold coat donor items from RP."
diff --git a/html/changelogs/AutoChangeLog-pr-8479.yml b/html/changelogs/AutoChangeLog-pr-8479.yml
deleted file mode 100644
index b6c8340527..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8479.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "Buffed krav maga leg sweep stun and stamina damage. On the other hand, it's now unable to be used on already lying targets."
diff --git a/html/changelogs/AutoChangeLog-pr-8482.yml b/html/changelogs/AutoChangeLog-pr-8482.yml
deleted file mode 100644
index 095f93a7a3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8482.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "fixes eyestabbing people with cutlery while being a pacifist."
diff --git a/html/changelogs/AutoChangeLog-pr-8483.yml b/html/changelogs/AutoChangeLog-pr-8483.yml
deleted file mode 100644
index 2e3b35ca92..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8483.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by mrhugo13 on tgstation13)"
-delete-after: True
-changes:
- - rscadd: "The Syndicate has decided to equip their Syndicate leaders operative (Aswell as their clown counterparts) with the new Combat Glove Plus! The new Combat Glove Plus does everything the old boring Combat Gloves does but with the added extra of learning Krav Maga upon wearing them, any other Syndicate operative who wants to get in on the action will have to pay 5tc."
diff --git a/html/changelogs/AutoChangeLog-pr-8485.yml b/html/changelogs/AutoChangeLog-pr-8485.yml
deleted file mode 100644
index abc79f1f30..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8485.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "More plushies"
- - tweak: "attack verbs and descs"
diff --git a/html/changelogs/AutoChangeLog-pr-8489.yml b/html/changelogs/AutoChangeLog-pr-8489.yml
deleted file mode 100644
index 5e90c56d67..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8489.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Coolgat3"
-delete-after: True
-changes:
- - rscadd: "Added combat gloves sprite"
- - imageadd: "Added said sprite"
diff --git a/html/changelogs/AutoChangeLog-pr-8491.yml b/html/changelogs/AutoChangeLog-pr-8491.yml
deleted file mode 100644
index 0e82e809f7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8491.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Reduces goonchat lag from being blasted by pellets and bullets repeatedly whilst wearing armor by properly removing the armor protection texts this times."
- - spellcheck: "also reduced the size of armor protection messages in general. they clog up the chat box."
diff --git a/html/changelogs/AutoChangeLog-pr-8494.yml b/html/changelogs/AutoChangeLog-pr-8494.yml
deleted file mode 100644
index 2e4d7ac65e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8494.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "bone satchles"
diff --git a/html/changelogs/AutoChangeLog-pr-8495.yml b/html/changelogs/AutoChangeLog-pr-8495.yml
deleted file mode 100644
index 92777ef8b0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8495.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - tweak: "\"Unwillingly\" eating food now sends a warning message instead of a notice. Unable to stuff food down your throat sends a danger message instead of a warning message."
diff --git a/html/changelogs/AutoChangeLog-pr-8497.yml b/html/changelogs/AutoChangeLog-pr-8497.yml
deleted file mode 100644
index 4c42899313..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8497.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds clockwork reflectors, a fragile anti-laser reflection shield object that can be constructed for 10 brass sheets. Upon firing on the object in the direction where it is shielded, it ricochets the bullet off of it relative to the shooting angle."
- - tweak: "Renames some windows in the build menu for consistency."
diff --git a/html/changelogs/AutoChangeLog-pr-8500.yml b/html/changelogs/AutoChangeLog-pr-8500.yml
deleted file mode 100644
index 09bfbd9748..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8500.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - balance: "rebalanced stunslugs"
diff --git a/html/changelogs/AutoChangeLog-pr-8501.yml b/html/changelogs/AutoChangeLog-pr-8501.yml
deleted file mode 100644
index fba27c4d52..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8501.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "colored boxes, and more types"
diff --git a/html/changelogs/AutoChangeLog-pr-8503.yml b/html/changelogs/AutoChangeLog-pr-8503.yml
deleted file mode 100644
index f6c4a7dc75..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8503.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "harm and such"
- - balance: "item classes"
diff --git a/html/changelogs/AutoChangeLog-pr-8504.yml b/html/changelogs/AutoChangeLog-pr-8504.yml
deleted file mode 100644
index 4e80d02845..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8504.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "resonators being so shitty"
diff --git a/html/changelogs/AutoChangeLog-pr-8505.yml b/html/changelogs/AutoChangeLog-pr-8505.yml
deleted file mode 100644
index 57d6399680..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8505.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - balance: "Clockwork Cult walls can no longer be deconstructed by RCDs when heated."
diff --git a/html/changelogs/AutoChangeLog-pr-8506.yml b/html/changelogs/AutoChangeLog-pr-8506.yml
deleted file mode 100644
index 6711217fb5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8506.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "CalamaBanana"
-delete-after: True
-changes:
- - rscadd: "Added Deer taur"
- - rscadd: "Added Elf ears to mammals"
diff --git a/html/changelogs/AutoChangeLog-pr-8514.yml b/html/changelogs/AutoChangeLog-pr-8514.yml
deleted file mode 100644
index f1d01a97e4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8514.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds several new toy loot to the arcade machine."
- - balance: "Rebalanced the arcade machine loot. Battlemachines now have a 0.5 second delay instead of a second delay between actions."
- - bugfix: "Fixed a bug that would not allow the one in a million pulse rifle to spawn."
diff --git a/html/changelogs/AutoChangeLog-pr-8515.yml b/html/changelogs/AutoChangeLog-pr-8515.yml
deleted file mode 100644
index 99e414f5e1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8515.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes stunbatons icon not properly updating on cell removal and insertion."
- - tweak: "Allows lower charge cells to be used with stun batons, and thus single use crapshots batons."
diff --git a/html/changelogs/AutoChangeLog-pr-8516.yml b/html/changelogs/AutoChangeLog-pr-8516.yml
deleted file mode 100644
index f7419f1add..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8516.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "Adds in a 7 seconds delay to the jackhammer dismantling a superheated clockwork wall."
diff --git a/html/changelogs/AutoChangeLog-pr-8517.yml b/html/changelogs/AutoChangeLog-pr-8517.yml
deleted file mode 100644
index 5e14c1c696..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8517.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added visible and hidden testicles"
- - rscadd: "Added multi-boob support. Now you can have two or three pairs of breasts."
- - bugfix: "fixed missing vagina and breast sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-8518.yml b/html/changelogs/AutoChangeLog-pr-8518.yml
deleted file mode 100644
index cbc34893b6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8518.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "escape pods emergency suits storage can now be busted open by emags or excessive damage."
- - bugfix: "Fixes alt click bypassing the escape pods' suits storage lock."
diff --git a/html/changelogs/AutoChangeLog-pr-8522.yml b/html/changelogs/AutoChangeLog-pr-8522.yml
deleted file mode 100644
index eb646034fd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8522.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Useroth"
-delete-after: True
-changes:
- - tweak: "The tentacle now directly puts the item in your hands, instead of toggling your throwing and tossing it at you. Tentacles suffer from ranged inaccuracies as if they were guns, I think it's enough of an inconvenience."
diff --git a/html/changelogs/AutoChangeLog-pr-8524.yml b/html/changelogs/AutoChangeLog-pr-8524.yml
deleted file mode 100644
index 66a7b6d456..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8524.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Adds a new trait \"Buns of Steel\" that makes you immune to the effects of ass slapping, and temporarily makes the user's arm useless like a stun baton hit. It costs 0 points."
diff --git a/html/changelogs/AutoChangeLog-pr-8525.yml b/html/changelogs/AutoChangeLog-pr-8525.yml
deleted file mode 100644
index ef26cf1a4b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8525.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "Game braking bug
-critical: bug fix"
diff --git a/html/changelogs/AutoChangeLog-pr-8528.yml b/html/changelogs/AutoChangeLog-pr-8528.yml
deleted file mode 100644
index 0dece1e63d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8528.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - bugfix: "fixed prosthetic hands being invisible"
- - bugfix: "male foxes exist again"
- - bugfix: "female chest markings improved from being too dark in comparison to their other colors, blending better"
- - bugfix: "Markings behave better on non-organic limbs."
diff --git a/html/changelogs/AutoChangeLog-pr-8534.yml b/html/changelogs/AutoChangeLog-pr-8534.yml
deleted file mode 100644
index 5c76fbdf36..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8534.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "dtfe3"
-delete-after: True
-changes:
- - rscadd: "Pink Panties"
diff --git a/html/changelogs/AutoChangeLog-pr-8537.yml b/html/changelogs/AutoChangeLog-pr-8537.yml
deleted file mode 100644
index a537ba1c3a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8537.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes emags wasting charges on un-emaggable & co stuff."
diff --git a/html/changelogs/AutoChangeLog-pr-8538.yml b/html/changelogs/AutoChangeLog-pr-8538.yml
deleted file mode 100644
index 7349a31683..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8538.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "dtfe3"
-delete-after: True
-changes:
- - rscadd: "Twintails"
diff --git a/html/changelogs/AutoChangeLog-pr-8540.yml b/html/changelogs/AutoChangeLog-pr-8540.yml
deleted file mode 100644
index 895b80bfa6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8540.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - balance: "Ass slapping blowback from the Buns of Steel perk now deals 20 stamina damage instead of 50, and no brute damage."
diff --git a/html/changelogs/AutoChangeLog-pr-8541.yml b/html/changelogs/AutoChangeLog-pr-8541.yml
deleted file mode 100644
index 82e76fe74b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8541.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "items to syndie surgery bags"
diff --git a/html/changelogs/AutoChangeLog-pr-8543.yml b/html/changelogs/AutoChangeLog-pr-8543.yml
deleted file mode 100644
index 1e1ce8922b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8543.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "SNOW CONES"
diff --git a/html/changelogs/AutoChangeLog-pr-8544.yml b/html/changelogs/AutoChangeLog-pr-8544.yml
deleted file mode 100644
index 1641eed42e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8544.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "carts buy-able cargo"
diff --git a/html/changelogs/AutoChangeLog-pr-8547.yml b/html/changelogs/AutoChangeLog-pr-8547.yml
deleted file mode 100644
index 51c2252138..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8547.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PRs by Naksu and XDTM)"
-delete-after: True
-changes:
- - bugfix: "Transferring quirks now properly removes the roundstart trait from the person losing the quirk."
- - bugfix: "Roundstart traits no longer block the removal of other sources of that trait."
- - code_imp: "status traits are now a datum var, the accessors are now defines rather than functions."
diff --git a/html/changelogs/AutoChangeLog-pr-8548.yml b/html/changelogs/AutoChangeLog-pr-8548.yml
deleted file mode 100644
index cd49f38686..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8548.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "dtfe3"
-delete-after: True
-changes:
- - rscadd: "Schoolgirl outfits for the loadout menu!"
diff --git a/html/changelogs/AutoChangeLog-pr-8549.yml b/html/changelogs/AutoChangeLog-pr-8549.yml
deleted file mode 100644
index 32b99d1d49..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8549.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "selling/time to craft"
- - bugfix: "crafting problems, and red stamp exsplote"
- - rscadd: "gives paper work sprites that are nicer"
diff --git a/html/changelogs/AutoChangeLog-pr-8551.yml b/html/changelogs/AutoChangeLog-pr-8551.yml
deleted file mode 100644
index 738b410e26..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8551.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "tigercat2000@Paradise"
-delete-after: True
-changes:
- - bugfix: "fixed invalid characters breaking chat output for that message"
diff --git a/html/changelogs/AutoChangeLog-pr-8552.yml b/html/changelogs/AutoChangeLog-pr-8552.yml
deleted file mode 100644
index 2b63c79756..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8552.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (Original PR by LaKiller8)"
-delete-after: True
-changes:
- - bugfix: "Goonchat options should now save properly."
diff --git a/html/changelogs/AutoChangeLog-pr-8553.yml b/html/changelogs/AutoChangeLog-pr-8553.yml
deleted file mode 100644
index e89e04537b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8553.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - tweak: "tweaked the name of Sublter to distinguish its use"
- - tweak: "Gave a hint for vore posting."
diff --git a/html/changelogs/AutoChangeLog-pr-8554.yml b/html/changelogs/AutoChangeLog-pr-8554.yml
deleted file mode 100644
index 8bf00955b5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8554.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-author: "Ghommie (original PRs by Nichlas0010 and ShizCalev)"
-delete-after: True
-changes:
- - tweak: "AI core display screen can now be set in character preferences."
- - bugfix: "AI core display screen will now be restore when revived."
- - spellcheck: "Corrected some inconsistent capitalization in the player preferences screen."
- - imageadd: "Readded some forgotten AI sprites."
- - bugfix: "Fixed Hades AI death animation not playing."
- - tweak: "the AI icon-selection menu now uses a radial."
- - imageadd: "Added in the death icon_states for the \"TechDemon\" AI screen."
diff --git a/html/changelogs/AutoChangeLog-pr-8555.yml b/html/changelogs/AutoChangeLog-pr-8555.yml
deleted file mode 100644
index bb2c116dfa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8555.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - code_imp: "Ported some radials code updates."
- - rscadd: "Ported the RCL wiring menu and a comfier RCD interface."
diff --git a/html/changelogs/AutoChangeLog-pr-8556.yml b/html/changelogs/AutoChangeLog-pr-8556.yml
deleted file mode 100644
index e84af4f774..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8556.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Readded Ninja speech modifications with their mask"
diff --git a/html/changelogs/AutoChangeLog-pr-8557.yml b/html/changelogs/AutoChangeLog-pr-8557.yml
deleted file mode 100644
index 601f70f2cb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8557.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original pr by Dennok on tgstation)"
-delete-after: True
-changes:
- - bugfix: "Now you don't lose your pulled thing on the z level edge."
diff --git a/html/changelogs/AutoChangeLog-pr-8558.yml b/html/changelogs/AutoChangeLog-pr-8558.yml
deleted file mode 100644
index 6bb951f8a2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8558.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (Original PR by coiax)"
-delete-after: True
-changes:
- - refactor: "atom/var/container_type has been moved into datum/reagents/var/reagents_holder_flags. There should be no visible changes to effects."
diff --git a/html/changelogs/AutoChangeLog-pr-8559.yml b/html/changelogs/AutoChangeLog-pr-8559.yml
deleted file mode 100644
index aee1727348..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8559.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by Naksu)"
-delete-after: True
-changes:
- - code_imp: "get_area() is now a define rather than a proc."
diff --git a/html/changelogs/AutoChangeLog-pr-8560.yml b/html/changelogs/AutoChangeLog-pr-8560.yml
deleted file mode 100644
index aa1be89e09..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8560.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (original PR by 4dplanner)"
-delete-after: True
-changes:
- - bugfix: "thrown objects (but not mobs) no longer hit the thrower"
- - bugfix: "mirror shield rebound no longer depends on the original thrower's momentum"
diff --git a/html/changelogs/AutoChangeLog-pr-8561.yml b/html/changelogs/AutoChangeLog-pr-8561.yml
deleted file mode 100644
index dca2bff2ff..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8561.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (Original PR by JJRcop)"
-delete-after: True
-changes:
- - rscadd: "Ports in more emojis, including : flushed :"
diff --git a/html/changelogs/AutoChangeLog-pr-8562.yml b/html/changelogs/AutoChangeLog-pr-8562.yml
deleted file mode 100644
index a93babfdae..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8562.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "AnalWerewolf"
-delete-after: True
-changes:
- - rscadd: "Fritz plushie"
- - rscadd: "Donor item"
diff --git a/html/changelogs/AutoChangeLog-pr-8565.yml b/html/changelogs/AutoChangeLog-pr-8565.yml
deleted file mode 100644
index 91faa4d8b6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8565.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Skully)"
-delete-after: True
-changes:
- - rscadd: "Nudity Permit, a completely invisible uniform that still has pockets and such, to loadout options. It is more or less a direct port from the RP server."
diff --git a/html/changelogs/AutoChangeLog-pr-8566.yml b/html/changelogs/AutoChangeLog-pr-8566.yml
deleted file mode 100644
index 085b74e87a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8566.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "A milder combat stance message will show up if the user switch combat mode on while on help intent."
diff --git a/html/changelogs/AutoChangeLog-pr-8567.yml b/html/changelogs/AutoChangeLog-pr-8567.yml
deleted file mode 100644
index 3814607aaa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8567.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - rscadd: "You can now use RPDs on windows and grilles."
diff --git a/html/changelogs/AutoChangeLog-pr-8569.yml b/html/changelogs/AutoChangeLog-pr-8569.yml
deleted file mode 100644
index 9a51ab1099..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8569.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "dtfe3"
-delete-after: True
-changes:
- - tweak: "Now the fox ears are located in front of hair meaning they now behave much like cat ears, that being they are on-top of the hair layer."
diff --git a/html/changelogs/AutoChangeLog-pr-8570.yml b/html/changelogs/AutoChangeLog-pr-8570.yml
deleted file mode 100644
index 787b486685..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8570.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "origami"
diff --git a/html/changelogs/AutoChangeLog-pr-8578.yml b/html/changelogs/AutoChangeLog-pr-8578.yml
deleted file mode 100644
index 39ded33f2d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8578.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - spellcheck: "Properly rewords the extinguisher's instructions on how to empty it on the floor since it was changed to be a screwdriver action instead of Alt Click a while ago."
diff --git a/html/changelogs/AutoChangeLog-pr-8579.yml b/html/changelogs/AutoChangeLog-pr-8579.yml
deleted file mode 100644
index 56ecea119f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8579.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "gang tower shield"
- - tweak: "costs of boots"
diff --git a/html/changelogs/AutoChangeLog-pr-8581.yml b/html/changelogs/AutoChangeLog-pr-8581.yml
deleted file mode 100644
index 90433ecb88..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8581.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Reskinnable PDAs. A related game preference."
- - refactor: "Refactoring the pda, pda painter, obj reskinning and chameleon pda a bit to support this feature."
- - imageadd: "more PDA sprites and ported reskins."
diff --git a/html/changelogs/AutoChangeLog-pr-8584.yml b/html/changelogs/AutoChangeLog-pr-8584.yml
deleted file mode 100644
index 2621812d64..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8584.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "organ box"
diff --git a/html/changelogs/AutoChangeLog-pr-8587.yml b/html/changelogs/AutoChangeLog-pr-8587.yml
deleted file mode 100644
index 4b7fdeb64c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8587.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "SkullyRoberts"
-delete-after: True
-changes:
- - rscadd: "Penis autosurgeon as rare maint loot."
diff --git a/html/changelogs/AutoChangeLog-pr-8591.yml b/html/changelogs/AutoChangeLog-pr-8591.yml
deleted file mode 100644
index 09eb449899..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8591.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (Original PR by Vile Beggar)"
-delete-after: True
-changes:
- - rscadd: "Warden now has an added drill hat in his locker. You can change the loudness setting of it by using a screwdriver on it. Use wirecutters on it for a surprise."
diff --git a/html/changelogs/AutoChangeLog-pr-8599.yml b/html/changelogs/AutoChangeLog-pr-8599.yml
deleted file mode 100644
index 41134f4d5b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8599.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Pacifists can eat people for heal belly or noisy. Digestive modes are auto-swapped to noisy"
diff --git a/html/changelogs/AutoChangeLog-pr-8602.yml b/html/changelogs/AutoChangeLog-pr-8602.yml
deleted file mode 100644
index 4974c1ae79..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8602.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added an underwear toggle button under 'Object' tab"
- - tweak: "Genitals now layer under underwear. Hide these if they're too obnoxious."
diff --git a/html/changelogs/AutoChangeLog-pr-8605.yml b/html/changelogs/AutoChangeLog-pr-8605.yml
deleted file mode 100644
index c6a601f1ca..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8605.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Medical breifcaseses"
diff --git a/html/changelogs/AutoChangeLog-pr-8611.yml b/html/changelogs/AutoChangeLog-pr-8611.yml
deleted file mode 100644
index 8176d10a84..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8611.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added digitigrade socks of all known ones anyway."
diff --git a/html/changelogs/AutoChangeLog-pr-8614.yml b/html/changelogs/AutoChangeLog-pr-8614.yml
deleted file mode 100644
index e9473181fb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8614.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by SpaceManiac)"
-delete-after: True
-changes:
- - bugfix: "Disassembling a chem dispenser for the first time will no longer always yield a fully-charged cell."
diff --git a/html/changelogs/AutoChangeLog-pr-8618.yml b/html/changelogs/AutoChangeLog-pr-8618.yml
deleted file mode 100644
index 77ba2439a1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8618.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "New cargo crate for tech-slugs!"
- - rscadd: "Ammo to each fitting crate"
- - bugfix: "Cat-code"
- - spellcheck: "fixed a few typos - Again my bad"
diff --git a/html/changelogs/AutoChangeLog-pr-8623.yml b/html/changelogs/AutoChangeLog-pr-8623.yml
deleted file mode 100644
index 63f51b18eb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8623.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - rscadd: "The RD can now suplex a immovable rod. Good fucking luck."
diff --git a/html/changelogs/AutoChangeLog-pr-8624.yml b/html/changelogs/AutoChangeLog-pr-8624.yml
deleted file mode 100644
index 598ed9b457..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8624.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - bugfix: "Fixes high alert ERT suit sprites. You can see them now!"
diff --git a/html/changelogs/AutoChangeLog-pr-8632.yml b/html/changelogs/AutoChangeLog-pr-8632.yml
deleted file mode 100644
index b2f74869c2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8632.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - rscadd: "Traitor codewords are now highlighted for traitors."
diff --git a/html/changelogs/AutoChangeLog-pr-8633.yml b/html/changelogs/AutoChangeLog-pr-8633.yml
deleted file mode 100644
index 3cbc9a78aa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8633.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - rscadd: "You can now examine pumps filters and mixers to see if you can use CTRL and Alt click on them."
diff --git a/html/changelogs/AutoChangeLog-pr-8634.yml b/html/changelogs/AutoChangeLog-pr-8634.yml
deleted file mode 100644
index d351579640..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8634.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes power cells being unable to be rigged. Also prevents them from starting processing on init if they don't self recharge."
- - bugfix: "Fixes many, little or otherwise, issues with the stunbaton status refactor."
diff --git a/html/changelogs/AutoChangeLog-pr-8636.yml b/html/changelogs/AutoChangeLog-pr-8636.yml
deleted file mode 100644
index 3b291661b5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8636.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "fixed airless place"
diff --git a/html/changelogs/AutoChangeLog-pr-8639.yml b/html/changelogs/AutoChangeLog-pr-8639.yml
deleted file mode 100644
index f2f24d33ad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8639.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-author: "Useroth"
-delete-after: True
-changes:
- - tweak: "Makes the netting much less clunky. If there's only one target you can net while you press the
-button, it will just net that target instead of bringing up a list of mobs."
- - tweak: "Energy nets now revive and fully heal capturees (even dead ones, after calculating points). If someone's got a scan and wants to get cloned, they can always kill themselves still."
- - tweak: "Capture points are added on capture, rather than round-end, so it no longer matters whether your captures kill themselves in the holding facility or not."
- - balance: "Makes the nets a bit more sturdy. (previously it took mere two welder hits to break one)"
- - balance: "Makes stungloves actually stun people (currently comparably with stunbatons, adjustable). Because electrocute_act(25, H) did fuck all, stunwise, and on top of that, people in insulated gloves were completely unaffected."
- - balance: "Reduced the stunglove electrocute_act value to 15 due to above. Could possibly be lowered further."
diff --git a/html/changelogs/AutoChangeLog-pr-8640.yml b/html/changelogs/AutoChangeLog-pr-8640.yml
deleted file mode 100644
index b06feb4613..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8640.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "baklava"
diff --git a/html/changelogs/AutoChangeLog-pr-8643.yml b/html/changelogs/AutoChangeLog-pr-8643.yml
deleted file mode 100644
index b172071e2e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8643.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "The sacrificial target icon will now display onto the cult objective ui alert once again."
diff --git a/html/changelogs/AutoChangeLog-pr-8645.yml b/html/changelogs/AutoChangeLog-pr-8645.yml
deleted file mode 100644
index c299dcbbb5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8645.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Stopping borgs from sprinting into negative cell charge."
diff --git a/html/changelogs/AutoChangeLog-pr-8648.yml b/html/changelogs/AutoChangeLog-pr-8648.yml
deleted file mode 100644
index 8d0f9d20c8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8648.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - balance: "makes uplink kits more usefull for the risk"
diff --git a/html/changelogs/AutoChangeLog-pr-8649.yml b/html/changelogs/AutoChangeLog-pr-8649.yml
deleted file mode 100644
index c8f61cc24e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8649.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "The default amount of z-levels reserved specifically for space ruin generation has been increased from 1 to 2"
diff --git a/html/changelogs/AutoChangeLog-pr-8652.yml b/html/changelogs/AutoChangeLog-pr-8652.yml
deleted file mode 100644
index b788c5785c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8652.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (Original PR by Dennok)"
-delete-after: True
-changes:
- - bugfix: "Now areas_in_z get areas spawned by templates and blueprints."
diff --git a/html/changelogs/AutoChangeLog-pr-8658.yml b/html/changelogs/AutoChangeLog-pr-8658.yml
deleted file mode 100644
index ad35118c3f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8658.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "Moving some tablecrafting recipes to the appropriate categories: Kitty ears and lizard cloche hats to \"clothing\"; Hot dogs to \"Sandwichs\"; Cuban carb, fish and chips and fish fingers to \"Fish\"."
- - bugfix: "Fixes the not-a-sandwich recipe being M.I.A."
diff --git a/html/changelogs/AutoChangeLog-pr-8659.yml b/html/changelogs/AutoChangeLog-pr-8659.yml
deleted file mode 100644
index 6287f1307f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8659.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by ninjanomnom)"
-delete-after: True
-changes:
- - bugfix: "Orbiting is a little more aggressive about staying in orbit. The wisp as a result now correctly follows you over shuttle moves."
diff --git a/html/changelogs/AutoChangeLog-pr-8660.yml b/html/changelogs/AutoChangeLog-pr-8660.yml
deleted file mode 100644
index 710c4489ea..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8660.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - code_imp: "Changes some files to be better"
diff --git a/html/changelogs/AutoChangeLog-pr-8663.yml b/html/changelogs/AutoChangeLog-pr-8663.yml
deleted file mode 100644
index 3f5aeacd3c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8663.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Adding in peanuts, peanut butter, peanut butter toasts and sandwiches, and the PB&J sandwich.
-The peanuts contain a little bit of extractable cooking oil (similarly to soy beans) and can be microwaved or dried in a drying rack to make roasted peanuts, which can be mixed in a all-in-one-grinder for peanut butter, required to make those sandwiches."
diff --git a/html/changelogs/AutoChangeLog-pr-8665.yml b/html/changelogs/AutoChangeLog-pr-8665.yml
deleted file mode 100644
index fc34f9ac3e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8665.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "Buffed wizard and artificier's Magic Missile, wizard and xeno queen's Repulse and juggernaut's Gauntlet Echo."
diff --git a/html/changelogs/AutoChangeLog-pr-8666.yml b/html/changelogs/AutoChangeLog-pr-8666.yml
deleted file mode 100644
index df2e2e3af0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8666.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by YPOQ)"
-delete-after: True
-changes:
- - bugfix: "Fixing roffle waffle, mushroom halluginogen and some invalid reagents."
diff --git a/html/changelogs/AutoChangeLog-pr-8667.yml b/html/changelogs/AutoChangeLog-pr-8667.yml
deleted file mode 100644
index 1f80a2917d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8667.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by Anturk)"
-delete-after: True
-changes:
- - rscadd: "Recipe for fabled secret sauce can now be found in the deepest reaches of space."
diff --git a/html/changelogs/AutoChangeLog-pr-8669.yml b/html/changelogs/AutoChangeLog-pr-8669.yml
deleted file mode 100644
index 20770e8cc2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8669.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (original PRs by Denton and Skoglol)"
-delete-after: True
-changes:
- - tweak: "Reorganized the syndicate uplinks. Items are now mostly alphabetical, some misplaced items moved to more fitting categories. Bundles, random item and TC have been moved into a new category called \"Bundles and Telecrystals\". Gloves of the North Star and Box of Throwing Weapons have been moved to Conspicuous and Dangerous Weapons. Combat Gloves Plus have been moved to Stealthy and Inconspicuous Weapons. Moved all implants into the Implants category."
- - tweak: "Added a new category to the uplink: Grenades and Explosives."
diff --git a/html/changelogs/AutoChangeLog-pr-8671.yml b/html/changelogs/AutoChangeLog-pr-8671.yml
deleted file mode 100644
index bb01481d5c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8671.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by wesoda25)"
-delete-after: True
-changes:
- - balance: "disembowelment no longer works on mobs that aren't dead or in critical condition"
diff --git a/html/changelogs/AutoChangeLog-pr-8673.yml b/html/changelogs/AutoChangeLog-pr-8673.yml
deleted file mode 100644
index 6ff2c7135c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8673.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - balance: "As all things are not"
diff --git a/html/changelogs/AutoChangeLog-pr-8674.yml b/html/changelogs/AutoChangeLog-pr-8674.yml
deleted file mode 100644
index 3277946844..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8674.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "fixing cat code that dosnt work, my bad"
diff --git a/html/changelogs/AutoChangeLog-pr-8675.yml b/html/changelogs/AutoChangeLog-pr-8675.yml
deleted file mode 100644
index 170a44ca25..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8675.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "Arcades stealing from noodles"
diff --git a/html/changelogs/AutoChangeLog-pr-8676.yml b/html/changelogs/AutoChangeLog-pr-8676.yml
deleted file mode 100644
index e82a965985..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8676.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "rapier"
diff --git a/html/changelogs/AutoChangeLog-pr-8677.yml b/html/changelogs/AutoChangeLog-pr-8677.yml
deleted file mode 100644
index 181f6d2932..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8677.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "speedy quirk"
diff --git a/html/changelogs/AutoChangeLog-pr-8681.yml b/html/changelogs/AutoChangeLog-pr-8681.yml
deleted file mode 100644
index 1cd5f04124..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8681.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (Original PRs by Tortellini Tony and BuffEngineering)"
-delete-after: True
-changes:
- - bugfix: "E-cigs will continue to display their setting after being emagged."
- - bugfix: "Vapes now come out of the mouth.
-fix Fixes an E-cig initialize() runtime."
diff --git a/html/changelogs/AutoChangeLog-pr-8687.yml b/html/changelogs/AutoChangeLog-pr-8687.yml
deleted file mode 100644
index 65347093ef..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8687.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by monster860)"
-delete-after: True
-changes:
- - bugfix: "fixes advanced proccall"
diff --git a/html/changelogs/AutoChangeLog-pr-8688.yml b/html/changelogs/AutoChangeLog-pr-8688.yml
deleted file mode 100644
index b22c2c52fd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8688.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (Original PR by nemvar)"
-delete-after: True
-changes:
- - rscadd: "Botanists can now get beeplushies (or cultivator and bucket) as an heirloom."
- - bugfix: "Clowns and mimes will now properly pick either a can of paint or their brand as heirloom now."
diff --git a/html/changelogs/AutoChangeLog-pr-8689.yml b/html/changelogs/AutoChangeLog-pr-8689.yml
deleted file mode 100644
index bf44770c76..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8689.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - rscadd: "Added a panda simplemob"
diff --git a/html/changelogs/AutoChangeLog-pr-8690.yml b/html/changelogs/AutoChangeLog-pr-8690.yml
deleted file mode 100644
index 3ac76333a2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8690.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - bugfix: "fixes empathy exploit."
diff --git a/html/changelogs/AutoChangeLog-pr-8691.yml b/html/changelogs/AutoChangeLog-pr-8691.yml
deleted file mode 100644
index 680904cc5c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8691.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (Original PRs by nemvar and Rowell)"
-delete-after: True
-changes:
- - rscadd: "Added beekini bras and panties, thigh-high and knee-high bee socks."
diff --git a/html/changelogs/AutoChangeLog-pr-8692.yml b/html/changelogs/AutoChangeLog-pr-8692.yml
deleted file mode 100644
index f1d87676ab..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8692.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Ghommie (original PRs by ShizCalev)"
-delete-after: True
-changes:
- - bugfix: "Fixed a bug that allowed you to teleport an ID in your possession to a PDA anywhere ingame."
- - bugfix: "Fixed an exploit allowing you to steal ID's/pens from PDA's not in your possession."
- - bugfix: "Fixed an exploit allowing you unlimited control of a PDA's interface even if it wasn't near you/in your possession."
- - bugfix: "Fixed Pride Mirror exploits."
diff --git a/html/changelogs/AutoChangeLog-pr-8693.yml b/html/changelogs/AutoChangeLog-pr-8693.yml
deleted file mode 100644
index 1e5e3fda58..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8693.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by Tlaltecuhtli)"
-delete-after: True
-changes:
- - bugfix: "Other people's clothes burning no longer spam you"
diff --git a/html/changelogs/AutoChangeLog-pr-8695.yml b/html/changelogs/AutoChangeLog-pr-8695.yml
deleted file mode 100644
index 671eaa519e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8695.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PRs by grandpawalton and Mickyan)"
-delete-after: True
-changes:
- - tweak: "the contents on the smartfridge icon now change depending on how many items it contains"
- - bugfix: "opening the maintenance panel of smartfridges now correctly updates the icon"
- - bugfix: "Screwing a disk compartmentalizer no longer makes it look like a smartfridge."
diff --git a/html/changelogs/AutoChangeLog-pr-8698.yml b/html/changelogs/AutoChangeLog-pr-8698.yml
deleted file mode 100644
index 464f74427e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8698.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes flashlights being unable to be used for rudimentary eyes and mouth exams."
diff --git a/html/changelogs/AutoChangeLog-pr-8708.yml b/html/changelogs/AutoChangeLog-pr-8708.yml
deleted file mode 100644
index 0929c2ee6c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8708.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - spellcheck: "Ironic"
diff --git a/html/changelogs/AutoChangeLog-pr-8709.yml b/html/changelogs/AutoChangeLog-pr-8709.yml
deleted file mode 100644
index 4aa6fd9b1d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8709.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "A bunch of minor issues with xenobiology are no more!"
diff --git a/html/changelogs/AutoChangeLog-pr-8711.yml b/html/changelogs/AutoChangeLog-pr-8711.yml
deleted file mode 100644
index f836783659..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8711.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Adds in a grey jumpsuit to the loadout choices, restricted to Assistants."
diff --git a/html/changelogs/AutoChangeLog-pr-8715.yml b/html/changelogs/AutoChangeLog-pr-8715.yml
deleted file mode 100644
index b99309cdd9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8715.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "Pentetic Jelly, new chemical made through mixing 1:1 slime jelly and pentetic acid."
- - tweak: "Anatomic panacea now gives pent jelly instead of pent acid. Medbeams now have TRUE tox healing to heal TOXINLOVER as well."
diff --git a/html/changelogs/AutoChangeLog-pr-8718.yml b/html/changelogs/AutoChangeLog-pr-8718.yml
deleted file mode 100644
index 102fbd4f23..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8718.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - rscadd: "ability to quickly max sensors"
diff --git a/html/changelogs/AutoChangeLog-pr-8720.yml b/html/changelogs/AutoChangeLog-pr-8720.yml
deleted file mode 100644
index 81684baeac..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8720.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (Credits to Kmc2000 for the original PR)"
-delete-after: True
-changes:
- - rscadd: "Porting in MRE boxes from Yogstation. But be careful, eating possibly expired MREs found in maintenance comes with an unrealistically large (actually small) chance of food poisoning. Otherwise just bail out and order actually safe-to-eat MREs from cargo for 2000 credits."
diff --git a/html/changelogs/AutoChangeLog-pr-8721.yml b/html/changelogs/AutoChangeLog-pr-8721.yml
deleted file mode 100644
index 4b616e9923..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8721.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by XDTM)"
-delete-after: True
-changes:
- - bugfix: "Reagents now stop their passive effects (for example, stun immunity) if the liver stops working while they're active."
diff --git a/html/changelogs/AutoChangeLog-pr-8722.yml b/html/changelogs/AutoChangeLog-pr-8722.yml
deleted file mode 100644
index fe858768af..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8722.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "I didn't code it right it in the first place"
diff --git a/html/changelogs/AutoChangeLog-pr-8724.yml b/html/changelogs/AutoChangeLog-pr-8724.yml
deleted file mode 100644
index 5fc86dd9c9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8724.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "new nodes"
- - balance: "points and node gear"
diff --git a/html/changelogs/AutoChangeLog-pr-8725.yml b/html/changelogs/AutoChangeLog-pr-8725.yml
deleted file mode 100644
index d42840ef0a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8725.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "stuff n things"
diff --git a/html/changelogs/AutoChangeLog-pr-8726.yml b/html/changelogs/AutoChangeLog-pr-8726.yml
deleted file mode 100644
index 49da4299ce..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8726.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - balance: "Changed bible heal proc, halving the healed damage and increasing brain damage 5x in exchange for a much wider array of items to protect you from it."
diff --git a/html/changelogs/AutoChangeLog-pr-8727.yml b/html/changelogs/AutoChangeLog-pr-8727.yml
deleted file mode 100644
index b1ca5f0d51..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8727.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (original PRs by Jujumatic and PKPenguin321, respectively)"
-delete-after: True
-changes:
- - rscadd: "Minesweeper Arcade machines. The higher the difficulty setting, the better the prizes will be."
- - rscadd: "Also keep your eye out for another new (and rare) arcade game!"
diff --git a/html/changelogs/AutoChangeLog-pr-8728.yml b/html/changelogs/AutoChangeLog-pr-8728.yml
deleted file mode 100644
index 2e860e737f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8728.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - tweak: "Moved around some chems from emag list into upgrades."
- - balance: "Added some fun chems to dispensers."
- - bugfix: "Gave dispensers old tg functionality."
diff --git a/html/changelogs/AutoChangeLog-pr-8729.yml b/html/changelogs/AutoChangeLog-pr-8729.yml
deleted file mode 100644
index a72f624352..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8729.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by AffectedArc07)"
-delete-after: True
-changes:
- - tweak: "Religion is now a globalvar instead of being a subsystem for some reason"
diff --git a/html/changelogs/AutoChangeLog-pr-8730.yml b/html/changelogs/AutoChangeLog-pr-8730.yml
deleted file mode 100644
index d0204f2830..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8730.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PRs by Tlaltecuhtli and nicbn)"
-delete-after: True
-changes:
- - rscadd: "alt click to eject beakers from chem masters + chem dispensers + grinders + chem heaters"
- - rscadd: "hit chem master + chem dispenser + chem heaters with a beaker and if its loaded with another it swaps em"
- - rscadd: "All-In-One Blender UI uses a radial menu now. You can see the contents and reagents by examining."
diff --git a/html/changelogs/AutoChangeLog-pr-8731.yml b/html/changelogs/AutoChangeLog-pr-8731.yml
deleted file mode 100644
index 0728c12124..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8731.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Ghommie (original PRs by nicbn and coiax)"
-delete-after: True
-changes:
- - rscadd: "Microwave UI uses a radial menu now. You can see the contents by examining."
- - rscadd: "Microwaves have a single wire accessible when open, the activation wire.
-When cut, the microwave will no longer function, when pulsed, the microwave
-will turn on."
- - rscadd: "Stabilized dark purple extracts now cook items in your hands, rather than dropping
-the cooked item on the floor."
diff --git a/html/changelogs/AutoChangeLog-pr-8732.yml b/html/changelogs/AutoChangeLog-pr-8732.yml
deleted file mode 100644
index 69a79b93ac..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8732.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by Nicjh)"
-delete-after: True
-changes:
- - rscadd: "Abductor console's select disguise option now uses a radial"
diff --git a/html/changelogs/AutoChangeLog-pr-8733.yml b/html/changelogs/AutoChangeLog-pr-8733.yml
deleted file mode 100644
index 593c06bd90..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8733.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by Swindly)"
-delete-after: True
-changes:
- - rscadd: "Arm-mounted implants that contain more than one item use a radial menu instead of a list menu."
diff --git a/html/changelogs/AutoChangeLog-pr-8734.yml b/html/changelogs/AutoChangeLog-pr-8734.yml
deleted file mode 100644
index 4f746c4cd5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8734.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (original PR by coiax)"
-delete-after: True
-changes:
- - code_imp: "Randomly coloured gloves and randomly coloured glowsticks now have
-slightly different typepaths, but otherwise function the same."
diff --git a/html/changelogs/AutoChangeLog-pr-8736.yml b/html/changelogs/AutoChangeLog-pr-8736.yml
deleted file mode 100644
index 68d64e2410..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8736.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "gear harness and a conflict merg"
- - rscdel: "Nudity permits"
- - bugfix: "nothing"
diff --git a/html/changelogs/AutoChangeLog-pr-8737.yml b/html/changelogs/AutoChangeLog-pr-8737.yml
deleted file mode 100644
index d8e868df33..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8737.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes CWC construct shells being visible as ghost role to latejoiners."
diff --git a/html/changelogs/AutoChangeLog-pr-8738.yml b/html/changelogs/AutoChangeLog-pr-8738.yml
deleted file mode 100644
index f0e48a77b5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8738.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by ShizCalev)"
-delete-after: True
-changes:
- - bugfix: "Pineapple haters/lovers will get/no longer get pineapple pizzas respectively from infinite pizza boxes."
diff --git a/html/changelogs/AutoChangeLog-pr-8739.yml b/html/changelogs/AutoChangeLog-pr-8739.yml
deleted file mode 100644
index 0c25a1a649..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8739.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "Leather, cardboard, bronze & bone golems!"
- - rscadd: "Bone hurting juice and interactions with plasmamen, skeletons & bone golems!"
diff --git a/html/changelogs/AutoChangeLog-pr-8740.yml b/html/changelogs/AutoChangeLog-pr-8740.yml
deleted file mode 100644
index 1966f34331..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8740.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (original PR by Denton)"
-delete-after: True
-changes:
- - tweak: "Nanotrasen has started shipping more types of bedsheets to its stations."
- - rscadd: "Added in Runtime, Pirate and Gondola bedsheets. The second one can also be found in some pirate ships, while the last can be crafted from gondola hides."
diff --git a/html/changelogs/AutoChangeLog-pr-8741.yml b/html/changelogs/AutoChangeLog-pr-8741.yml
deleted file mode 100644
index be803933ae..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8741.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by AffectedArc07 and Shazbot)"
-delete-after: True
-changes:
- - imageadd: "Added 8 new sock styles"
diff --git a/html/changelogs/AutoChangeLog-pr-8742.yml b/html/changelogs/AutoChangeLog-pr-8742.yml
deleted file mode 100644
index 03428fc8d1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8742.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Donner item"
diff --git a/html/changelogs/AutoChangeLog-pr-8744.yml b/html/changelogs/AutoChangeLog-pr-8744.yml
deleted file mode 100644
index 2979a4a842..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8744.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - bugfix: "atmos helmet visual bug"
diff --git a/html/changelogs/AutoChangeLog-pr-8745.yml b/html/changelogs/AutoChangeLog-pr-8745.yml
deleted file mode 100644
index 6feaa2eadd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8745.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "Ported addition of new CAS cards."
- - bugfix: "Ported a fix for CAS."
diff --git a/html/changelogs/AutoChangeLog-pr-8747.yml b/html/changelogs/AutoChangeLog-pr-8747.yml
deleted file mode 100644
index c8a4689c60..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8747.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Luna's Gauntlets"
diff --git a/html/changelogs/AutoChangeLog-pr-8750.yml b/html/changelogs/AutoChangeLog-pr-8750.yml
deleted file mode 100644
index a3ff5e8a91..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8750.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - bugfix: "Fixes brain damage/trauma healing nanites so they actually work while there are only traumas."
diff --git a/html/changelogs/AutoChangeLog-pr-8752.yml b/html/changelogs/AutoChangeLog-pr-8752.yml
deleted file mode 100644
index 243b9695a8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8752.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "Added the ability to alter your genitalia as a slimeperson more than addition/removal."
- - bugfix: "fixed genitalia removal proc in alter form."
diff --git a/html/changelogs/AutoChangeLog-pr-8753.yml b/html/changelogs/AutoChangeLog-pr-8753.yml
deleted file mode 100644
index 04fd009e2f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8753.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - balance: "Ported the inability for non-station AI to interact with station z-level."
diff --git a/html/changelogs/AutoChangeLog-pr-8755.yml b/html/changelogs/AutoChangeLog-pr-8755.yml
deleted file mode 100644
index a1c4742802..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8755.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - tweak: "tweaked the Genital character creation layout to look better"
- - bugfix: "fixed having balls/womb when you don't have the linked organ at character creation"
- - bugfix: "fixed being able to squeeze semen directly from your balls. Probably."
diff --git a/html/changelogs/AutoChangeLog-pr-8756.yml b/html/changelogs/AutoChangeLog-pr-8756.yml
deleted file mode 100644
index 8d78c6d5e8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8756.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - balance: "HoS mains can now peacefully sleep in their office."
diff --git a/html/changelogs/AutoChangeLog-pr-8760.yml b/html/changelogs/AutoChangeLog-pr-8760.yml
deleted file mode 100644
index 78812c5c05..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8760.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - balance: "rebalanced lingy dingy powery gamey"
diff --git a/html/changelogs/AutoChangeLog-pr-8761.yml b/html/changelogs/AutoChangeLog-pr-8761.yml
deleted file mode 100644
index 4ee792c3a6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8761.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "melee and block harm"
- - bugfix: "sprites*"
diff --git a/html/changelogs/AutoChangeLog-pr-8762.yml b/html/changelogs/AutoChangeLog-pr-8762.yml
deleted file mode 100644
index e248589b1b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8762.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - imageadd: "new sprites for the flechette gun, its magazines and the toy ray gun"
diff --git a/html/changelogs/AutoChangeLog-pr-8763.yml b/html/changelogs/AutoChangeLog-pr-8763.yml
deleted file mode 100644
index d99b529656..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8763.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - balance: "bone satchles"
diff --git a/html/changelogs/AutoChangeLog-pr-8764.yml b/html/changelogs/AutoChangeLog-pr-8764.yml
deleted file mode 100644
index ad5b82505a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8764.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "holster doing holster things"
diff --git a/html/changelogs/AutoChangeLog-pr-8765.yml b/html/changelogs/AutoChangeLog-pr-8765.yml
deleted file mode 100644
index 2cac0773ad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8765.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "Merges the end-of-shift and its shuttle autocall announcements into one."
- - bugfix: "Prevents the end-of-shift shuttle from being recalled (even if to no avail)."
diff --git a/html/changelogs/AutoChangeLog-pr-8766.yml b/html/changelogs/AutoChangeLog-pr-8766.yml
deleted file mode 100644
index 33c2a47a71..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8766.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes being able to teleport papers to your location with TK."
diff --git a/html/changelogs/AutoChangeLog-pr-8767.yml b/html/changelogs/AutoChangeLog-pr-8767.yml
deleted file mode 100644
index ce01bf471b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8767.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed some monkey-code shenanigeans making items sometimes disappear from pickpocketing."
diff --git a/html/changelogs/AutoChangeLog-pr-8768.yml b/html/changelogs/AutoChangeLog-pr-8768.yml
deleted file mode 100644
index de8338b545..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8768.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - imageadd: "New sprites for the some pda cartridges."
diff --git a/html/changelogs/AutoChangeLog-pr-8773.yml b/html/changelogs/AutoChangeLog-pr-8773.yml
deleted file mode 100644
index 6cc39f8184..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8773.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - tweak: "Podpeople now have customization options."
diff --git a/html/changelogs/AutoChangeLog-pr-8774.yml b/html/changelogs/AutoChangeLog-pr-8774.yml
deleted file mode 100644
index 7ba01cc6aa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8774.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - bugfix: "Removed the human check for cult conversion of captain/chaplain minds."
diff --git a/html/changelogs/AutoChangeLog-pr-8775.yml b/html/changelogs/AutoChangeLog-pr-8775.yml
deleted file mode 100644
index 51e8a15b13..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8775.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "The crew monitor's entry for the Quartermaster will now appear bolded, while HoP's will be of the same color of the service/unknown/other jobs."
diff --git a/html/changelogs/AutoChangeLog-pr-8776.yml b/html/changelogs/AutoChangeLog-pr-8776.yml
deleted file mode 100644
index bd3d30677a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8776.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-author: "Ghommie (original PRs by ShizCalev, coiax and Tlaltecuhtli)"
-delete-after: True
-changes:
- - bugfix: "Caks will no longer override the bonus reagents provided in a donut when frosting them."
- - bugfix: "Caks can no longer create frosted frosted jelly donuts."
- - bugfix: "Jelly donuts will no longer lose their vitamins when they're frosted."
- - bugfix: "Fixed chaos donuts potentially doubling the amount of reagents added when microwaved with something else."
- - bugfix: "Donuts now always contain 1 sprinkles as was stated on the wiki. Frosted donuts have a chance at adding an extra sprinkle."
- - code_imp: "Improved the code for ensuring that security members enjoy donuts and security-themed alcoholic drinks."
- - balance: "neurotoxin doesnt insta stun but gives you limb paralysis overtime and heart attacks if it stays in for too long and it is also alcholic"
- - balance: "beepsky smash now summons imaginary beepskys that deal stamina damage instead of outright stunning"
diff --git a/html/changelogs/AutoChangeLog-pr-8778.yml b/html/changelogs/AutoChangeLog-pr-8778.yml
deleted file mode 100644
index 1fa8446e6a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8778.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-author: "Ghommie (original PRs by carshalash, GranpaWalton, BebeYoshi & Hexmaniacosanna, Fire Chance, Ordonis, Krysonism and OnlineGirlfriend)"
-delete-after: True
-changes:
- - tweak: "Reduced booze power of Mead, Red Mead, and Irish Cream."
- - tweak: "Increased booze power of Grappa."
- - rscadd: "Added a new premium drink to the soda machine called \"Grey Bull\" which gives temporary shock resistance"
- - rscadd: "A new drink called Blank Paper was added to the bar menu, it was made by a mime and it represents a new start."
- - rscadd: "Adds a variety of fine alcoholic beverages for discerning patrons of the bar: Wizz Fizz, Bug Spray, Champagne, Applejack, Jack Rose, Turbo, Old Timer, Rubberneck, Duplex, Trappist Beer, Blazaam and Planet Cracker!"
- - rscadd: "Also more nonalcoholic drinks: Cream Soda, Lemonade and Red Queen."
- - rscadd: "Packs of a novel artificial sweetener have been added to the kitchen vendor."
- - rscadd: "Bottles of trappist beer and champagne are now available in the premium seection of the booze-o-mat."
- - rscadd: "Juicing parsnips now yields parsnip juice."
- - rscadd: "Maintenance peaches."
- - bugfix: "Grape soda now cools you down like other sodas."
- - tweak: "tweaked the Arnold Palmer recipe, it now uses lemonade."
- - imageadd: "Added new drink, bottle, vomit and peach can sprites."
diff --git a/html/changelogs/AutoChangeLog-pr-8779.yml b/html/changelogs/AutoChangeLog-pr-8779.yml
deleted file mode 100644
index b5e90f7ecb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8779.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - balance: "Roundstart carbon jetpacks now have full_speed FALSE."
diff --git a/html/changelogs/AutoChangeLog-pr-8781.yml b/html/changelogs/AutoChangeLog-pr-8781.yml
deleted file mode 100644
index 12bd5ccdf0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8781.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - tweak: "Adds plasteel to medical and security techfabs."
diff --git a/html/changelogs/AutoChangeLog-pr-8783.yml b/html/changelogs/AutoChangeLog-pr-8783.yml
deleted file mode 100644
index 5b283b9b21..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8783.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "emergency pods' storage will now properly work."
diff --git a/html/changelogs/AutoChangeLog-pr-8784.yml b/html/changelogs/AutoChangeLog-pr-8784.yml
deleted file mode 100644
index 7d6d9d4739..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8784.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Donor item"
diff --git a/html/changelogs/AutoChangeLog-pr-8785.yml b/html/changelogs/AutoChangeLog-pr-8785.yml
deleted file mode 100644
index 0dd9cb0df4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8785.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Joy, Happiness, Honk"
diff --git a/html/changelogs/AutoChangeLog-pr-8790.yml b/html/changelogs/AutoChangeLog-pr-8790.yml
deleted file mode 100644
index 0c0e6cd116..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8790.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - rscadd: "It's now possible to forcefully eject the occupants of a dogborg's sleeper by using a crowbar on them. This action is instant."
- - tweak: "Resist values for dogborg sleepers have been adjusted. The baseline has been decreased from 30 seconds to 15 seconds. Medihound sleepers have a resist timer of 3 seconds. Sechound sleepers retain a resist timer of 30 seconds."
- - tweak: "It now takes 10 full seconds to insert people into your sleeper. This should hopefully give people some more room to breathe and react to a dogborg attempting to sleeper someone either for no reason or in a way that violates law 2."
diff --git a/html/changelogs/AutoChangeLog-pr-8793.yml b/html/changelogs/AutoChangeLog-pr-8793.yml
deleted file mode 100644
index 82a113c94d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8793.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "The PDA skin preference will now properly save up."
- - tweak: "Changed the default PDA icon var to match the default PDA skin preference."
diff --git a/html/changelogs/AutoChangeLog-pr-8794.yml b/html/changelogs/AutoChangeLog-pr-8794.yml
deleted file mode 100644
index 612a3e655b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8794.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixing the `(pointless) badassary` category appearing between the `dangerous and conspicious` and `stealthy and inconspicious` categories."
- - bugfix: "Combat gloves plus now properly use the combat gloves sprite."
diff --git a/html/changelogs/AutoChangeLog-pr-8795.yml b/html/changelogs/AutoChangeLog-pr-8795.yml
deleted file mode 100644
index 7fe2250a0b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8795.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Sishen1542, original by @zxaber"
-delete-after: True
-changes:
- - balance: "Utility mechs no longer automatically get beacons."
- - balance: "Tracking beacons no longer delete themselves when EMPing a mech, and instead have a ten-second cooldown in-between EMPs. They also now do heavy EMP damage rather than light."
- - balance: "Mechs that take EMP damage lose the use of their weapons and equipment temporarily. Movement and abilities are not effected."
- - balance: "Mechs taking EMP damage no longer roll for a random malfunction."
diff --git a/html/changelogs/AutoChangeLog-pr-8796.yml b/html/changelogs/AutoChangeLog-pr-8796.yml
deleted file mode 100644
index 2ffdee9b37..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8796.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "small mix up in terms"
diff --git a/html/changelogs/AutoChangeLog-pr-8797.yml b/html/changelogs/AutoChangeLog-pr-8797.yml
deleted file mode 100644
index 40c7afc570..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8797.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542, original by @Tlaltecuhtli"
-delete-after: True
-changes:
- - bugfix: "alt clicking the emitter now rotates it instead of only flipping"
diff --git a/html/changelogs/AutoChangeLog-pr-8798.yml b/html/changelogs/AutoChangeLog-pr-8798.yml
deleted file mode 100644
index 367aadad80..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8798.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542, original by Arkatos"
-delete-after: True
-changes:
- - rscadd: "Action buttons can now be dragged onto each other to swap places"
diff --git a/html/changelogs/AutoChangeLog-pr-8799.yml b/html/changelogs/AutoChangeLog-pr-8799.yml
deleted file mode 100644
index 73d3f590ba..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8799.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Promiscuous Organs crate, pills to lewd crate and testicles to maints"
diff --git a/html/changelogs/AutoChangeLog-pr-8800.yml b/html/changelogs/AutoChangeLog-pr-8800.yml
deleted file mode 100644
index 7b397ec23e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8800.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542, original by Skoglol"
-delete-after: True
-changes:
- - rscadd: "Heaters/freezers now support ctrl clicking to turn on and alt clicking to min/max target temperature."
diff --git a/html/changelogs/AutoChangeLog-pr-8801.yml b/html/changelogs/AutoChangeLog-pr-8801.yml
deleted file mode 100644
index e1089f2f1d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8801.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542, original by NewSta"
-delete-after: True
-changes:
- - tweak: "updated the miasma canister sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-8802.yml b/html/changelogs/AutoChangeLog-pr-8802.yml
deleted file mode 100644
index b97119c32d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8802.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PRs by ShizCalev, MrDoombringer, AnturK, bgobandit, 81Denton and actioninja)"
-delete-after: True
-changes:
- - rscadd: "Failsafe codes for uplinks are now available for purchase."
- - rscadd: "Nuke Ops now have the ability to purchase a usable RPG, the PML-9, as well as a couple different types of rockets for it. you can also suicide rocket jump with them!"
- - spellcheck: "Improved Uplink item descriptions and formatting."
diff --git a/html/changelogs/AutoChangeLog-pr-8805.yml b/html/changelogs/AutoChangeLog-pr-8805.yml
deleted file mode 100644
index 8abefd9ce2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8805.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - bugfix: "supply display are now properly on the wall"
diff --git a/html/changelogs/AutoChangeLog-pr-8812.yml b/html/changelogs/AutoChangeLog-pr-8812.yml
deleted file mode 100644
index 0de67cfe59..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8812.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542, original by XDTM"
-delete-after: True
-changes:
- - rscadd: "Using the wrong surgery tool during surgery no longer attacks the patient, if on help or disarm intent."
diff --git a/html/changelogs/AutoChangeLog-pr-8819.yml b/html/changelogs/AutoChangeLog-pr-8819.yml
deleted file mode 100644
index 0b750fccb6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8819.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "Added public autolathes to all maps."
diff --git a/html/changelogs/AutoChangeLog-pr-8820.yml b/html/changelogs/AutoChangeLog-pr-8820.yml
deleted file mode 100644
index 3e83e29cc3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8820.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by variableundefined)"
-delete-after: True
-changes:
- - bugfix: "Cancel button to assault pod destination selector."
diff --git a/html/changelogs/AutoChangeLog-pr-8821.yml b/html/changelogs/AutoChangeLog-pr-8821.yml
deleted file mode 100644
index f45caba949..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8821.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Ghommie (original PRs by ShizCalev)"
-delete-after: True
-changes:
- - tweak: "Corgi collars can now be removed!"
- - tweak: "Updated the corgi & parrot inventory panels to use the same formatting as other mobs"
- - bugfix: "Fixed corgi inventory panels not closing properly."
- - bugfix: "Fixed the parrot inventory panel not closing properly if you're not able to interact with it."
diff --git a/html/changelogs/AutoChangeLog-pr-8823.yml b/html/changelogs/AutoChangeLog-pr-8823.yml
deleted file mode 100644
index b334bfbd7e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8823.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (Original PR by tralezab)"
-delete-after: True
-changes:
- - bugfix: "Fixes an issue with spontaneous appendicitis picking incompatible mob biotypes."
diff --git a/html/changelogs/AutoChangeLog-pr-8824.yml b/html/changelogs/AutoChangeLog-pr-8824.yml
deleted file mode 100644
index 6a12573112..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8824.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by Mickyan)"
-delete-after: True
-changes:
- - bugfix: "Fixed being unable to smother people using the damp rag"
diff --git a/html/changelogs/AutoChangeLog-pr-8825.yml b/html/changelogs/AutoChangeLog-pr-8825.yml
deleted file mode 100644
index a56be4e2ab..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8825.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PR by MrDoomBringer, AnturK and YPOQ)"
-delete-after: True
-changes:
- - bugfix: "Explosions will no longer damage wizards in rod form, the supermatter monitoring radio and megafauna GPS."
- - bugfix: "Supplypods no longer detonate their contents."
- - bugfix: "Fixed silicon items (e.g. cyborg modules) being destroyed by explosion epicenters."
diff --git a/html/changelogs/AutoChangeLog-pr-8826.yml b/html/changelogs/AutoChangeLog-pr-8826.yml
deleted file mode 100644
index 3f7520b84e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8826.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Ghommie (original PR by Skoglol)"
-delete-after: True
-changes:
- - code_imp: "New helper proc for alt-click turf listing, bypasses any interaction overrides."
- - code_imp: "Ghosts and revenants now use the new proc."
- - bugfix: "Ghosts can no longer toggleopen sleepers, adjust skateboard speed or close laptops"
- - bugfix: "Revenant can now alt-click turf to list contents."
- - tweak: "Revenant now slightly less nosy, use shift click to examine."
- - tweak: "Alt-clicking the same turf again no longer closes the turf listing tab."
diff --git a/html/changelogs/AutoChangeLog-pr-8827.yml b/html/changelogs/AutoChangeLog-pr-8827.yml
deleted file mode 100644
index e1aaadd698..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8827.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by ninjanomnom)"
-delete-after: True
-changes:
- - bugfix: "Gaps between sounds in some looping sound effects should no longer happen as much under heavy server lag."
diff --git a/html/changelogs/AutoChangeLog-pr-8828.yml b/html/changelogs/AutoChangeLog-pr-8828.yml
deleted file mode 100644
index 4278a14ae1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8828.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by Skoglol)"
-delete-after: True
-changes:
- - bugfix: "Reduced ventcrawl lag greatly."
diff --git a/html/changelogs/AutoChangeLog-pr-8829.yml b/html/changelogs/AutoChangeLog-pr-8829.yml
deleted file mode 100644
index 6d0dd108dd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8829.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "BurgerLUA"
-delete-after: True
-changes:
- - code_imp: "Added a new framework for reagents. Reagents can now have a bool that determines if it can be detected by handheld medical analyzers. Currently only the changeling sting chemical does this."
- - balance: "Made changeling transformation string last between 10-15 minutes. Lowered the dna cost of changeling sting from 3 dna to 2 dna. Lowered the chemical cost from 50 to 10. Lowered the loudness from 2 to 1. Changeling sting transformation can be removed via high doses of calomel."
diff --git a/html/changelogs/AutoChangeLog-pr-8830.yml b/html/changelogs/AutoChangeLog-pr-8830.yml
deleted file mode 100644
index e4cb94374b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8830.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PRs by Kmc2000 and actioninja)"
-delete-after: True
-changes:
- - rscadd: "Added darkmode! You can opt-in to this by clicking the new toggle darkmode button just beside the settings one."
- - rscadd: "Byond members will now have a new setting for their Antag OOC color, instead of using their OOC one. (Antag OOC still locked under admin discretion though)"
- - rscdel: "Default black'n'white windows style."
diff --git a/html/changelogs/AutoChangeLog-pr-8834.yml b/html/changelogs/AutoChangeLog-pr-8834.yml
deleted file mode 100644
index 0b7a7b30c5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8834.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes the space ninja's energy netting."
diff --git a/html/changelogs/AutoChangeLog-pr-8835.yml b/html/changelogs/AutoChangeLog-pr-8835.yml
deleted file mode 100644
index cf646b879b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8835.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - tweak: "consistency in hop and cap berets"
diff --git a/html/changelogs/AutoChangeLog-pr-8841.yml b/html/changelogs/AutoChangeLog-pr-8841.yml
deleted file mode 100644
index 8bb73dac26..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8841.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Adding one pAI to the wizard shuttle and ERT prep room"
diff --git a/html/changelogs/AutoChangeLog-pr-8842.yml b/html/changelogs/AutoChangeLog-pr-8842.yml
deleted file mode 100644
index 8a8903b7e5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8842.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "UristMcAstronaut"
-delete-after: True
-changes:
- - bugfix: "allows a pai to activate its holoform while in a pai connector without getting derped."
diff --git a/html/changelogs/AutoChangeLog-pr-8843.yml b/html/changelogs/AutoChangeLog-pr-8843.yml
deleted file mode 100644
index 74a3cc07e8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8843.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Coolgat3"
-delete-after: True
-changes:
- - imageadd: "added combat boots sprite"
diff --git a/html/changelogs/AutoChangeLog-pr-8844.yml b/html/changelogs/AutoChangeLog-pr-8844.yml
deleted file mode 100644
index 05f0f2fb22..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8844.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes the rocket launcher being unreloadable."
- - balance: "Buffed its accuracy a bit."
- - tweak: "Replaced the grenade launcher emagged minesweeper loot with the rocket launcher like it was originally supposed to be."
diff --git a/html/changelogs/AutoChangeLog-pr-8845.yml b/html/changelogs/AutoChangeLog-pr-8845.yml
deleted file mode 100644
index 4fe0319fad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8845.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - imageadd: "Tweaked the :b: emoji."
diff --git a/html/changelogs/AutoChangeLog-pr-8846.yml b/html/changelogs/AutoChangeLog-pr-8846.yml
deleted file mode 100644
index 26b1dad6d5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8846.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Rubber Toolboxes."
diff --git a/html/changelogs/AutoChangeLog-pr-8847.yml b/html/changelogs/AutoChangeLog-pr-8847.yml
deleted file mode 100644
index 678b3d433b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8847.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Porting in two bar signs: Cyber Sylph's and Meow Mix."
diff --git a/html/changelogs/AutoChangeLog-pr-8852.yml b/html/changelogs/AutoChangeLog-pr-8852.yml
deleted file mode 100644
index 4d49f26831..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8852.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - imagedel: "Removes a moth plush from the game."
diff --git a/html/changelogs/AutoChangeLog-pr-8853.yml b/html/changelogs/AutoChangeLog-pr-8853.yml
deleted file mode 100644
index 1507e8620d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8853.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PRs by Naksu and coiax, loser)"
-delete-after: True
-changes:
- - code_imp: "Cleaned up saycode"
- - bugfix: "Taking mutadone while having the communication disorder brain trauma will no longer spam your chat with messages."
- - rscadd: "IPCs now come with a subtype of robotic tongue without the omnilingual ability, instead of innately having robotic voice spans."
diff --git a/html/changelogs/AutoChangeLog-pr-8854.yml b/html/changelogs/AutoChangeLog-pr-8854.yml
deleted file mode 100644
index fc45d2087e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8854.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixing stamina damage melee weaponry being unusable by pacifists, and still damaging objects and triggering electrified grilles when thrown."
diff --git a/html/changelogs/AutoChangeLog-pr-8857.yml b/html/changelogs/AutoChangeLog-pr-8857.yml
deleted file mode 100644
index 6e32fff883..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8857.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - refactor: "refactored underwears to allow custom color preferences, instead of manually colored sprites."
- - rscdel: "The aforementioned manually colored pieces. Some of your char preferences may have been resetted as result."
- - rscadd: "More underwear choices, including: Bowling shirts, long johns, a tank top, fishnets, more bee socks, bee t-shirt and bee boxers (original PR for the latter three by nemvar from /tg/station)."
- - tweak: "random bodies will now have random underwear again."
- - bugfix: "Dressers will now properly change undergarment again."
diff --git a/html/changelogs/AutoChangeLog-pr-8858.yml b/html/changelogs/AutoChangeLog-pr-8858.yml
deleted file mode 100644
index 6fc057f88d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8858.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "Made unholy water healtoxinlover"
diff --git a/html/changelogs/AutoChangeLog-pr-8860.yml b/html/changelogs/AutoChangeLog-pr-8860.yml
deleted file mode 100644
index 95593b1dad..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8860.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Zelus Oil, brass flasks"
diff --git a/html/changelogs/AutoChangeLog-pr-8870.yml b/html/changelogs/AutoChangeLog-pr-8870.yml
deleted file mode 100644
index 08c9860a30..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8870.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "Toned down many species' female chest sprites to fit the smaller cups."
- - bugfix: "Fixed some body parts sprites inconsistencies, such as the W/E female and male chest sprites being the same in some species, and jellypeople's legs being one tile off on W/E"
diff --git a/html/changelogs/AutoChangeLog-pr-8872.yml b/html/changelogs/AutoChangeLog-pr-8872.yml
deleted file mode 100644
index a79ec48298..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8872.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - balance: "Normal mops now only use 2 stamina to mop a tile, nerfed from their previous value of 5 stamina per tile mopped."
- - balance: "Advanced mops now only use 1 stamina to mop turfs, from their former value of 2 stam."
diff --git a/html/changelogs/AutoChangeLog-pr-8873.yml b/html/changelogs/AutoChangeLog-pr-8873.yml
deleted file mode 100644
index af166d496a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8873.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by YPOQ)"
-delete-after: True
-changes:
- - bugfix: "Fixes clockwork armor not actually having armor."
diff --git a/html/changelogs/AutoChangeLog-pr-8874.yml b/html/changelogs/AutoChangeLog-pr-8874.yml
deleted file mode 100644
index 0d7b51a941..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8874.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (original PRs by Floyd/Qustinnus, optimumtact, Denton and coiax)"
-delete-after: True
-changes:
- - rscadd: "You can now select what your pills will look like when making pills from the Chem Master"
- - rscadd: "Red pills can make you think."
diff --git a/html/changelogs/AutoChangeLog-pr-8877.yml b/html/changelogs/AutoChangeLog-pr-8877.yml
deleted file mode 100644
index 205ff8f2c3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8877.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerLUA"
-delete-after: True
-changes:
- - bugfix: "Fixed most reagents having a placeholder color."
diff --git a/html/changelogs/AutoChangeLog-pr-8880.yml b/html/changelogs/AutoChangeLog-pr-8880.yml
deleted file mode 100644
index e720f00ccb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8880.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - tweak: "air alarms are green now instead of blue when the atmosphere is ideal"
diff --git a/html/changelogs/AutoChangeLog-pr-8881.yml b/html/changelogs/AutoChangeLog-pr-8881.yml
deleted file mode 100644
index 3599d4fa23..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8881.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixing baklava pies a bit."
diff --git a/html/changelogs/AutoChangeLog-pr-8883.yml b/html/changelogs/AutoChangeLog-pr-8883.yml
deleted file mode 100644
index 715ce5dbfc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8883.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - tweak: "Hexacrocin overdose no longer causes climaxes"
diff --git a/html/changelogs/AutoChangeLog-pr-8884.yml b/html/changelogs/AutoChangeLog-pr-8884.yml
deleted file mode 100644
index c63618a6d9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8884.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (original PR by duckay)"
-delete-after: True
-changes:
- - rscadd: "Added better names and descriptions for blueshirt officer gear."
- - rscadd: "Added the above gear to the premium selection of the sectech"
diff --git a/html/changelogs/AutoChangeLog-pr-8885.yml b/html/changelogs/AutoChangeLog-pr-8885.yml
deleted file mode 100644
index 1469ccf460..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8885.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (original PR by coiax)"
-delete-after: True
-changes:
- - code_imp: "The Squeak subsystem has been renamed to Minor Mapping."
diff --git a/html/changelogs/AutoChangeLog-pr-8887.yml b/html/changelogs/AutoChangeLog-pr-8887.yml
deleted file mode 100644
index 45826fe571..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8887.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "NT Newscasters have had repeated reports of gang activity and are now looking into it."
- - rscadd: "NT Psykers keep mumbling about last words of someone who died. Somehow they even have a newsletter for this..."
- - bugfix: "Gangster greeting messages are a batch message rather than 5 laggy to_chats"
diff --git a/html/changelogs/AutoChangeLog-pr-8898.yml b/html/changelogs/AutoChangeLog-pr-8898.yml
deleted file mode 100644
index e836d4225e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8898.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "WhiteHusky"
-delete-after: True
-changes:
- - tweak: "Checking yourself shouldn't freeze the client anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-8900.yml b/html/changelogs/AutoChangeLog-pr-8900.yml
deleted file mode 100644
index cbb910c3d5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8900.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Seris02"
-delete-after: True
-changes:
- - rscadd: "Abductor Replication Lab ruin and advanced tools"
diff --git a/html/changelogs/AutoChangeLog-pr-8906.yml b/html/changelogs/AutoChangeLog-pr-8906.yml
deleted file mode 100644
index c988071f3e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8906.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "Sweaters now cover groins too."
diff --git a/html/changelogs/AutoChangeLog-pr-8908.yml b/html/changelogs/AutoChangeLog-pr-8908.yml
deleted file mode 100644
index d9cbd5abed..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8908.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "Improved the zelus flask to be more viable for bottle smashing than the average barman's selection."
- - code_imp: "Very slight bottle smashing code clean up, stupid const vars."
diff --git a/html/changelogs/AutoChangeLog-pr-8909.yml b/html/changelogs/AutoChangeLog-pr-8909.yml
deleted file mode 100644
index bfb1470f71..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8909.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes krav maga gloves, wizard spells knockdowns."
diff --git a/html/changelogs/AutoChangeLog-pr-8912.yml b/html/changelogs/AutoChangeLog-pr-8912.yml
deleted file mode 100644
index 5d5a7c38fc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8912.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PRs by ShizCalev and bobbahbrown)"
-delete-after: True
-changes:
- - rscadd: "Headsets now dynamically show in their description how to speak on any channels they can use when held or worn."
- - code_imp: "Radio channels names and keys now use defines."
- - tweak: "The head arrival announcement will now be broadcast to the supply for the quartermaster."
diff --git a/html/changelogs/AutoChangeLog-pr-8913.yml b/html/changelogs/AutoChangeLog-pr-8913.yml
deleted file mode 100644
index ccac6aef16..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8913.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Added new chairs"
diff --git a/html/changelogs/AutoChangeLog-pr-8914.yml b/html/changelogs/AutoChangeLog-pr-8914.yml
deleted file mode 100644
index ea7f548d6a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8914.yml
+++ /dev/null
@@ -1,13 +0,0 @@
-author: "Ghommie (original PRs by Mickyan, Anturk, ShizCalev, nemvar and Naksu)"
-delete-after: True
-changes:
- - rscadd: "After rigorous mandatory art training for the crew, many new graffiti styles are now available"
- - bugfix: "Cleaned up some crayon and spraycan code for futureproofing."
- - bugfix: "Spraypainting blast doors no longer makes them see-through."
- - balance: "Paint remover now works on blast doors and the like."
- - rscadd: "Most objects can now be colored using a spray can."
- - spellcheck: "Added visible message to spraying objects and windows."
- - rscadd: "Colored lights now shine in different colours."
- - rscdel: "Removed individual buttons text in crayon/spraycan UI, speeding it up."
- - bugfix: "Text mode buffer is actually visible in the UI."
- - tweak: "Last letter of a text mode buffer no longer rotates out to be replaced with \"a\", allowing the text mode to be used for individual symbols."
diff --git a/html/changelogs/AutoChangeLog-pr-8915.yml b/html/changelogs/AutoChangeLog-pr-8915.yml
deleted file mode 100644
index 5e3e0e77a9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8915.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "Added in an alert pop up to the cult convertees, on top of the older \"click here to become a blood cultist\" chat message."
- - tweak: "The convertee's screen will now flash red to fit in the aforementioned message's fluff."
- - spellcheck: "Made said message less verbose."
diff --git a/html/changelogs/AutoChangeLog-pr-8917.yml b/html/changelogs/AutoChangeLog-pr-8917.yml
deleted file mode 100644
index 2b858cad47..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8917.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - bugfix: "Warp whistles no longer grant permanent invulnerability and invisibility"
diff --git a/html/changelogs/AutoChangeLog-pr-8920.yml b/html/changelogs/AutoChangeLog-pr-8920.yml
deleted file mode 100644
index 6d3ae3ada4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8920.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Towels. Crafted with 3 sheets of cloth, they can be worn on head, suit and belt slots even without uniform, or laid flat on the floor. Sprites from Baystation and Aurora Station."
- - rscadd: "You can combat mode right click people while wielding rags and towels to pat out their flames (to no use for rags) or otherwise drying them out."
diff --git a/html/changelogs/AutoChangeLog-pr-8921.yml b/html/changelogs/AutoChangeLog-pr-8921.yml
deleted file mode 100644
index 9c1c456f7f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8921.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - admin: "Bugtesting zone upgrades for easy bug/game testing"
diff --git a/html/changelogs/AutoChangeLog-pr-8922.yml b/html/changelogs/AutoChangeLog-pr-8922.yml
deleted file mode 100644
index 1e641bd424..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8922.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "Gamemode voting results are displayed at the end-round screen."
diff --git a/html/changelogs/AutoChangeLog-pr-8925.yml b/html/changelogs/AutoChangeLog-pr-8925.yml
deleted file mode 100644
index ddc90eba19..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8925.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerLUA"
-delete-after: True
-changes:
- - bugfix: "Fixed autolathe wires not correctly shocking you when pulsed."
diff --git a/html/changelogs/AutoChangeLog-pr-8926.yml b/html/changelogs/AutoChangeLog-pr-8926.yml
deleted file mode 100644
index 762318ab21..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8926.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - rscadd: "Added the secbat, a box to hold it and the ability to dispense it from the SecTech vendor."
diff --git a/html/changelogs/AutoChangeLog-pr-8927.yml b/html/changelogs/AutoChangeLog-pr-8927.yml
deleted file mode 100644
index 3a87d7652e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8927.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "toned down the stamina costs of some of the bulkier weapons."
- - code_imp: "repathed hypereutactic blades to be a subtype of dual sabers. Way less copypasta."
diff --git a/html/changelogs/AutoChangeLog-pr-8929.yml b/html/changelogs/AutoChangeLog-pr-8929.yml
deleted file mode 100644
index 4fed45f1d0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8929.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixing CX Shredder guns not accepting standard flechette mags."
- - bugfix: "Fixing missing magpistol magazines icon states."
diff --git a/html/changelogs/AutoChangeLog-pr-8931.yml b/html/changelogs/AutoChangeLog-pr-8931.yml
deleted file mode 100644
index 2bde1025db..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8931.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "more cargo to cargo"
diff --git a/html/changelogs/AutoChangeLog-pr-8932.yml b/html/changelogs/AutoChangeLog-pr-8932.yml
deleted file mode 100644
index d9038ef1a5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8932.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "EmeraldSundisk"
-delete-after: True
-changes:
- - rscadd: "Adds a gun range to Box Station"
- - rscadd: "Provides some extra power grid connections"
- - rscdel: "Sunglasses and Earmuffs removed from the Warden's Office - they can be found at the range instead"
- - tweak: "Rearranges a few objects within the prison as to accommodate the new gun range"
diff --git a/html/changelogs/AutoChangeLog-pr-8933.yml b/html/changelogs/AutoChangeLog-pr-8933.yml
deleted file mode 100644
index 09d318be08..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8933.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - balance: "Cloning no longer gives you positive mutations, but a chance for a negative one. Cloning has a chance to \"scramble\" your visual DNA."
diff --git a/html/changelogs/AutoChangeLog-pr-8934.yml b/html/changelogs/AutoChangeLog-pr-8934.yml
deleted file mode 100644
index e86e47a45f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8934.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "More loadout gear"
diff --git a/html/changelogs/AutoChangeLog-pr-8939.yml b/html/changelogs/AutoChangeLog-pr-8939.yml
deleted file mode 100644
index 6041d66721..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8939.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "The syndicate base's bathroom is now fitted with a shower, and a special towel."
- - bugfix: "Fixed many issues with towels."
- - tweak: "The dry people off with rags/towels action can only be done if the object is NOT moist with reagents now. Also cleans banana creaming."
- - rscadd: "Towels deal more damage while soaked with reagents."
- - rscadd: "You can now squeeze rags/towels with Alt-Click."
- - rscdel: "deleted an old and crappier towel sprite that got in the way."
diff --git a/html/changelogs/AutoChangeLog-pr-8942.yml b/html/changelogs/AutoChangeLog-pr-8942.yml
deleted file mode 100644
index a1b80ba839..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8942.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Chayse"
-delete-after: True
-changes:
- - tweak: "Changed the Warden's compact combat shotgun to instead be a regular combat shotgun with a foldable stock and penalties for being folded."
diff --git a/html/changelogs/AutoChangeLog-pr-8945.yml b/html/changelogs/AutoChangeLog-pr-8945.yml
deleted file mode 100644
index afa9bdaa95..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8945.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes Pubby's disposal conveyor belts and lack of a second lawyer spawner."
diff --git a/html/changelogs/AutoChangeLog-pr-8949.yml b/html/changelogs/AutoChangeLog-pr-8949.yml
deleted file mode 100644
index 83560d74f2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8949.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "Poojawa power creep"
diff --git a/html/changelogs/AutoChangeLog-pr-8950.yml b/html/changelogs/AutoChangeLog-pr-8950.yml
deleted file mode 100644
index 62b90d2407..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8950.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "Not my work not my credit"
diff --git a/html/changelogs/AutoChangeLog-pr-8952.yml b/html/changelogs/AutoChangeLog-pr-8952.yml
deleted file mode 100644
index df2ff22d09..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8952.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CdrCross"
-delete-after: True
-changes:
- - rscadd: "Adds the ability for cloning consoles to read and write record lists to the circuit board, and provides a template for giving other machines local circuit board memory."
diff --git a/html/changelogs/AutoChangeLog-pr-8953.yml b/html/changelogs/AutoChangeLog-pr-8953.yml
deleted file mode 100644
index 2128149556..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8953.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Toriate"
-delete-after: True
-changes:
- - rscadd: "RPD now has inhands"
- - imageadd: "New sprites for RCDs and RPDs, inhands included"
diff --git a/html/changelogs/AutoChangeLog-pr-8956.yml b/html/changelogs/AutoChangeLog-pr-8956.yml
deleted file mode 100644
index d6d33b3bd2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8956.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - tweak: "Altered the icons for inventory backplates. Sleek! Stylish! New!"
diff --git a/html/changelogs/AutoChangeLog-pr-8958.yml b/html/changelogs/AutoChangeLog-pr-8958.yml
deleted file mode 100644
index a800b1b218..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8958.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Emitter gun"
diff --git a/html/changelogs/AutoChangeLog-pr-8959.yml b/html/changelogs/AutoChangeLog-pr-8959.yml
deleted file mode 100644
index 87ca24462e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8959.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "suit storage nulling anti magic item protection"
diff --git a/html/changelogs/AutoChangeLog-pr-8964.yml b/html/changelogs/AutoChangeLog-pr-8964.yml
deleted file mode 100644
index 6675fecc50..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8964.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - balance: "rebalanced steal goals restrictions"
- - spellcheck: "fixed a few misleading goals"
diff --git a/html/changelogs/AutoChangeLog-pr-8965.yml b/html/changelogs/AutoChangeLog-pr-8965.yml
deleted file mode 100644
index 138991e507..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8965.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "ports a fix"
diff --git a/html/changelogs/AutoChangeLog-pr-8966.yml b/html/changelogs/AutoChangeLog-pr-8966.yml
deleted file mode 100644
index 2d63b8356e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8966.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - imageadd: "RCL now show what color is currently in use"
diff --git a/html/changelogs/AutoChangeLog-pr-8968.yml b/html/changelogs/AutoChangeLog-pr-8968.yml
deleted file mode 100644
index 0a0b0e84d0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8968.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "oversight in benos"
diff --git a/html/changelogs/AutoChangeLog-pr-8970.yml b/html/changelogs/AutoChangeLog-pr-8970.yml
deleted file mode 100644
index 304c9115dc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8970.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "original by @randolfthemeh and @twaticus, port by sishen1542"
-delete-after: True
-changes:
- - rscadd: "jumpskirts"
- - rscadd: "more jumpskirts"
- - rscadd: "jumpskirt/suit prefs"
diff --git a/html/changelogs/AutoChangeLog-pr-8971.yml b/html/changelogs/AutoChangeLog-pr-8971.yml
deleted file mode 100644
index c5b5215ff9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8971.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - tweak: "slime people now enjoy eating toxic food and it will not disgust them"
diff --git a/html/changelogs/AutoChangeLog-pr-8974.yml b/html/changelogs/AutoChangeLog-pr-8974.yml
deleted file mode 100644
index b71dc88ecd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8974.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "EgoSumStultus"
-delete-after: True
-changes:
- - bugfix: "Fixed blood chiller's inhand"
diff --git a/html/changelogs/AutoChangeLog-pr-8976.yml b/html/changelogs/AutoChangeLog-pr-8976.yml
deleted file mode 100644
index 67e7bbc11a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8976.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "combat pushes will now properly stop targets from using firearms, and will disarm the firearm if performed a second time, and also slow down people by 15%, and won't push people on tables blocked by shutters or other dense object anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-8978.yml b/html/changelogs/AutoChangeLog-pr-8978.yml
deleted file mode 100644
index 56e3760e9c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8978.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Yakumo Chen"
-delete-after: True
-changes:
- - balance: "Made stealth implant boxes flimsier"
diff --git a/html/changelogs/AutoChangeLog-pr-8979.yml b/html/changelogs/AutoChangeLog-pr-8979.yml
deleted file mode 100644
index f826fcd681..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8979.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes CHECK_BITFIELD macro."
diff --git a/html/changelogs/AutoChangeLog-pr-8980.yml b/html/changelogs/AutoChangeLog-pr-8980.yml
deleted file mode 100644
index caba11ae69..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8980.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes hypovials being unable to transfer out liquids or be refilled by large dispensers like water tanks."
- - bugfix: "Fixes chem-masters machineries not dispensing newly made pills inside loaded in pill bottles."
diff --git a/html/changelogs/AutoChangeLog-pr-8982.yml b/html/changelogs/AutoChangeLog-pr-8982.yml
deleted file mode 100644
index 8599966d64..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8982.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PR by Skoglol)"
-delete-after: True
-changes:
- - bugfix: "Mining bags will no longer drop ore into backpack."
- - bugfix: "Mining bags in backpack no longer interferes with other mining bags."
- - bugfix: "Fixes some storage size circumventions."
diff --git a/html/changelogs/AutoChangeLog-pr-8984.yml b/html/changelogs/AutoChangeLog-pr-8984.yml
deleted file mode 100644
index 31c45cdbc6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8984.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Stunswords now fit in the captain's sabre sheat."
diff --git a/html/changelogs/AutoChangeLog-pr-8985.yml b/html/changelogs/AutoChangeLog-pr-8985.yml
deleted file mode 100644
index 37aaa4162d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8985.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - bugfix: "hos trenchcloak now properly has a sprite on digi characters"
diff --git a/html/changelogs/AutoChangeLog-pr-8986.yml b/html/changelogs/AutoChangeLog-pr-8986.yml
deleted file mode 100644
index 810631f5f5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8986.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "reworked ninja's stealth mode. Increased invisibility, but engaging in combat, attacking or throwing things, bumping people will temporarily lower it."
- - rscadd: "Ninja shoes are even stealthier."
- - code_imp: "cleaned up some 2014 tier processing code horror."
diff --git a/html/changelogs/AutoChangeLog-pr-8988.yml b/html/changelogs/AutoChangeLog-pr-8988.yml
deleted file mode 100644
index 9145d73c01..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8988.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "kiwedespars"
-delete-after: True
-changes:
- - rscadd: "regenerative materia to hallucination sting"
- - rscadd: "mindbreaker toxin as an actual chemical to hallucination sting"
diff --git a/html/changelogs/AutoChangeLog-pr-8991.yml b/html/changelogs/AutoChangeLog-pr-8991.yml
deleted file mode 100644
index 138991e507..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8991.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "ports a fix"
diff --git a/html/changelogs/AutoChangeLog-pr-8992.yml b/html/changelogs/AutoChangeLog-pr-8992.yml
deleted file mode 100644
index 299792fee3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8992.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Chayse"
-delete-after: True
-changes:
- - rscadd: "Assorted space-worthy helmets can now act as masks for internals."
- - refactor: "Internals code can now check any item with the ALLOWSINTERNALS flag through the GET_INTERNAL_SLOTS define. For now this only checks head and mask slots, since those are the most realistically speaking usable ones."
diff --git a/html/changelogs/AutoChangeLog-pr-8994.yml b/html/changelogs/AutoChangeLog-pr-8994.yml
deleted file mode 100644
index a3a4fef0b7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8994.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "the oxyloss fullscreen overlays now also take in consideration 1/5 of the user stamina loss."
diff --git a/html/changelogs/AutoChangeLog-pr-8995.yml b/html/changelogs/AutoChangeLog-pr-8995.yml
deleted file mode 100644
index 76669d7821..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8995.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "When you're jogging, you will only slip on water if you have more than 20% staminaloss, for real this time."
diff --git a/html/changelogs/AutoChangeLog-pr-8996.yml b/html/changelogs/AutoChangeLog-pr-8996.yml
deleted file mode 100644
index 7c631e3301..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8996.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - imageadd: "Different cuffs now come with different worn overlays instead of a generic one."
diff --git a/html/changelogs/AutoChangeLog-pr-8998.yml b/html/changelogs/AutoChangeLog-pr-8998.yml
deleted file mode 100644
index 981e746fc9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8998.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "High luminosity eyes can now be properly deactivated and won't illuminate your surroundings again until turned back on."
diff --git a/html/changelogs/AutoChangeLog-pr-8999.yml b/html/changelogs/AutoChangeLog-pr-8999.yml
deleted file mode 100644
index 182e3a8409..0000000000
--- a/html/changelogs/AutoChangeLog-pr-8999.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - balance: "Chestbursters no longer give and remove your brain. They just disembowel and kill you now."
diff --git a/html/changelogs/AutoChangeLog-pr-9000.yml b/html/changelogs/AutoChangeLog-pr-9000.yml
deleted file mode 100644
index 3fa3e8946f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9000.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "EgoSumStultus"
-delete-after: True
-changes:
- - bugfix: "FIXED SHIELF"
diff --git a/html/changelogs/AutoChangeLog-pr-9001.yml b/html/changelogs/AutoChangeLog-pr-9001.yml
deleted file mode 100644
index be2fd2b833..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9001.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - rscdel: "duplicate definition of hos and sec skirts"
diff --git a/html/changelogs/AutoChangeLog-pr-9005.yml b/html/changelogs/AutoChangeLog-pr-9005.yml
deleted file mode 100644
index d65017a00d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9005.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "QM rooms not getting Key Aunths"
diff --git a/html/changelogs/AutoChangeLog-pr-9008.yml b/html/changelogs/AutoChangeLog-pr-9008.yml
deleted file mode 100644
index 0c73bc8ae9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9008.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - bugfix: "Krav Maga leg sweep now works properly."
diff --git a/html/changelogs/AutoChangeLog-pr-9009.yml b/html/changelogs/AutoChangeLog-pr-9009.yml
deleted file mode 100644
index 21cf0c8d85..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9009.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - bugfix: "Fixes WarOps miscalculating players."
diff --git a/html/changelogs/AutoChangeLog-pr-9010.yml b/html/changelogs/AutoChangeLog-pr-9010.yml
deleted file mode 100644
index 52aed38e2c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9010.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - balance: "Activating the nuclear device during war-ops informs the crew of the nuke's position."
diff --git a/html/changelogs/AutoChangeLog-pr-9014.yml b/html/changelogs/AutoChangeLog-pr-9014.yml
deleted file mode 100644
index f217b64afd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9014.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes freshly cloned people starting with undershirts. Fixes random characters possibly rolling with undergarments of the opposite gender (Doesn't affect preferences' freedom of choice)."
diff --git a/html/changelogs/AutoChangeLog-pr-9018.yml b/html/changelogs/AutoChangeLog-pr-9018.yml
deleted file mode 100644
index 7acb63b426..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9018.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-author: "Ghommie (original PRs by XDTM, optimumtact, Nichlas0010 and monster860)"
-delete-after: True
-changes:
- - rscadd: "Added Quantum Keycards, devices that can link to a quantum pad, and can be used on any other quantum pad to teleport to its linked pad.
-spellchecking: Renamed \"Bluespace Teleportation Tech\" tech node to \"Bluespace Travel\"."
- - tweak: "Moved roasting sticks from the \"Bluespace Travel\" to \"Practical Bluespace\"."
- - rscadd: "Spraying holy water on tiles will now prevent cult-based teleportation from using them as a destination point."
- - tweak: "Quantum, wormhole and magic teleportation is no longer disrupted by bags of holding."
- - bugfix: "You are now also blocked from teleporting IN to no-teleport areas, not just out of them."
- - tweak: "Quantum teleportation now makes pretty rainbow sparks instead of the normal ones."
- - bugfix: "Non-bluespace teleportation (spells etc.) no longer makes sparks."
- - bugfix: "Fixed teleportation deleting mob spawners like golem shells and ashwalker eggs."
diff --git a/html/changelogs/AutoChangeLog-pr-9019.yml b/html/changelogs/AutoChangeLog-pr-9019.yml
deleted file mode 100644
index 8006c134e3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9019.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "MRE menu 3 has cuban nachos instead of a chili now."
- - bugfix: "Removed the illustration overlay from MREs, looks pretty weird otherwise."
- - rscadd: "MRE menu 4, vegetarian."
diff --git a/html/changelogs/AutoChangeLog-pr-9021.yml b/html/changelogs/AutoChangeLog-pr-9021.yml
deleted file mode 100644
index e8809f1d7e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9021.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (by Floyd / Qustinnus, Arathian)"
-delete-after: True
-changes:
- - rscadd: "The robotocist now has robe to show his love for toasters"
diff --git a/html/changelogs/AutoChangeLog-pr-9022.yml b/html/changelogs/AutoChangeLog-pr-9022.yml
deleted file mode 100644
index 4fb48506e4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9022.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (by nemvar)"
-delete-after: True
-changes:
- - tweak: "Dwarfs are now more robust."
diff --git a/html/changelogs/AutoChangeLog-pr-9024.yml b/html/changelogs/AutoChangeLog-pr-9024.yml
deleted file mode 100644
index 1d75959c79..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9024.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie (by Arkatos)"
-delete-after: True
-changes:
- - bugfix: "Fixed an issue with a Lizardwine drink crafting, where a final product would contain unwated 100u of Ethanol."
diff --git a/html/changelogs/AutoChangeLog-pr-9026.yml b/html/changelogs/AutoChangeLog-pr-9026.yml
deleted file mode 100644
index bf8ce9efbe..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9026.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - rscadd: "The alert level is displayed at the job selection screen."
diff --git a/html/changelogs/AutoChangeLog-pr-9030.yml b/html/changelogs/AutoChangeLog-pr-9030.yml
deleted file mode 100644
index 94c797433a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9030.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - bugfix: "Attaching a beaker that contains water to an IV stand no longer causes a visual glitch"
diff --git a/html/changelogs/AutoChangeLog-pr-9033.yml b/html/changelogs/AutoChangeLog-pr-9033.yml
deleted file mode 100644
index 3e69bc9486..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9033.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "EgoSumStultus"
-delete-after: True
-changes:
- - bugfix: "fixed magpistol magazine sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-9036.yml b/html/changelogs/AutoChangeLog-pr-9036.yml
deleted file mode 100644
index afd2882fc3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9036.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - rscadd: "shoes can have a different icon used for their item and mob icons"
- - bugfix: "combat gloves plus having no mob icon"
diff --git a/html/changelogs/AutoChangeLog-pr-9040.yml b/html/changelogs/AutoChangeLog-pr-9040.yml
deleted file mode 100644
index 33958a2ece..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9040.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "new books/cooking"
diff --git a/html/changelogs/AutoChangeLog-pr-9042.yml b/html/changelogs/AutoChangeLog-pr-9042.yml
deleted file mode 100644
index 38c4006383..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9042.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "EgoSumStultus"
-delete-after: True
-changes:
- - rscadd: "Added the Femur Breaker"
diff --git a/html/changelogs/AutoChangeLog-pr-9043.yml b/html/changelogs/AutoChangeLog-pr-9043.yml
deleted file mode 100644
index 14c9331e5b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9043.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "chef"
-delete-after: True
-changes:
- - rscadd: "Added main hallway approach to monastery"
- - rscadd: "Added Maintenance hallway approach, with some maint loot"
- - tweak: "moved the docking arm for the white ship"
- - tweak: "changed placement of some grills and windows"
diff --git a/html/changelogs/AutoChangeLog-pr-9044.yml b/html/changelogs/AutoChangeLog-pr-9044.yml
deleted file mode 100644
index 6133ea45e9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9044.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Original by Citinited, port by Sishen1542"
-delete-after: True
-changes:
- - rscadd: "You can now use an airlock electronics on a locker to add a lock, and can screwdriver an unlocked locker to remove its lock."
- - rscadd: "You can now remove the locks on broken or emagged lockers."
- - tweak: "Removing the lock from a personal locker now wipes that locker's ID details."
- - tweak: "Broken lockers have had their appearance changed."
diff --git a/html/changelogs/AutoChangeLog-pr-9045.yml b/html/changelogs/AutoChangeLog-pr-9045.yml
deleted file mode 100644
index 8917707ae3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9045.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "CameronWoof"
-delete-after: True
-changes:
- - tweak: "Fluid-producing sexual organs no longer start full"
- - tweak: "Sexual organ fluid capacity decreased from 50 to 15"
- - tweak: "Sexual organ production rate decreased from 5u to 0.035u per two seconds."
- - tweak: "Sexual fluid decals no longer contain reagents"
- - tweak: "Sexual fluids cannot by synthesized (e.g., by the Odysseus)"
diff --git a/html/changelogs/AutoChangeLog-pr-9046.yml b/html/changelogs/AutoChangeLog-pr-9046.yml
deleted file mode 100644
index 24e7035a88..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9046.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - tweak: "density = 0"
diff --git a/html/changelogs/AutoChangeLog-pr-9050.yml b/html/changelogs/AutoChangeLog-pr-9050.yml
deleted file mode 100644
index 3b12a12f17..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9050.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "fixes a few bad touchs on combat mode pushing."
diff --git a/html/changelogs/AutoChangeLog-pr-9052.yml b/html/changelogs/AutoChangeLog-pr-9052.yml
deleted file mode 100644
index a75b6c51ae..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9052.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - balance: "Hierophant now goes sicko mode, but hey, at least you can't be multi-hit by melee waves!"
diff --git a/html/changelogs/AutoChangeLog-pr-9054.yml b/html/changelogs/AutoChangeLog-pr-9054.yml
deleted file mode 100644
index 5952c9ecfd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9054.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - balance: "hugboxing mining loot"
diff --git a/html/changelogs/AutoChangeLog-pr-9057.yml b/html/changelogs/AutoChangeLog-pr-9057.yml
deleted file mode 100644
index 4df1b23ca7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9057.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "EgoSumStultus"
-delete-after: True
-changes:
- - rscadd: "Adds male AI vox."
diff --git a/html/changelogs/AutoChangeLog-pr-9061.yml b/html/changelogs/AutoChangeLog-pr-9061.yml
deleted file mode 100644
index 4fc9d10ba5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9061.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - tweak: "The femur breaker now uses `*scream` instead of forced speech. This means that the femur breaker will no longer spam deadchat with \"AAAAAAAAAHHHHHHHHHH!!\""
- - tweak: "The femur breaker will now guarantee that the victim falls into crit, which will make it harder to perform torture scenes with it since the victim can just succumb."
diff --git a/html/changelogs/AutoChangeLog-pr-9062.yml b/html/changelogs/AutoChangeLog-pr-9062.yml
deleted file mode 100644
index 12102204c3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9062.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - spellcheck: "less bad wording in slime"
diff --git a/html/changelogs/AutoChangeLog-pr-9064.yml b/html/changelogs/AutoChangeLog-pr-9064.yml
deleted file mode 100644
index 6e775c1eb4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9064.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Cebutris"
-delete-after: True
-changes:
- - rscadd: "Hugs of the North Star! Get them from the arcades (if you're lucky) and hug your friends at INCREDIBLE hihg speeds!"
diff --git a/html/changelogs/AutoChangeLog-pr-9069.yml b/html/changelogs/AutoChangeLog-pr-9069.yml
deleted file mode 100644
index 0439515dd3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9069.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes clock cult Abscond scripture not dragging pulled mobs into Reebe. Also fixes blood cult tele runes teleporting you from the source turf to the source turf."
diff --git a/html/changelogs/AutoChangeLog-pr-9070.yml b/html/changelogs/AutoChangeLog-pr-9070.yml
deleted file mode 100644
index 2013550dd2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9070.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - rscadd: "inhands sprite for rainbow knife"
- - tweak: "colour of highlight on the regular knife when held in the right hand"
diff --git a/html/changelogs/AutoChangeLog-pr-9071.yml b/html/changelogs/AutoChangeLog-pr-9071.yml
deleted file mode 100644
index 40ae43867f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9071.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Yakumo Chen"
-delete-after: True
-changes:
- - balance: "Autocloning now requires tier 4 parts"
diff --git a/html/changelogs/AutoChangeLog-pr-9077.yml b/html/changelogs/AutoChangeLog-pr-9077.yml
deleted file mode 100644
index 2f42e36dd6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9077.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "original by actioninja, port by sishen1542"
-delete-after: True
-changes:
- - tweak: "Medical and Security consoles now check access on worn or inhand ID instead of requiring an inserted ID"
- - tweak: "mining vendor now reads from ID in hand or on person instead of requiring an inserted ID"
- - bugfix: "ORM is functional again (for real this time)"
- - tweak: "ORM claim points button transfers points to worn/inhand ID instead of to an inserted ID, no longer accepts insertions"
- - tweak: "Same for gulag consoles"
diff --git a/html/changelogs/AutoChangeLog-pr-9078.yml b/html/changelogs/AutoChangeLog-pr-9078.yml
deleted file mode 100644
index 2e202ec43a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9078.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "kappa-sama"
-delete-after: True
-changes:
- - rscdel: "Removed racism"
- - tweak: "Teleporter calibration actually matters to all roundstart players"
- - balance: "Slows down teleportation with the console/hub/teleporter setup if you care for your species."
- - balance: "Dedicated non-humans can now get hulk without having to become human."
diff --git a/html/changelogs/AutoChangeLog-pr-9079.yml b/html/changelogs/AutoChangeLog-pr-9079.yml
deleted file mode 100644
index 42aa732e16..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9079.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - balance: "ling blade now has 40 armor pen"
diff --git a/html/changelogs/AutoChangeLog-pr-9080.yml b/html/changelogs/AutoChangeLog-pr-9080.yml
deleted file mode 100644
index 1ae1e3e2aa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9080.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - rscadd: "Adds 3 new music tracks."
diff --git a/html/changelogs/AutoChangeLog-pr-9081.yml b/html/changelogs/AutoChangeLog-pr-9081.yml
deleted file mode 100644
index c66148e446..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9081.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerBB"
-delete-after: True
-changes:
- - balance: "Central Command informs you when a Meteor Storm is about to hit 5 to 10 minutes before it happens."
diff --git a/html/changelogs/AutoChangeLog-pr-9083.yml b/html/changelogs/AutoChangeLog-pr-9083.yml
deleted file mode 100644
index 74b4d95ca3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9083.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "strawbarries and such"
diff --git a/html/changelogs/AutoChangeLog-pr-9084.yml b/html/changelogs/AutoChangeLog-pr-9084.yml
deleted file mode 100644
index c2569d10b4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9084.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "fixes clock cult mass recall."
diff --git a/html/changelogs/AutoChangeLog-pr-9085.yml b/html/changelogs/AutoChangeLog-pr-9085.yml
deleted file mode 100644
index 92f5dc4cf8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9085.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes underwear colors a bit."
diff --git a/html/changelogs/AutoChangeLog-pr-9086.yml b/html/changelogs/AutoChangeLog-pr-9086.yml
deleted file mode 100644
index 4dea682d47..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9086.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "original by TheChosenEvilOne, port by sishen1542"
-delete-after: True
-changes:
- - rscadd: "Ported dynamic mode from /vg/, originally made by @DeityLink, @Kurfursten and @ShiftyRail"
diff --git a/html/changelogs/AutoChangeLog-pr-9089.yml b/html/changelogs/AutoChangeLog-pr-9089.yml
deleted file mode 100644
index dc1e351f25..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9089.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "original by Tlaltecuhtli, port by sishen1542"
-delete-after: True
-changes:
- - rscadd: "rcd disk that gives rcd computer frame and machine frame designs"
- - rscadd: "upgraded rcd in CE lockers"
- - tweak: "moved deconstruction to the upgrade disk, ashwalker rcd comes upgraded"
diff --git a/html/changelogs/AutoChangeLog-pr-9097.yml b/html/changelogs/AutoChangeLog-pr-9097.yml
deleted file mode 100644
index 941c0e7b98..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9097.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "lolman360"
-delete-after: True
-changes:
- - rscadd: "NT has authorized shipments or Cotton to Megaseed Servitors. It's time to start picking, liggers."
diff --git a/html/changelogs/AutoChangeLog-pr-9098.yml b/html/changelogs/AutoChangeLog-pr-9098.yml
deleted file mode 100644
index 6e11eaeb90..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9098.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Cebutris"
-delete-after: True
-changes:
- - bugfix: "Tea Aspera now properly contains tea powder"
diff --git a/html/changelogs/AutoChangeLog-pr-9099.yml b/html/changelogs/AutoChangeLog-pr-9099.yml
deleted file mode 100644
index d3caa658f2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9099.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - tweak: "tweaked Neurotoxin"
- - balance: "added more depth to Neurotoxin"
- - bugfix: "fixed the inability to create Neurotoxin"
diff --git a/html/changelogs/AutoChangeLog-pr-9100.yml b/html/changelogs/AutoChangeLog-pr-9100.yml
deleted file mode 100644
index 81141b3b0c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9100.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Cebutris"
-delete-after: True
-changes:
- - tweak: "Breasts no longer lactate by default, lactation is now a preference"
diff --git a/html/changelogs/AutoChangeLog-pr-9101.yml b/html/changelogs/AutoChangeLog-pr-9101.yml
deleted file mode 100644
index 174619dd49..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9101.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542, original by XDTM"
-delete-after: True
-changes:
- - rscadd: "Surgery steps are now shown in detail only to the surgeon and anyone standing adjacent to them; the patient and people watching from further away get a more vague/ambiguous description."
diff --git a/html/changelogs/AutoChangeLog-pr-9107.yml b/html/changelogs/AutoChangeLog-pr-9107.yml
deleted file mode 100644
index 65a14b9576..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9107.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - bugfix: "You can now actually use the resist hotkey to resist out of handcuffs. Woah, revolutionary"
diff --git a/html/changelogs/AutoChangeLog-pr-9109.yml b/html/changelogs/AutoChangeLog-pr-9109.yml
deleted file mode 100644
index 137ca7f325..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9109.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "amazing things like tea of catnip, catnip and plant"
diff --git a/html/changelogs/AutoChangeLog-pr-9113.yml b/html/changelogs/AutoChangeLog-pr-9113.yml
deleted file mode 100644
index 1bdae7cab9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9113.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - bugfix: "fixes fermichem reactions for tiny volumes work"
- - tweak: "makes quantisation level for chemistry finer"
diff --git a/html/changelogs/AutoChangeLog-pr-9115.yml b/html/changelogs/AutoChangeLog-pr-9115.yml
deleted file mode 100644
index 32c3109c43..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9115.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Thalpy"
-delete-after: True
-changes:
- - bugfix: "fixes message_admins in SDZF"
diff --git a/html/changelogs/AutoChangeLog-pr-9119.yml b/html/changelogs/AutoChangeLog-pr-9119.yml
deleted file mode 100644
index 756c3edcb2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9119.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - rscadd: "mining shuttle console can now be printed after computer consoles have been researched"
diff --git a/html/changelogs/AutoChangeLog-pr-9122.yml b/html/changelogs/AutoChangeLog-pr-9122.yml
deleted file mode 100644
index 1d3ff248fb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9122.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "fun"
- - rscdel: "bad stuff"
- - balance: "mech bad"
diff --git a/html/changelogs/AutoChangeLog-pr-9126.yml b/html/changelogs/AutoChangeLog-pr-9126.yml
deleted file mode 100644
index c3e54a8f2d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9126.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "original by Skoglol, port by sishen1542"
-delete-after: True
-changes:
- - balance: "Added lots of new virus cures, made cure difficulty scale more consistently. Cures are now picked from a list of possible cures per resistance level, multiple diseases at the same level no longer always share a cure. Looking at you table salt."
diff --git a/html/changelogs/AutoChangeLog-pr-9130.yml b/html/changelogs/AutoChangeLog-pr-9130.yml
deleted file mode 100644
index f10e72a6ce..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9130.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Owai-Seek"
-delete-after: True
-changes:
- - rscadd: "custodial cruiser cargo crate"
- - tweak: "removed light replacer from power designs and moved to misc designs"
- - tweak: "added pimpin ride to custodial locator"
- - tweak: "added additional items to janibelt whitelist"
- - tweak: "made plant DNA manipulator unwrenchable"
- - balance: "reduced janitor premium supply costs"
diff --git a/html/changelogs/AutoChangeLog-pr-9132.yml b/html/changelogs/AutoChangeLog-pr-9132.yml
deleted file mode 100644
index f9dee17687..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9132.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Toriate"
-delete-after: True
-changes:
- - imageadd: "Updated the sprites of all the regular crates"
diff --git a/html/changelogs/AutoChangeLog-pr-9133.yml b/html/changelogs/AutoChangeLog-pr-9133.yml
deleted file mode 100644
index 50bfced879..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9133.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Raptorizer"
-delete-after: True
-changes:
- - tweak: "Doubled peach spawn rate"
diff --git a/html/changelogs/AutoChangeLog-pr-9134.yml b/html/changelogs/AutoChangeLog-pr-9134.yml
deleted file mode 100644
index f0be3bdd0a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9134.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Arturlang"
-delete-after: True
-changes:
- - tweak: "Advanced toxin filtration nanites now heal slimes"
diff --git a/html/changelogs/AutoChangeLog-pr-9136.yml b/html/changelogs/AutoChangeLog-pr-9136.yml
deleted file mode 100644
index 7bb9e3ccf2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9136.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - balance: "rebalances strained muscles"
diff --git a/html/changelogs/AutoChangeLog-pr-9137.yml b/html/changelogs/AutoChangeLog-pr-9137.yml
deleted file mode 100644
index a61a3dbe6f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9137.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "added in the assistant response team"
- - bugfix: "fixed up access on the centcom hangar button"
diff --git a/html/changelogs/AutoChangeLog-pr-9138.yml b/html/changelogs/AutoChangeLog-pr-9138.yml
deleted file mode 100644
index b78d505c5a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9138.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kappa-sama"
-delete-after: True
-changes:
- - bugfix: "seed"
diff --git a/html/changelogs/AutoChangeLog-pr-9141.yml b/html/changelogs/AutoChangeLog-pr-9141.yml
deleted file mode 100644
index 86230537de..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9141.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Fixed another runtime in warp whistles."
diff --git a/html/changelogs/AutoChangeLog-pr-9142.yml b/html/changelogs/AutoChangeLog-pr-9142.yml
deleted file mode 100644
index 75fbfe4155..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9142.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "glue uplinks"
diff --git a/html/changelogs/AutoChangeLog-pr-9145.yml b/html/changelogs/AutoChangeLog-pr-9145.yml
deleted file mode 100644
index 27e5712dd0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9145.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "RPDs to drones"
diff --git a/html/changelogs/AutoChangeLog-pr-9147.yml b/html/changelogs/AutoChangeLog-pr-9147.yml
deleted file mode 100644
index 7f1dcb7e7e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9147.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Code-Cygnet"
-delete-after: True
-changes:
- - rscadd: "Added new things - Mind trait, alcohol reagent, chemical reagent, drink sprite and recipe."
- - imageadd: "added commander_and_chief sprite to drinks.dmi"
diff --git a/html/changelogs/AutoChangeLog-pr-9149.yml b/html/changelogs/AutoChangeLog-pr-9149.yml
deleted file mode 100644
index 8a10035d1f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9149.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Armor and such"
diff --git a/html/changelogs/AutoChangeLog-pr-9150.yml b/html/changelogs/AutoChangeLog-pr-9150.yml
deleted file mode 100644
index 585ea0a149..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9150.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "flavor"
- - bugfix: "maybe a runtime"
diff --git a/html/changelogs/AutoChangeLog-pr-9151.yml b/html/changelogs/AutoChangeLog-pr-9151.yml
deleted file mode 100644
index ed01c0d137..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9151.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "chameloen clothing"
diff --git a/html/changelogs/AutoChangeLog-pr-9155.yml b/html/changelogs/AutoChangeLog-pr-9155.yml
deleted file mode 100644
index ad16ff6276..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9155.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - server: "Poly's speech now echos to the chat bot."
diff --git a/html/changelogs/AutoChangeLog-pr-9162.yml b/html/changelogs/AutoChangeLog-pr-9162.yml
deleted file mode 100644
index a415ce8bbc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9162.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - balance: "storage tweaks for belt briefcase"
- - imageadd: "codersprite for belt briefcase"
diff --git a/html/changelogs/AutoChangeLog-pr-9164.yml b/html/changelogs/AutoChangeLog-pr-9164.yml
deleted file mode 100644
index 08d7ccec18..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9164.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "lolman360"
-delete-after: True
-changes:
- - imageadd: "missing durathread sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-9169.yml b/html/changelogs/AutoChangeLog-pr-9169.yml
deleted file mode 100644
index 2a9d3ae34b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9169.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "EmeraldSundisk"
-delete-after: True
-changes:
- - rscadd: "Adds a mass driver to Delta Station's chapel"
- - rscadd: "Adds a second means of entry into the chapel"
- - tweak: "Slightly expands the chapel to make room for the driver, slight adjustment to air systems"
- - tweak: "Clears a path in the station exterior for the mass driver to work properly"
- - tweak: "Nearby maintenance loot has been relocated to accommodate the chapel expansion, surrounding area has been \"cleaned up\" somewhat"
diff --git a/html/changelogs/AutoChangeLog-pr-9170.yml b/html/changelogs/AutoChangeLog-pr-9170.yml
deleted file mode 100644
index 566d427605..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9170.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "tons of peach themed items"
- - spellcheck: "caje"
diff --git a/html/changelogs/AutoChangeLog-pr-9172.yml b/html/changelogs/AutoChangeLog-pr-9172.yml
deleted file mode 100644
index 751cfa6d26..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9172.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kevinz000"
-delete-after: True
-changes:
- - rscadd: "Racking shotguns is now more threatening."
diff --git a/html/changelogs/AutoChangeLog-pr-9175.yml b/html/changelogs/AutoChangeLog-pr-9175.yml
deleted file mode 100644
index d3aa92d42d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9175.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "lolman360"
-delete-after: True
-changes:
- - rscadd: "Added durathread jumpskirt"
- - imageadd: "Duraskirt sprites and rolled down jumpsuit sprites."
diff --git a/html/changelogs/AutoChangeLog-pr-9177.yml b/html/changelogs/AutoChangeLog-pr-9177.yml
deleted file mode 100644
index 4b8a06c8af..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9177.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "JTGSZ"
-delete-after: True
-changes:
- - tweak: "Added one more gang boss slot bringing total to 4 from 3"
- - bugfix: "Fixed Gang Boss being able to be deconverted"
diff --git a/html/changelogs/AutoChangeLog-pr-9178.yml b/html/changelogs/AutoChangeLog-pr-9178.yml
deleted file mode 100644
index 2a6de13f5e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9178.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - bugfix: "the `!tgs poly` command now actually works"
diff --git a/html/changelogs/AutoChangeLog-pr-9180.yml b/html/changelogs/AutoChangeLog-pr-9180.yml
deleted file mode 100644
index e184ad3205..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9180.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - rscadd: "Poly now has a 0.01% chance per squawk to speak through the TGS relay."
diff --git a/html/changelogs/AutoChangeLog-pr-9183.yml b/html/changelogs/AutoChangeLog-pr-9183.yml
deleted file mode 100644
index dc5b5a8bdb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9183.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixes Blood Cult conversion prompts"
diff --git a/html/changelogs/AutoChangeLog-pr-9184.yml b/html/changelogs/AutoChangeLog-pr-9184.yml
deleted file mode 100644
index d0b4d1fa7e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9184.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscdel: "Removes an obnoxious temporary overlay var."
diff --git a/html/changelogs/AutoChangeLog-pr-9186.yml b/html/changelogs/AutoChangeLog-pr-9186.yml
deleted file mode 100644
index f0497ee7c2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9186.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "added pharaoh gear to chaplain vendor"
- - spellcheck: "fixed typos in pharaoh items"
diff --git a/html/changelogs/AutoChangeLog-pr-9189.yml b/html/changelogs/AutoChangeLog-pr-9189.yml
deleted file mode 100644
index cf9b0c70a3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9189.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "made laser minigun not shitcode and also craftable"
- - soundadd: "added new fire sounds for the laser minigun"
diff --git a/html/changelogs/AutoChangeLog-pr-9191.yml b/html/changelogs/AutoChangeLog-pr-9191.yml
deleted file mode 100644
index 242e268017..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9191.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - rscadd: "can now carry people on your back by aggressive grabbing them while they are laying down and then dragging their sprite onto yours."
- - tweak: "dragging people who are prone is now much slower, and carrying them will allow you to move faster at the cost of taking 5 seconds to lift them up onto your back."
- - tweak: "pacifists can now aggressive grab (cannot table slam people though)"
diff --git a/html/changelogs/AutoChangeLog-pr-9194.yml b/html/changelogs/AutoChangeLog-pr-9194.yml
deleted file mode 100644
index 24299209ea..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9194.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kappa-sama"
-delete-after: True
-changes:
- - tweak: "added obj/item/key to wallet whitelist"
diff --git a/html/changelogs/AutoChangeLog-pr-9199.yml b/html/changelogs/AutoChangeLog-pr-9199.yml
deleted file mode 100644
index bf0219c7d9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9199.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - balance: "added a small fire delay (3 ticks) to automatic shotguns"
- - balance: "Reduced buckshot brute damage by 20%. (12.5 -> 10 brute per pellet) (75 -> 60 brute at close range)"
- - balance: "Reduced rubbershot stamina damage by 40% (25 -> 15 stamina per pellet) (150 -> 90 stamina at close range)"
- - balance: "Reduced beanbag stamina damage by 12.5% (80 -> 70 stamina per shot)"
diff --git a/html/changelogs/AutoChangeLog-pr-9200.yml b/html/changelogs/AutoChangeLog-pr-9200.yml
deleted file mode 100644
index d1be09ee4a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9200.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Owai-Seek"
-delete-after: True
-changes:
- - bugfix: "fixed them strawberries"
diff --git a/html/changelogs/AutoChangeLog-pr-9203.yml b/html/changelogs/AutoChangeLog-pr-9203.yml
deleted file mode 100644
index 0ad87d26c1..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9203.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - imageadd: "redid brass tools to look better*"
diff --git a/html/changelogs/AutoChangeLog-pr-9204.yml b/html/changelogs/AutoChangeLog-pr-9204.yml
deleted file mode 100644
index 3b70354fd9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9204.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "/cursed from a item path"
diff --git a/html/changelogs/AutoChangeLog-pr-9208.yml b/html/changelogs/AutoChangeLog-pr-9208.yml
deleted file mode 100644
index 1645164266..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9208.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "colorable socks can be colored again."
diff --git a/html/changelogs/AutoChangeLog-pr-9209.yml b/html/changelogs/AutoChangeLog-pr-9209.yml
deleted file mode 100644
index 5ed81d6856..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9209.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "original by redmoogle, port by sishen1542"
-delete-after: True
-changes:
- - rscadd: "Added support for 3 new gasses; Tritium, Pluoxium, and BZ"
diff --git a/html/changelogs/AutoChangeLog-pr-9210.yml b/html/changelogs/AutoChangeLog-pr-9210.yml
deleted file mode 100644
index b02811e7a8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9210.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "EmeraldSundisk"
-delete-after: True
-changes:
- - tweak: "CentCom has noticed the lack of coffins in Delta Station's chapel and provided some, but in exchange for reducing the chapel morgue's capacity."
- - tweak: "Fixed a maintenance door the chaplain should have been able to open."
- - bugfix: "Fixes space areas outside the driver
-removal: CentCom Defense Analysts have ordered the maintenance hatch to the Mass Driver room be removed citing \"security concerns\"."
diff --git a/html/changelogs/AutoChangeLog-pr-9212.yml b/html/changelogs/AutoChangeLog-pr-9212.yml
deleted file mode 100644
index 48e8b8b4d3..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9212.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "dapnee"
-delete-after: True
-changes:
- - rscadd: "Plasmaglass tables, spears, tiny plasmaglass shards"
- - bugfix: "Plasmaglass structures now drop plasmaglass shards instead of nothing"
diff --git a/html/changelogs/AutoChangeLog-pr-9216.yml b/html/changelogs/AutoChangeLog-pr-9216.yml
deleted file mode 100644
index 0be9314dbc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9216.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "oops not being blacklisted"
diff --git a/html/changelogs/AutoChangeLog-pr-9219.yml b/html/changelogs/AutoChangeLog-pr-9219.yml
deleted file mode 100644
index 138991e507..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9219.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "ports a fix"
diff --git a/html/changelogs/AutoChangeLog-pr-9221.yml b/html/changelogs/AutoChangeLog-pr-9221.yml
deleted file mode 100644
index 0256c4a7c9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9221.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - rscadd: "holy lasrifle, hypertool, divine lightblade, and blessed baseball bat. Four new holy weapons!"
- - balance: "stamina and force tweaks for most holy weapons."
- - tweak: "prayer beads no longer deconvert after a 10 second timer, now just inject holy water for delayed effect"
- - tweak: "cultist runes are now destroyed with a bible or a null rod"
- - tweak: "bo-staff now functions as a nerfed sleepy carp staff"
- - bugfix: "fixed kevinz code to add in non-null rod child items as holy weapons"
diff --git a/html/changelogs/AutoChangeLog-pr-9227.yml b/html/changelogs/AutoChangeLog-pr-9227.yml
deleted file mode 100644
index 9f6bfabdc4..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9227.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "Missing sprites with bad ones"
diff --git a/html/changelogs/AutoChangeLog-pr-9229.yml b/html/changelogs/AutoChangeLog-pr-9229.yml
deleted file mode 100644
index 5c617f6ab0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9229.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "emag charge amount"
diff --git a/html/changelogs/AutoChangeLog-pr-9235.yml b/html/changelogs/AutoChangeLog-pr-9235.yml
deleted file mode 100644
index 112f34a7f0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9235.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Yakumo Chen"
-delete-after: True
-changes:
- - rscdel: "Removes autoscan"
- - balance: "Scanning people now requires someone to operate the cloning computer regardless of part level."
diff --git a/html/changelogs/AutoChangeLog-pr-9238.yml b/html/changelogs/AutoChangeLog-pr-9238.yml
deleted file mode 100644
index b2eb8db233..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9238.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Surgerys and spays in bags"
diff --git a/html/changelogs/AutoChangeLog-pr-9239.yml b/html/changelogs/AutoChangeLog-pr-9239.yml
deleted file mode 100644
index 781dcd82b6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9239.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - tweak: "earthbloods stam regen"
diff --git a/html/changelogs/AutoChangeLog-pr-9241.yml b/html/changelogs/AutoChangeLog-pr-9241.yml
deleted file mode 100644
index 1cb08cd8d0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9241.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Alonefromhell"
-delete-after: True
-changes:
- - rscadd: "Ported Oracle UI, a framework for self-updating and neat UI's"
- - refactor: "Paper now uses OUI"
- - refactor: "Bins now use OUI"
diff --git a/html/changelogs/AutoChangeLog-pr-9242.yml b/html/changelogs/AutoChangeLog-pr-9242.yml
deleted file mode 100644
index 1e47385e67..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9242.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "kappa-sama"
-delete-after: True
-changes:
- - tweak: "blood cult ritual daggers fit in jack/combat boots"
diff --git a/html/changelogs/AutoChangeLog-pr-9247.yml b/html/changelogs/AutoChangeLog-pr-9247.yml
deleted file mode 100644
index 4f6e0b0875..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9247.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fermi"
-delete-after: True
-changes:
- - bugfix: "Fixes tiny runaway decimals in reagents system."
diff --git a/html/changelogs/AutoChangeLog-pr-9248.yml b/html/changelogs/AutoChangeLog-pr-9248.yml
deleted file mode 100644
index 3e6eff727c..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9248.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - imageadd: "Red to Blue/Black crosses as questioned by Bhijn"
diff --git a/html/changelogs/AutoChangeLog-pr-9249.yml b/html/changelogs/AutoChangeLog-pr-9249.yml
deleted file mode 100644
index b2ef0c2d46..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9249.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "clean bot not cleaning basic cleanables"
diff --git a/html/changelogs/AutoChangeLog-pr-9251.yml b/html/changelogs/AutoChangeLog-pr-9251.yml
deleted file mode 100644
index c40c2e05fc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9251.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - tweak: "all chaplain suits can hold the same items in suit storage"
- - code_imp: "improvement to organisation for chaplain suits"
diff --git a/html/changelogs/AutoChangeLog-pr-9256.yml b/html/changelogs/AutoChangeLog-pr-9256.yml
deleted file mode 100644
index dcf039a2a0..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9256.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fermi"
-delete-after: True
-changes:
- - bugfix: "SDGF: Fixes infinite clones."
diff --git a/html/changelogs/AutoChangeLog-pr-9260.yml b/html/changelogs/AutoChangeLog-pr-9260.yml
deleted file mode 100644
index f94d9772f9..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9260.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "dapnee"
-delete-after: True
-changes:
- - rscadd: "Trim lines!"
diff --git a/html/changelogs/AutoChangeLog-pr-9263.yml b/html/changelogs/AutoChangeLog-pr-9263.yml
deleted file mode 100644
index 36a03fa125..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9263.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "new traitor bundle"
diff --git a/html/changelogs/AutoChangeLog-pr-9267.yml b/html/changelogs/AutoChangeLog-pr-9267.yml
deleted file mode 100644
index a894c0d468..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9267.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Tupinambis"
-delete-after: True
-changes:
- - balance: "Engivend RCDs now vend upgraded RCDs"
diff --git a/html/changelogs/AutoChangeLog-pr-9269.yml b/html/changelogs/AutoChangeLog-pr-9269.yml
deleted file mode 100644
index 693588208e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9269.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - tweak: "re-enables femichem explosions in grenades."
- - tweak: "adds nuance to the SDGF and hatmium explosions."
diff --git a/html/changelogs/AutoChangeLog-pr-9275.yml b/html/changelogs/AutoChangeLog-pr-9275.yml
deleted file mode 100644
index cd74273366..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9275.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - bugfix: "Fixes analyse function on ChemMasters to correctly display purity."
- - bugfix: "Fixes the custom transfer for buffer to beaker button."
diff --git a/html/changelogs/AutoChangeLog-pr-9276.yml b/html/changelogs/AutoChangeLog-pr-9276.yml
deleted file mode 100644
index f778c26c13..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9276.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "trash"
- - imageadd: "eye bleed
-:add: misstakes"
diff --git a/html/changelogs/AutoChangeLog-pr-9277.yml b/html/changelogs/AutoChangeLog-pr-9277.yml
deleted file mode 100644
index 4bf92cd32e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9277.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-author: "Poojawa"
-delete-after: True
-changes:
- - rscadd: "Added new wings to Insects and separated fluff from old ones, they're Insect's new body markings now without being per-limb (for now)."
- - rscadd: "Horns are now available to mammals, and they have their own color."
- - rscadd: "Legs are no longer a binary hack code, but actually something that can be changed. Framework for tauric adaptations."
- - rscdel: "Purged Modular Citadel's sprite_accessories."
- - bugfix: "improved the quality of a number of sprites."
- - tweak: "Moths are now all insects. Avians and Aquatics are all anthromorphics. Just as planned."
- - rscadd: "Anthromorphs can choose their preferred gibbing meat. I guess. Snowflakes are weird."
- - bugfix: "Additional Gentlemen names."
diff --git a/html/changelogs/AutoChangeLog-pr-9278.yml b/html/changelogs/AutoChangeLog-pr-9278.yml
deleted file mode 100644
index 3ec1eb839a..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9278.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Spamming forged packets no longer crashes the server."
diff --git a/html/changelogs/AutoChangeLog-pr-9279.yml b/html/changelogs/AutoChangeLog-pr-9279.yml
deleted file mode 100644
index 572f40e643..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9279.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed undergarments color preferences resetting each round."
diff --git a/html/changelogs/AutoChangeLog-pr-9282.yml b/html/changelogs/AutoChangeLog-pr-9282.yml
deleted file mode 100644
index 5a27defb41..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9282.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed a few dozen suits' body coverage inconsistencies. These changes shouldn't affect armor and utility vests for most."
diff --git a/html/changelogs/AutoChangeLog-pr-9283.yml b/html/changelogs/AutoChangeLog-pr-9283.yml
deleted file mode 100644
index 33e02f8539..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9283.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscdel: "Removed old things!"
diff --git a/html/changelogs/AutoChangeLog-pr-9288.yml b/html/changelogs/AutoChangeLog-pr-9288.yml
deleted file mode 100644
index 8a684431bf..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9288.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - bugfix: "UI memes"
diff --git a/html/changelogs/AutoChangeLog-pr-9289.yml b/html/changelogs/AutoChangeLog-pr-9289.yml
deleted file mode 100644
index 7abf947bfc..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9289.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - bugfix: "fixing chems for strained muscles"
diff --git a/html/changelogs/AutoChangeLog-pr-9292.yml b/html/changelogs/AutoChangeLog-pr-9292.yml
deleted file mode 100644
index 33168f9c43..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9292.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed clown shoes and work boots."
diff --git a/html/changelogs/AutoChangeLog-pr-9293.yml b/html/changelogs/AutoChangeLog-pr-9293.yml
deleted file mode 100644
index a99bf1ab41..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9293.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed some overlay bug that happens when legcuffed and then handcuffed."
diff --git a/html/changelogs/AutoChangeLog-pr-9295.yml b/html/changelogs/AutoChangeLog-pr-9295.yml
deleted file mode 100644
index a96540c11b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9295.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - balance: "Slowed down police baton and tele baton speed by 75%, should be still be faster than the legacy speed (2 seconds) by 0.6 seconds. Telescopic batons' stamina cost per swing is now on par with police batons, ergo more expensive."
diff --git a/html/changelogs/AutoChangeLog-pr-9296.yml b/html/changelogs/AutoChangeLog-pr-9296.yml
deleted file mode 100644
index 101ec1aaa8..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9296.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "EmeraldSundisk"
-delete-after: True
-changes:
- - rscadd: "Increases the number of plots to 9 (from 5)"
- - rscadd: "Additional lighting placed directly outside the garden"
- - tweak: "Cleans up the area to reflect use. Moves the seed extractor to a more central location"
- - tweak: "Relocates the seed packs on botany's counter to the garden
-removal: Removes wooden barricades outside the garden"
- - config: "Renames \"Abandoned Garden\" area designation to \"Maintenance Garden\", but does not replace the icon in Dream Maker"
diff --git a/html/changelogs/AutoChangeLog-pr-9298.yml b/html/changelogs/AutoChangeLog-pr-9298.yml
deleted file mode 100644
index 8301acbbd6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9298.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed undershirts n socks colors prefs."
diff --git a/html/changelogs/AutoChangeLog-pr-9302.yml b/html/changelogs/AutoChangeLog-pr-9302.yml
deleted file mode 100644
index 4f6ed4d336..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9302.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "deathride58"
-delete-after: True
-changes:
- - bugfix: "Things that access job_preferences now explicitly access keys, which means it no longer attempts to access invalid indices and runtimes as a result."
diff --git a/html/changelogs/AutoChangeLog-pr-9304.yml b/html/changelogs/AutoChangeLog-pr-9304.yml
deleted file mode 100644
index f4a919c52f..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9304.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Trilbyspaceclone"
-delete-after: True
-changes:
- - rscadd: "Blue space blood bag"
diff --git a/html/changelogs/AutoChangeLog-pr-9306.yml b/html/changelogs/AutoChangeLog-pr-9306.yml
deleted file mode 100644
index 0a560c8090..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9306.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "kappa-sama"
-delete-after: True
-changes:
- - tweak: "voidcells can now unlock alien tech"
- - balance: "rebalanced tech trees (not really)"
diff --git a/html/changelogs/AutoChangeLog-pr-9307.yml b/html/changelogs/AutoChangeLog-pr-9307.yml
deleted file mode 100644
index de787a4274..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9307.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "BurgerLUA"
-delete-after: True
-changes:
- - balance: "Rebalanced special jetpacks."
diff --git a/html/changelogs/AutoChangeLog-pr-9310.yml b/html/changelogs/AutoChangeLog-pr-9310.yml
deleted file mode 100644
index 34ded5a0db..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9310.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "GrayRachnid"
-delete-after: True
-changes:
- - rscadd: "Added windoors to all the flaps on delta."
diff --git a/html/changelogs/AutoChangeLog-pr-9312.yml b/html/changelogs/AutoChangeLog-pr-9312.yml
deleted file mode 100644
index 487b79393b..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9312.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "XDTM"
-delete-after: True
-changes:
- - rscadd: "Added the experimental dissection surgery, which can be performed once per corpse to gain techweb points."
- - rscadd: "Rarer specimens are more valuable, so xenos and rare species are more efficient subjects."
- - rscadd: "Added two new surgery procedures, under the Experimental Surgery techweb node."
- - rscadd: "Ligament Hook makes it so you can attach limbs manually (like skeletons) but makes dismemberment more likely as well."
- - rscadd: "Ligament Reinforcement prevents dismemberment, but makes limbs easier to disable through damage."
- - tweak: "Golem limbs can now be disabled, although they are still undismemberable."
diff --git a/html/changelogs/AutoChangeLog-pr-9317.yml b/html/changelogs/AutoChangeLog-pr-9317.yml
deleted file mode 100644
index 11d58e79ce..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9317.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-author: "Ghommie (original PR by CrazyClown12)"
-delete-after: True
-changes:
- - tweak: "The chloral hydrate inside of the sleepy pen is no longer slower acting than chloral hydrate made in chemistry."
- - tweak: "The chloral hydrate inside of cookies synthesised by emagged borgs is no longer slower acting than chloral hydrate made in chemistry."
- - balance: "Slight tirizene buff."
- - rscdel: "Delayed chloral hydrate"
diff --git a/html/changelogs/AutoChangeLog-pr-9318.yml b/html/changelogs/AutoChangeLog-pr-9318.yml
deleted file mode 100644
index 5f7f4af654..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9318.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - bugfix: "Fixes small residues of chems that won't go away!"
diff --git a/html/changelogs/AutoChangeLog-pr-9320.yml b/html/changelogs/AutoChangeLog-pr-9320.yml
deleted file mode 100644
index 605de17ab2..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9320.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie (original PR by harmonyn)"
-delete-after: True
-changes:
- - balance: "Resisting out of bucklecuffs takes more/less time depending on the handcuffs you used, i.e., fake handcuffs will not bucklecuff someone for ages."
- - tweak: "fake handcuffs shouldn't no longer demoralize restrained criminals scums."
diff --git a/html/changelogs/AutoChangeLog-pr-9321.yml b/html/changelogs/AutoChangeLog-pr-9321.yml
deleted file mode 100644
index d0c4f6d18d..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9321.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Linzolle"
-delete-after: True
-changes:
- - bugfix: "blood halberd not going back to 17 force after unwielding"
- - spellcheck: "unnecessary 's at the end of blood rites healing"
- - rscadd: "QoL to blood rites, examine the ritual aura to view how many blood charges are left"
diff --git a/html/changelogs/AutoChangeLog-pr-9322.yml b/html/changelogs/AutoChangeLog-pr-9322.yml
deleted file mode 100644
index 2d2632bb81..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9322.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Sishen1542"
-delete-after: True
-changes:
- - bugfix: "narsie no longer asks for consent"
diff --git a/html/changelogs/AutoChangeLog-pr-9326.yml b/html/changelogs/AutoChangeLog-pr-9326.yml
deleted file mode 100644
index 582230dedb..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9326.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "YakumoChen"
-delete-after: True
-changes:
- - tweak: "AEGs brought more in line with current radiation system. Try not to get EMP'd."
diff --git a/html/changelogs/AutoChangeLog-pr-9331.yml b/html/changelogs/AutoChangeLog-pr-9331.yml
deleted file mode 100644
index 0ecd5dfad7..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9331.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "You can now alt-click to rotate machinery such as the tachyon-droppler array or emitters again."
diff --git a/html/changelogs/AutoChangeLog-pr-9332.yml b/html/changelogs/AutoChangeLog-pr-9332.yml
deleted file mode 100644
index e8a2aa1faa..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9332.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Sofas can't be wielded and transformed back into plain chairs anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-9334.yml b/html/changelogs/AutoChangeLog-pr-9334.yml
deleted file mode 100644
index cc31ec8896..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9334.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - rscadd: "Enables emojis for PDA messages."
diff --git a/html/changelogs/AutoChangeLog-pr-9335.yml b/html/changelogs/AutoChangeLog-pr-9335.yml
deleted file mode 100644
index b36c0957dd..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9335.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Raptorizer"
-delete-after: True
-changes:
- - tweak: "tweaked numbers/variables"
- - balance: "rebalanced numbers/variables"
- - spellcheck: "removed unneeded code"
diff --git a/html/changelogs/AutoChangeLog-pr-9336.yml b/html/changelogs/AutoChangeLog-pr-9336.yml
deleted file mode 100644
index 3f86da234e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9336.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-author: "Fermis"
-delete-after: True
-changes:
- - tweak: "tweaked beaker health and allows use of syringes/droppers on chem_heaters"
- - soundadd: "added a sound for when beakers take temperature damage."
- - imageadd: "added some icons for melting beakers"
- - refactor: "refactored how beakers take damage"
- - bugfix: "fixes how beakers would only take one instance of damage on pH damage"
diff --git a/html/changelogs/AutoChangeLog-pr-9338.yml b/html/changelogs/AutoChangeLog-pr-9338.yml
deleted file mode 100644
index e5909f52ae..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9338.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "lolman360"
-delete-after: True
-changes:
- - bugfix: "Fixes an undocumented change to the naming of Plasmamen."
diff --git a/html/changelogs/AutoChangeLog-pr-9341.yml b/html/changelogs/AutoChangeLog-pr-9341.yml
deleted file mode 100644
index e017f2941e..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9341.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "Blood cult altar, forge and archives now use radial menus."
diff --git a/html/changelogs/AutoChangeLog-pr-9342.yml b/html/changelogs/AutoChangeLog-pr-9342.yml
deleted file mode 100644
index 75d441f143..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9342.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed some machineries' UIs."
diff --git a/html/changelogs/AutoChangeLog-pr-9344.yml b/html/changelogs/AutoChangeLog-pr-9344.yml
deleted file mode 100644
index c45c9269b6..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9344.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Ghommie (original PRs by Time-Green and Qustinnus)"
-delete-after: True
-changes:
- - tweak: "loot crates can't explode after unlocking anymore"
- - bugfix: "jumping into loot crates no longers causes them to go boom"
- - bugfix: "You can now deconstruct abandoned crates with a welder without making them go boom. After unlocking them, of course."
diff --git a/html/changelogs/AutoChangeLog-pr-9348.yml b/html/changelogs/AutoChangeLog-pr-9348.yml
deleted file mode 100644
index a58556b992..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9348.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - tweak: "blood and clock cultists messages from metabolizing"
diff --git a/html/changelogs/AutoChangeLog-pr-9349.yml b/html/changelogs/AutoChangeLog-pr-9349.yml
deleted file mode 100644
index e51b826f01..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9349.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-author: "Ghommie"
-delete-after: True
-changes:
- - bugfix: "Fixed advanced medical scanners borg upgrades."
- - bugfix: "Fixes certain borg upgrades being unapplicable on dogborg counterparts of the target cyborg type."
diff --git a/html/changelogs/AutoChangeLog-pr-9352.yml b/html/changelogs/AutoChangeLog-pr-9352.yml
deleted file mode 100644
index e34277b531..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9352.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: "JTGSZ"
-delete-after: True
-changes:
- - tweak: "Gave Qualifies_for_Rank Check back its checks in job controller."
diff --git a/html/changelogs/AutoChangeLog-pr-9356.yml b/html/changelogs/AutoChangeLog-pr-9356.yml
deleted file mode 100644
index 65aacda077..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9356.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-author: "EmeraldSundisk"
-delete-after: True
-changes:
- - rscadd: "Expands the chapel mass driver room to make it easier to use"
- - rscadd: "Rearranges the chapel backroom so there are now six coffins and burial garments roundstart"
- - tweak: "Cleans up the Janitor's office"
- - tweak: "Readjusts the station exterior so mass-driven coffins (hopefully) have less friction"
- - bugfix: "Adds a fan to the chapel driver"
- - bugfix: "The Janitor missed a few spots around the newly renovated Maintenance Garden"
diff --git a/html/changelogs/AutoChangeLog-pr-9359.yml b/html/changelogs/AutoChangeLog-pr-9359.yml
deleted file mode 100644
index 1eb933e4c5..0000000000
--- a/html/changelogs/AutoChangeLog-pr-9359.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-author: "Bhijn"
-delete-after: True
-changes:
- - balance: "The point production mode of radiation collectors has been reverted to the original behavior of using all of the stored power every process cycle instead of just 4% of it"
- - tweak: "Radiation collectors now display the amount of power/research points they're producing per minute rather than per process cycle, which should hopefully clear up a lot of confusion."
- - tweak: "Radiation collectors also display what's happening to the gas within them, which should make it a lot more obvious as to how you get tritium."
diff --git a/html/changelogs/AutoChangeLog-pr-9574.yml b/html/changelogs/AutoChangeLog-pr-9574.yml
new file mode 100644
index 0000000000..240d5ad0af
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9574.yml
@@ -0,0 +1,4 @@
+author: "r4d6"
+delete-after: True
+changes:
+ - rscadd: "Added Departements Winter Coats to the loadout list."
diff --git a/html/changelogs/AutoChangeLog-pr-9611.yml b/html/changelogs/AutoChangeLog-pr-9611.yml
new file mode 100644
index 0000000000..48a0e9982b
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9611.yml
@@ -0,0 +1,6 @@
+author: "kevinz000"
+delete-after: True
+changes:
+ - rscadd: "Cargo has passive point generation again at 750 points/minute"
+ - balance: "Mindshield crate price increased from 3000 to 4000"
+ - balance: "Miasma sell price reduced from 15/mol to 4/mol"
diff --git a/html/changelogs/AutoChangeLog-pr-9694.yml b/html/changelogs/AutoChangeLog-pr-9694.yml
new file mode 100644
index 0000000000..6c4842e70e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9694.yml
@@ -0,0 +1,4 @@
+author: "him"
+delete-after: True
+changes:
+ - bugfix: "hos and aeg guns now conform to le epic taser rework standards"
diff --git a/html/changelogs/AutoChangeLog-pr-9695.yml b/html/changelogs/AutoChangeLog-pr-9695.yml
new file mode 100644
index 0000000000..60455c2bb5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9695.yml
@@ -0,0 +1,7 @@
+author: "Ghommie (original PRs by ShizCalev, CRTXBacon and Niknakflak)"
+delete-after: True
+changes:
+ - rscadd: "Adds the intelliLantern, a big ol' spooky intelliCard skin"
+ - rscadd: "crafting recipe for the new intelliCard skin (requires 1 pumpkin, 1 intelliCard, 5 cables and a wirecutter as a tool)"
+ - tweak: "changed the intelliTater crafting recipe to match the intelliLantern recipe (but with a potato for obvious reasons)
+add:cute pai gameboy face :3"
diff --git a/html/changelogs/AutoChangeLog-pr-9696.yml b/html/changelogs/AutoChangeLog-pr-9696.yml
new file mode 100644
index 0000000000..3188173d54
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9696.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Insert snarky remark about clock welders actually displaying the welder flame overlay when turned on now here."
diff --git a/html/changelogs/AutoChangeLog-pr-9704.yml b/html/changelogs/AutoChangeLog-pr-9704.yml
new file mode 100644
index 0000000000..f4c8127241
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9704.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - balance: "Minor ninja tweaks and stealth nerfs. The stealth penalty for the many combat-related actions, bumping and now teleporting/dashing or firing guns has been increased a by a third. There is now a cooldown of 5 seconds on toggling stealth as well as a slighty slowed stealth in/out animation."
diff --git a/html/changelogs/AutoChangeLog-pr-9705.yml b/html/changelogs/AutoChangeLog-pr-9705.yml
new file mode 100644
index 0000000000..c3dafc0582
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9705.yml
@@ -0,0 +1,4 @@
+author: "kappa-sama"
+delete-after: True
+changes:
+ - tweak: "changed flavor text of alien tech on uplink"
diff --git a/html/changelogs/AutoChangeLog-pr-9709.yml b/html/changelogs/AutoChangeLog-pr-9709.yml
new file mode 100644
index 0000000000..73d3164433
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9709.yml
@@ -0,0 +1,5 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - rscadd: "8 new cargo crates!"
+ - tweak: "tablet cargo crate by -3k"
diff --git a/html/changelogs/AutoChangeLog-pr-9710.yml b/html/changelogs/AutoChangeLog-pr-9710.yml
new file mode 100644
index 0000000000..fc815f5255
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9710.yml
@@ -0,0 +1,5 @@
+author: "Trilbyspaceclone"
+delete-after: True
+changes:
+ - admin: "Closes a bunch of issues"
+ - server: "updates changlogs and such"
diff --git a/html/changelogs/AutoChangeLog-pr-8289.yml b/html/changelogs/AutoChangeLog-pr-9713.yml
similarity index 53%
rename from html/changelogs/AutoChangeLog-pr-8289.yml
rename to html/changelogs/AutoChangeLog-pr-9713.yml
index d389d95cd6..fcefecf94d 100644
--- a/html/changelogs/AutoChangeLog-pr-8289.yml
+++ b/html/changelogs/AutoChangeLog-pr-9713.yml
@@ -1,4 +1,4 @@
author: "Trilbyspaceclone"
delete-after: True
changes:
- - tweak: "armor"
+ - bugfix: "fixed a catnip not having sprites"
diff --git a/html/changelogs/AutoChangeLog-pr-9715.yml b/html/changelogs/AutoChangeLog-pr-9715.yml
new file mode 100644
index 0000000000..a7cfb50426
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9715.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - imageadd: "Ported slighty better matchbox sprites from CEV-Eris, also resprited cigar boxes myself."
diff --git a/html/changelogs/AutoChangeLog-pr-9716.yml b/html/changelogs/AutoChangeLog-pr-9716.yml
new file mode 100644
index 0000000000..704b263b50
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9716.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed abductors/abductees objectives by porting an objective code."
diff --git a/html/changelogs/AutoChangeLog-pr-9717.yml b/html/changelogs/AutoChangeLog-pr-9717.yml
new file mode 100644
index 0000000000..7ac1988b74
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9717.yml
@@ -0,0 +1,4 @@
+author: "Putnam3145"
+delete-after: True
+changes:
+ - tweak: "SDGF now copies memories as well as antag data and factions."
diff --git a/html/changelogs/AutoChangeLog-pr-9724.yml b/html/changelogs/AutoChangeLog-pr-9724.yml
new file mode 100644
index 0000000000..853d38b041
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9724.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Fixed free real estate paraplegic trait and bolas."
diff --git a/html/changelogs/AutoChangeLog-pr-9726.yml b/html/changelogs/AutoChangeLog-pr-9726.yml
new file mode 100644
index 0000000000..9e8f3bf71e
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9726.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "fixing a few runtimes on lightgeists, libido trait, rcd, one admin transformation topic, chem dispensers, glowing robotic eyes..."
diff --git a/html/changelogs/AutoChangeLog-pr-9734.yml b/html/changelogs/AutoChangeLog-pr-9734.yml
new file mode 100644
index 0000000000..dd134e480c
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9734.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - imageadd: "Porting CEV-eris delivery packages sprites and dunking the old syndie cybernetics box sprite."
diff --git a/html/changelogs/AutoChangeLog-pr-9168.yml b/html/changelogs/AutoChangeLog-pr-9744.yml
similarity index 51%
rename from html/changelogs/AutoChangeLog-pr-9168.yml
rename to html/changelogs/AutoChangeLog-pr-9744.yml
index 2375f6a28a..a653e77c1a 100644
--- a/html/changelogs/AutoChangeLog-pr-9168.yml
+++ b/html/changelogs/AutoChangeLog-pr-9744.yml
@@ -1,4 +1,4 @@
author: "Seris02"
delete-after: True
changes:
- - rscadd: "Added looc hotkey"
+ - bugfix: "fixed the meteor hallucination"
diff --git a/html/changelogs/AutoChangeLog-pr-9745.yml b/html/changelogs/AutoChangeLog-pr-9745.yml
new file mode 100644
index 0000000000..95a6d943b5
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9745.yml
@@ -0,0 +1,4 @@
+author: "Ghommie"
+delete-after: True
+changes:
+ - bugfix: "Certain objects shouldn't be able to become radioactive because of a bitflag that previously was checked nowhere in the code anymore."
diff --git a/html/changelogs/AutoChangeLog-pr-9746.yml b/html/changelogs/AutoChangeLog-pr-9746.yml
new file mode 100644
index 0000000000..e4b1c312ea
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-9746.yml
@@ -0,0 +1,4 @@
+author: "actioninja"
+delete-after: True
+changes:
+ - bugfix: "med records no longer can eat id cards for no reason"
diff --git a/icons/effects/blood.dmi b/icons/effects/blood.dmi
index 6a1a35f326..5bc30f886c 100644
Binary files a/icons/effects/blood.dmi and b/icons/effects/blood.dmi differ
diff --git a/icons/effects/fluidtracks.dmi b/icons/effects/fluidtracks.dmi
new file mode 100644
index 0000000000..e2f0c97479
Binary files /dev/null and b/icons/effects/fluidtracks.dmi differ
diff --git a/icons/effects/footprints.dmi b/icons/effects/footprints.dmi
index a98344abe4..69207097c0 100644
Binary files a/icons/effects/footprints.dmi and b/icons/effects/footprints.dmi differ
diff --git a/icons/mecha/neovgre.dmi b/icons/mecha/neovgre.dmi
new file mode 100644
index 0000000000..ba9d57daf9
Binary files /dev/null and b/icons/mecha/neovgre.dmi differ
diff --git a/icons/mob/AI.dmi b/icons/mob/AI.dmi
index 7de8152118..bdf54e36e5 100644
Binary files a/icons/mob/AI.dmi and b/icons/mob/AI.dmi differ
diff --git a/icons/mob/actions.dmi b/icons/mob/actions.dmi
index 4e23c102ce..e6e0abe111 100644
Binary files a/icons/mob/actions.dmi and b/icons/mob/actions.dmi differ
diff --git a/icons/mob/actions/actions_AI.dmi b/icons/mob/actions/actions_AI.dmi
index 2ddc7923cc..e3ff3aba93 100644
Binary files a/icons/mob/actions/actions_AI.dmi and b/icons/mob/actions/actions_AI.dmi differ
diff --git a/icons/mob/actions/backgrounds.dmi b/icons/mob/actions/backgrounds.dmi
index 82303c5862..3697fe4ff5 100644
Binary files a/icons/mob/actions/backgrounds.dmi and b/icons/mob/actions/backgrounds.dmi differ
diff --git a/icons/mob/aibots.dmi b/icons/mob/aibots.dmi
index f4049abc41..5f5987f2d3 100644
Binary files a/icons/mob/aibots.dmi and b/icons/mob/aibots.dmi differ
diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi
index 2a85f8a422..a46ad83640 100644
Binary files a/icons/mob/animal.dmi and b/icons/mob/animal.dmi differ
diff --git a/icons/mob/augmentation/augments.dmi b/icons/mob/augmentation/augments.dmi
index 574a5ddc48..e311b6605d 100644
Binary files a/icons/mob/augmentation/augments.dmi and b/icons/mob/augmentation/augments.dmi differ
diff --git a/icons/mob/augmentation/augments_engineer.dmi b/icons/mob/augmentation/augments_engineer.dmi
index 7f2b2e8de9..8aac118b35 100644
Binary files a/icons/mob/augmentation/augments_engineer.dmi and b/icons/mob/augmentation/augments_engineer.dmi differ
diff --git a/icons/mob/augmentation/augments_mining.dmi b/icons/mob/augmentation/augments_mining.dmi
index 39df4823fd..61d8cc30e5 100644
Binary files a/icons/mob/augmentation/augments_mining.dmi and b/icons/mob/augmentation/augments_mining.dmi differ
diff --git a/icons/mob/augmentation/augments_security.dmi b/icons/mob/augmentation/augments_security.dmi
index 2679f7c9f8..e954c6e22a 100644
Binary files a/icons/mob/augmentation/augments_security.dmi and b/icons/mob/augmentation/augments_security.dmi differ
diff --git a/icons/mob/augmentation/surplus_augments.dmi b/icons/mob/augmentation/surplus_augments.dmi
index bc3e4bd73c..d2eb194c28 100644
Binary files a/icons/mob/augmentation/surplus_augments.dmi and b/icons/mob/augmentation/surplus_augments.dmi differ
diff --git a/icons/mob/back.dmi b/icons/mob/back.dmi
index b22f50623c..26f81b70df 100644
Binary files a/icons/mob/back.dmi and b/icons/mob/back.dmi differ
diff --git a/icons/mob/custom_w.dmi b/icons/mob/custom_w.dmi
index 1b917d9434..b572338fc6 100644
Binary files a/icons/mob/custom_w.dmi and b/icons/mob/custom_w.dmi differ
diff --git a/icons/mob/dam_mob.dmi b/icons/mob/dam_mob.dmi
index fe92746b43..c34b57b434 100644
Binary files a/icons/mob/dam_mob.dmi and b/icons/mob/dam_mob.dmi differ
diff --git a/icons/mob/eyes.dmi b/icons/mob/eyes.dmi
index 6cce82b5f7..b981a18f06 100644
Binary files a/icons/mob/eyes.dmi and b/icons/mob/eyes.dmi differ
diff --git a/icons/mob/feet.dmi b/icons/mob/feet.dmi
index 118688aaba..c57a7cc112 100644
Binary files a/icons/mob/feet.dmi and b/icons/mob/feet.dmi differ
diff --git a/icons/mob/head.dmi b/icons/mob/head.dmi
index 25183c5cea..1c477e968f 100644
Binary files a/icons/mob/head.dmi and b/icons/mob/head.dmi differ
diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi
index 10474f94da..164fabe806 100644
Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ
diff --git a/icons/mob/human_parts.dmi b/icons/mob/human_parts.dmi
index 6bd504674f..916686e63f 100644
Binary files a/icons/mob/human_parts.dmi and b/icons/mob/human_parts.dmi differ
diff --git a/icons/mob/human_parts_greyscale.dmi b/icons/mob/human_parts_greyscale.dmi
index 8b894fea6b..ab30929727 100644
Binary files a/icons/mob/human_parts_greyscale.dmi and b/icons/mob/human_parts_greyscale.dmi differ
diff --git a/icons/mob/inhands/64x64_righthand.dmi b/icons/mob/inhands/64x64_righthand.dmi
index bbeddf9152..3750e28906 100644
Binary files a/icons/mob/inhands/64x64_righthand.dmi and b/icons/mob/inhands/64x64_righthand.dmi differ
diff --git a/icons/mob/inhands/misc/tiles_lefthand.dmi b/icons/mob/inhands/misc/tiles_lefthand.dmi
new file mode 100644
index 0000000000..d7903fcd48
Binary files /dev/null and b/icons/mob/inhands/misc/tiles_lefthand.dmi differ
diff --git a/icons/mob/inhands/misc/tiles_righthand.dmi b/icons/mob/inhands/misc/tiles_righthand.dmi
new file mode 100644
index 0000000000..9295ac7344
Binary files /dev/null and b/icons/mob/inhands/misc/tiles_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/hammers_lefthand.dmi b/icons/mob/inhands/weapons/hammers_lefthand.dmi
index 0ea340f1f3..306fd0db8a 100644
Binary files a/icons/mob/inhands/weapons/hammers_lefthand.dmi and b/icons/mob/inhands/weapons/hammers_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/hammers_righthand.dmi b/icons/mob/inhands/weapons/hammers_righthand.dmi
index dbe34513ea..674e4d510b 100644
Binary files a/icons/mob/inhands/weapons/hammers_righthand.dmi and b/icons/mob/inhands/weapons/hammers_righthand.dmi differ
diff --git a/icons/mob/inhands/weapons/swords_lefthand.dmi b/icons/mob/inhands/weapons/swords_lefthand.dmi
index d306e22892..2169b87580 100644
Binary files a/icons/mob/inhands/weapons/swords_lefthand.dmi and b/icons/mob/inhands/weapons/swords_lefthand.dmi differ
diff --git a/icons/mob/inhands/weapons/swords_righthand.dmi b/icons/mob/inhands/weapons/swords_righthand.dmi
index 3e0c3424d3..f054d8f744 100644
Binary files a/icons/mob/inhands/weapons/swords_righthand.dmi and b/icons/mob/inhands/weapons/swords_righthand.dmi differ
diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi
index 9beedfb417..4de67f41f8 100644
Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
index 8142e03498..d724747a50 100644
Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ
diff --git a/icons/mob/screen_cyborg.dmi b/icons/mob/screen_cyborg.dmi
index 7c64ace299..632443036e 100644
Binary files a/icons/mob/screen_cyborg.dmi and b/icons/mob/screen_cyborg.dmi differ
diff --git a/icons/mob/suit.dmi b/icons/mob/suit.dmi
index 740ad43d42..b0fb5984c3 100644
Binary files a/icons/mob/suit.dmi and b/icons/mob/suit.dmi differ
diff --git a/icons/mob/uniform.dmi b/icons/mob/uniform.dmi
index 2506d9e629..072511b444 100644
Binary files a/icons/mob/uniform.dmi and b/icons/mob/uniform.dmi differ
diff --git a/icons/mob/wings.dmi b/icons/mob/wings.dmi
index 58f4cb735c..105da7d865 100644
Binary files a/icons/mob/wings.dmi and b/icons/mob/wings.dmi differ
diff --git a/icons/obj/1x2.dmi b/icons/obj/1x2.dmi
new file mode 100644
index 0000000000..ec3bcac2fa
Binary files /dev/null and b/icons/obj/1x2.dmi differ
diff --git a/icons/obj/aicards.dmi b/icons/obj/aicards.dmi
index e03e5d9567..8e846c3796 100644
Binary files a/icons/obj/aicards.dmi and b/icons/obj/aicards.dmi differ
diff --git a/icons/obj/barsigns.dmi b/icons/obj/barsigns.dmi
index 2c4d401088..1fffa2e540 100644
Binary files a/icons/obj/barsigns.dmi and b/icons/obj/barsigns.dmi differ
diff --git a/icons/obj/bloodbank.dmi b/icons/obj/bloodbank.dmi
new file mode 100644
index 0000000000..4b4b2b6990
Binary files /dev/null and b/icons/obj/bloodbank.dmi differ
diff --git a/icons/obj/card.dmi b/icons/obj/card.dmi
index 507801844c..a3b0d19df4 100644
Binary files a/icons/obj/card.dmi and b/icons/obj/card.dmi differ
diff --git a/icons/obj/chemical.dmi b/icons/obj/chemical.dmi
index 5b9e13ed52..89acf0645e 100644
Binary files a/icons/obj/chemical.dmi and b/icons/obj/chemical.dmi differ
diff --git a/icons/obj/cigarettes.dmi b/icons/obj/cigarettes.dmi
index 0f0433be7f..5c55efd67f 100644
Binary files a/icons/obj/cigarettes.dmi and b/icons/obj/cigarettes.dmi differ
diff --git a/icons/obj/citvending.dmi b/icons/obj/citvending.dmi
index 37c2c8fcf1..8f836b7eb5 100644
Binary files a/icons/obj/citvending.dmi and b/icons/obj/citvending.dmi differ
diff --git a/icons/obj/closet.dmi b/icons/obj/closet.dmi
index 1b8eada39c..d3f055d1f2 100644
Binary files a/icons/obj/closet.dmi and b/icons/obj/closet.dmi differ
diff --git a/icons/obj/clothing/glasses.dmi b/icons/obj/clothing/glasses.dmi
index 2cdf97bd37..75a03a585c 100644
Binary files a/icons/obj/clothing/glasses.dmi and b/icons/obj/clothing/glasses.dmi differ
diff --git a/icons/obj/clothing/hats.dmi b/icons/obj/clothing/hats.dmi
index 77029e36b6..aa2129f686 100644
Binary files a/icons/obj/clothing/hats.dmi and b/icons/obj/clothing/hats.dmi differ
diff --git a/icons/obj/clothing/shoes.dmi b/icons/obj/clothing/shoes.dmi
index a042f30ea3..e3a9f6d84e 100644
Binary files a/icons/obj/clothing/shoes.dmi and b/icons/obj/clothing/shoes.dmi differ
diff --git a/icons/obj/clothing/suits.dmi b/icons/obj/clothing/suits.dmi
index dc5fa1399d..852638bc3d 100644
Binary files a/icons/obj/clothing/suits.dmi and b/icons/obj/clothing/suits.dmi differ
diff --git a/icons/obj/clothing/uniforms.dmi b/icons/obj/clothing/uniforms.dmi
index b456f31a95..50f9e0a207 100644
Binary files a/icons/obj/clothing/uniforms.dmi and b/icons/obj/clothing/uniforms.dmi differ
diff --git a/icons/obj/computer.dmi b/icons/obj/computer.dmi
index c3374e9c1c..74ca148039 100644
Binary files a/icons/obj/computer.dmi and b/icons/obj/computer.dmi differ
diff --git a/icons/obj/crates.dmi b/icons/obj/crates.dmi
index 3ab7f4b510..ca81686e94 100644
Binary files a/icons/obj/crates.dmi and b/icons/obj/crates.dmi differ
diff --git a/icons/obj/custom.dmi b/icons/obj/custom.dmi
index 601e32fb63..bbb813d7c9 100644
Binary files a/icons/obj/custom.dmi and b/icons/obj/custom.dmi differ
diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi
index 032b0c27ad..db0e5a301a 100644
Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ
diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi
index f9c1a197e7..e8b3d434f5 100644
Binary files a/icons/obj/drinks.dmi and b/icons/obj/drinks.dmi differ
diff --git a/icons/obj/food/food.dmi b/icons/obj/food/food.dmi
index 75df4b5cc5..2ea48828d2 100644
Binary files a/icons/obj/food/food.dmi and b/icons/obj/food/food.dmi differ
diff --git a/icons/obj/guns/energy.dmi b/icons/obj/guns/energy.dmi
index a6d5c8a5e1..ca339b5262 100644
Binary files a/icons/obj/guns/energy.dmi and b/icons/obj/guns/energy.dmi differ
diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi
index 0831d47577..6b2d9e5c06 100644
Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ
diff --git a/icons/obj/halloween_items.dmi b/icons/obj/halloween_items.dmi
index c08ea71148..b4f11165dc 100644
Binary files a/icons/obj/halloween_items.dmi and b/icons/obj/halloween_items.dmi differ
diff --git a/icons/obj/hydroponics/growing_flowers.dmi b/icons/obj/hydroponics/growing_flowers.dmi
index 2f541dfc9b..245841a6b4 100644
Binary files a/icons/obj/hydroponics/growing_flowers.dmi and b/icons/obj/hydroponics/growing_flowers.dmi differ
diff --git a/icons/obj/hydroponics/growing_fruits.dmi b/icons/obj/hydroponics/growing_fruits.dmi
index 029d49e196..dfcb54b7b9 100644
Binary files a/icons/obj/hydroponics/growing_fruits.dmi and b/icons/obj/hydroponics/growing_fruits.dmi differ
diff --git a/icons/obj/hydroponics/harvest.dmi b/icons/obj/hydroponics/harvest.dmi
index 7796e1b199..63dc8b98fd 100644
Binary files a/icons/obj/hydroponics/harvest.dmi and b/icons/obj/hydroponics/harvest.dmi differ
diff --git a/icons/obj/hydroponics/seeds.dmi b/icons/obj/hydroponics/seeds.dmi
index 96fd5be650..3c625cbe40 100644
Binary files a/icons/obj/hydroponics/seeds.dmi and b/icons/obj/hydroponics/seeds.dmi differ
diff --git a/icons/obj/items_and_weapons.dmi b/icons/obj/items_and_weapons.dmi
index 6336669501..e41135b446 100644
Binary files a/icons/obj/items_and_weapons.dmi and b/icons/obj/items_and_weapons.dmi differ
diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi
index f28b8be5c5..20e0f5f73c 100644
Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ
diff --git a/icons/obj/machines/dominator.dmi b/icons/obj/machines/dominator.dmi
index 42337dc1c8..3718fc4f83 100644
Binary files a/icons/obj/machines/dominator.dmi and b/icons/obj/machines/dominator.dmi differ
diff --git a/icons/obj/machines/mining_machines.dmi b/icons/obj/machines/mining_machines.dmi
index 28d608125d..aa60e7100c 100644
Binary files a/icons/obj/machines/mining_machines.dmi and b/icons/obj/machines/mining_machines.dmi differ
diff --git a/icons/obj/machines/teleporter.dmi b/icons/obj/machines/teleporter.dmi
index 1d3c97199b..08c014af8f 100644
Binary files a/icons/obj/machines/teleporter.dmi and b/icons/obj/machines/teleporter.dmi differ
diff --git a/icons/obj/mining.dmi b/icons/obj/mining.dmi
index 6e05bf548b..a7593e4a55 100644
Binary files a/icons/obj/mining.dmi and b/icons/obj/mining.dmi differ
diff --git a/icons/obj/nuke_tools.dmi b/icons/obj/nuke_tools.dmi
index 2c10b5424f..799c4baabb 100644
Binary files a/icons/obj/nuke_tools.dmi and b/icons/obj/nuke_tools.dmi differ
diff --git a/icons/obj/objects.dmi b/icons/obj/objects.dmi
index 647722b1de..87db0caa67 100644
Binary files a/icons/obj/objects.dmi and b/icons/obj/objects.dmi differ
diff --git a/icons/obj/reagentfillings.dmi b/icons/obj/reagentfillings.dmi
index 1b8dacf36d..eb3ca4b2f7 100644
Binary files a/icons/obj/reagentfillings.dmi and b/icons/obj/reagentfillings.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table_blue.dmi b/icons/obj/smooth_structures/fancy_table_blue.dmi
new file mode 100644
index 0000000000..07e13e99e6
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table_blue.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table_cyan.dmi b/icons/obj/smooth_structures/fancy_table_cyan.dmi
new file mode 100644
index 0000000000..4f1a90e33b
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table_cyan.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table_green.dmi b/icons/obj/smooth_structures/fancy_table_green.dmi
new file mode 100644
index 0000000000..ea7f8daa99
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table_green.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table_orange.dmi b/icons/obj/smooth_structures/fancy_table_orange.dmi
new file mode 100644
index 0000000000..fe0375ddbb
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table_orange.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table_purple.dmi b/icons/obj/smooth_structures/fancy_table_purple.dmi
new file mode 100644
index 0000000000..c404a9eb5f
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table_purple.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table_red.dmi b/icons/obj/smooth_structures/fancy_table_red.dmi
new file mode 100644
index 0000000000..8bca0ca8c9
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table_red.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table_royalblack.dmi b/icons/obj/smooth_structures/fancy_table_royalblack.dmi
new file mode 100644
index 0000000000..064b7c1945
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table_royalblack.dmi differ
diff --git a/icons/obj/smooth_structures/fancy_table_royalblue.dmi b/icons/obj/smooth_structures/fancy_table_royalblue.dmi
new file mode 100644
index 0000000000..9d0eba7265
Binary files /dev/null and b/icons/obj/smooth_structures/fancy_table_royalblue.dmi differ
diff --git a/icons/obj/sofa.dmi b/icons/obj/sofa.dmi
index dafe06a7f1..069fb1e08d 100644
Binary files a/icons/obj/sofa.dmi and b/icons/obj/sofa.dmi differ
diff --git a/icons/obj/storage.dmi b/icons/obj/storage.dmi
index fae8134791..fedb6c828e 100644
Binary files a/icons/obj/storage.dmi and b/icons/obj/storage.dmi differ
diff --git a/icons/obj/structures.dmi b/icons/obj/structures.dmi
index 2e1fdfa7a8..dd8f7bed1d 100644
Binary files a/icons/obj/structures.dmi and b/icons/obj/structures.dmi differ
diff --git a/icons/obj/surgery.dmi b/icons/obj/surgery.dmi
index eed8ee64e7..fcc28de7b9 100755
Binary files a/icons/obj/surgery.dmi and b/icons/obj/surgery.dmi differ
diff --git a/icons/obj/syringe.dmi b/icons/obj/syringe.dmi
index 59bc7a8e7c..b474dc68ba 100644
Binary files a/icons/obj/syringe.dmi and b/icons/obj/syringe.dmi differ
diff --git a/icons/obj/tiles.dmi b/icons/obj/tiles.dmi
index 9305e4b7bc..3aa6912da7 100644
Binary files a/icons/obj/tiles.dmi and b/icons/obj/tiles.dmi differ
diff --git a/icons/obj/tools.dmi b/icons/obj/tools.dmi
index 6130c67eb3..efd7974897 100644
Binary files a/icons/obj/tools.dmi and b/icons/obj/tools.dmi differ
diff --git a/icons/obj/turnstile.dmi b/icons/obj/turnstile.dmi
new file mode 100644
index 0000000000..0107ade705
Binary files /dev/null and b/icons/obj/turnstile.dmi differ
diff --git a/icons/turf/areas.dmi b/icons/turf/areas.dmi
index 01cb909d27..992b37cc3d 100644
Binary files a/icons/turf/areas.dmi and b/icons/turf/areas.dmi differ
diff --git a/icons/turf/floors/carpet_blue.dmi b/icons/turf/floors/carpet_blue.dmi
new file mode 100644
index 0000000000..f797be9745
Binary files /dev/null and b/icons/turf/floors/carpet_blue.dmi differ
diff --git a/icons/turf/floors/carpet_cyan.dmi b/icons/turf/floors/carpet_cyan.dmi
new file mode 100644
index 0000000000..feca351ca9
Binary files /dev/null and b/icons/turf/floors/carpet_cyan.dmi differ
diff --git a/icons/turf/floors/carpet_green.dmi b/icons/turf/floors/carpet_green.dmi
new file mode 100644
index 0000000000..fdd1f071f7
Binary files /dev/null and b/icons/turf/floors/carpet_green.dmi differ
diff --git a/icons/turf/floors/carpet_orange.dmi b/icons/turf/floors/carpet_orange.dmi
new file mode 100644
index 0000000000..ddf239b63b
Binary files /dev/null and b/icons/turf/floors/carpet_orange.dmi differ
diff --git a/icons/turf/floors/carpet_purple.dmi b/icons/turf/floors/carpet_purple.dmi
new file mode 100644
index 0000000000..c1f40ec7fa
Binary files /dev/null and b/icons/turf/floors/carpet_purple.dmi differ
diff --git a/icons/turf/floors/carpet_red.dmi b/icons/turf/floors/carpet_red.dmi
new file mode 100644
index 0000000000..926655688e
Binary files /dev/null and b/icons/turf/floors/carpet_red.dmi differ
diff --git a/icons/turf/floors/carpet_royalblack.dmi b/icons/turf/floors/carpet_royalblack.dmi
new file mode 100644
index 0000000000..bc5cef1cf0
Binary files /dev/null and b/icons/turf/floors/carpet_royalblack.dmi differ
diff --git a/icons/turf/floors/carpet_royalblue.dmi b/icons/turf/floors/carpet_royalblue.dmi
new file mode 100644
index 0000000000..841e49e957
Binary files /dev/null and b/icons/turf/floors/carpet_royalblue.dmi differ
diff --git a/icons/turf/space.dmi b/icons/turf/space.dmi
index d32279e704..33e3fab9a4 100644
Binary files a/icons/turf/space.dmi and b/icons/turf/space.dmi differ
diff --git a/icons/turf/walls.dmi b/icons/turf/walls.dmi
index 3290e3f92c..dd6c7f3a7c 100644
Binary files a/icons/turf/walls.dmi and b/icons/turf/walls.dmi differ
diff --git a/interface/interface.dm b/interface/interface.dm
index 8a4ba5b96b..215765c88d 100644
--- a/interface/interface.dm
+++ b/interface/interface.dm
@@ -4,11 +4,15 @@
set desc = "Type what you want to know about. This will open the wiki in your web browser. Type nothing to go to the main page."
set hidden = 1
var/wikiurl = CONFIG_GET(string/wikiurl)
+ var/wikiurltg = CONFIG_GET(string/wikiurltg)
if(wikiurl)
if(query)
- var/output = wikiurl + "/index.php?title=Special%3ASearch&profile=default&search=" + query
+ var/output = wikiurl + "?search=" + query
+ src << link(output)
+ output = wikiurltg + "/index.php?title=Special%3ASearch&profile=default&search=" + query
src << link(output)
else if (query != null)
+ src << link(wikiurltg)
src << link(wikiurl)
else
to_chat(src, "The wiki URL is not set in the server configuration. ")
diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm
index 2ecd9f9004..c51778bbdb 100644
--- a/interface/stylesheet.dm
+++ b/interface/stylesheet.dm
@@ -153,6 +153,7 @@ h1.alert, h2.alert {color: #000000;}
.redtext {color: #FF0000; font-size: 3;}
.clown {color: #FF69Bf; font-size: 3; font-family: "Comic Sans MS", cursive, sans-serif; font-weight: bold;}
.his_grace {color: #15D512; font-family: "Courier New", cursive, sans-serif; font-style: italic;}
+.spooky {color: #FF9100;}
.velvet {color: #660015; font-weight: bold; animation: velvet 5000ms infinite;}
@keyframes velvet {
0% { color: #400020; }
diff --git a/modular_citadel/code/controllers/subsystem/shuttle.dm b/modular_citadel/code/controllers/subsystem/shuttle.dm
index ce3f062bdd..567b23f202 100644
--- a/modular_citadel/code/controllers/subsystem/shuttle.dm
+++ b/modular_citadel/code/controllers/subsystem/shuttle.dm
@@ -1,7 +1,7 @@
/datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end after 2 hours have passed.
if((world.realtime - SSshuttle.realtimeofstart) > auto_call && EMERGENCY_IDLE_OR_RECALLED) //2 hours
SSshuttle.emergency.request(silent = TRUE)
- priority_announce("The shift has come to an end and the shuttle called. [seclevel2num(get_security_level()) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, 'sound/ai/shuttlecalled.ogg', "Priority")
+ priority_announce("The shift has come to an end and the shuttle called. [seclevel2num(get_security_level()) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, "shuttlecalled", "Priority")
log_game("Round time limit reached. Shuttle has been auto-called.")
message_admins("Round time limit reached. Shuttle called.")
emergencyNoRecall = TRUE
diff --git a/modular_citadel/code/datums/components/phantomthief.dm b/modular_citadel/code/datums/components/phantomthief.dm
deleted file mode 100644
index d34e16f6e9..0000000000
--- a/modular_citadel/code/datums/components/phantomthief.dm
+++ /dev/null
@@ -1,49 +0,0 @@
-//This component applies a customizable drop_shadow filter to its wearer when they toggle combat mode on or off. This can stack.
-
-/datum/component/phantomthief
- dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS
-
- var/filter_x
- var/filter_y
- var/filter_size
- var/filter_border
- var/filter_color
-
- var/datum/component/redirect/combattoggle_redir
-
-/datum/component/phantomthief/Initialize(_x = -2, _y = 0, _size = 0, _border = 0, _color = "#E62111")
- filter_x = _x
- filter_y = _y
- filter_size = _size
- filter_border = _border
- filter_color = _color
-
- RegisterSignal(parent, COMSIG_COMBAT_TOGGLED, .proc/handlefilterstuff)
- RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, .proc/OnEquipped)
- RegisterSignal(parent, COMSIG_ITEM_DROPPED, .proc/OnDropped)
-
-/datum/component/phantomthief/proc/handlefilterstuff(mob/user, combatmodestate)
- if(istype(user))
- var/thefilter = filter(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, border = filter_border, color = filter_color)
- if(!combatmodestate)
- user.filters -= thefilter
- else
- user.filters += thefilter
-
-/datum/component/phantomthief/proc/stripdesiredfilter(mob/user)
- if(istype(user))
- var/thefilter = filter(type = "drop_shadow", x = filter_x, y = filter_y, size = filter_size, border = filter_border, color = filter_color)
- user.filters -= thefilter
-
-/datum/component/phantomthief/proc/OnEquipped(mob/user, slot)
- if(!istype(user))
- return
- if(!combattoggle_redir)
- combattoggle_redir = user.AddComponent(/datum/component/redirect, list(COMSIG_COMBAT_TOGGLED = CALLBACK(src, .proc/handlefilterstuff)))
-
-/datum/component/phantomthief/proc/OnDropped(mob/user)
- if(!istype(user))
- return
- if(combattoggle_redir)
- QDEL_NULL(combattoggle_redir)
- stripdesiredfilter(user)
diff --git a/modular_citadel/code/datums/components/souldeath.dm b/modular_citadel/code/datums/components/souldeath.dm
index 5beddf3529..ab45210a46 100644
--- a/modular_citadel/code/datums/components/souldeath.dm
+++ b/modular_citadel/code/datums/components/souldeath.dm
@@ -29,7 +29,7 @@
if(!wearer)
return //idfk
new/obj/effect/temp_visual/souldeath(wearer.loc, wearer)
- playsound(wearer, 'modular_citadel/sound/misc/souldeath.ogg', 100, FALSE)
+ playsound(wearer, 'sound/misc/souldeath.ogg', 100, FALSE)
/datum/component/souldeath/neck
equip_slot = SLOT_NECK
diff --git a/modular_citadel/code/datums/mood_events/moodular.dm b/modular_citadel/code/datums/mood_events/moodular.dm
index aa87f1b97a..ee502c7b39 100644
--- a/modular_citadel/code/datums/mood_events/moodular.dm
+++ b/modular_citadel/code/datums/mood_events/moodular.dm
@@ -18,7 +18,7 @@
// Jack the Ripper starring plush
/obj/item/toy/plush/attackby(obj/item/I, mob/living/user, params)
. = ..()
- if(I.is_sharp())
+ if(I.get_sharpness())
if(!grenade)
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT,"plushjack", /datum/mood_event/plushjack)
diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm
index 4bc83d2af6..abf68cc398 100644
--- a/modular_citadel/code/datums/status_effects/chems.dm
+++ b/modular_citadel/code/datums/status_effects/chems.dm
@@ -37,64 +37,62 @@
alert_type = null
var/moveCalc = 1
var/cachedmoveCalc = 1
+ var/last_checked_size //used to prevent potential cpu waste from happening every tick.
-/datum/status_effect/chem/breast_enlarger/on_apply(mob/living/carbon/human/H)//Removes clothes, they're too small to contain you. You belong to space now.
+/datum/status_effect/chem/breast_enlarger/on_apply()//Removes clothes, they're too small to contain you. You belong to space now.
log_game("FERMICHEM: [owner]'s breasts has reached comical sizes. ID: [owner.key]")
- var/mob/living/carbon/human/o = owner
- var/items = o.get_contents()
- for(var/obj/item/W in items)
- if(W == o.w_uniform || W == o.wear_suit)
- o.dropItemToGround(W, TRUE)
- playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
- to_chat(o, "Your clothes give, ripping into peices under the strain of your swelling breasts! Unless you manage to reduce the size of your breasts, there's no way you're going to be able to put anything on over these melons..! ")
- o.visible_message("[o]'s chest suddenly bursts forth, ripping their clothes off!' ")
- else
- to_chat(o, "Your bountiful bosom is so rich with mass, you seriously doubt you'll be able to fit any clothes over it. ")
- return ..()
+ var/mob/living/carbon/human/H = owner
+ var/message = FALSE
+ if(H.w_uniform)
+ H.dropItemToGround(H.w_uniform, TRUE)
+ message = TRUE
+ if(H.wear_suit)
+ H.dropItemToGround(H.wear_suit, TRUE)
+ message = TRUE
+ if(message)
+ playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
+ H.visible_message("[H]'s chest suddenly bursts forth, ripping their clothes off!' ", \
+ "Your clothes give, ripping into peices under the strain of your swelling breasts! Unless you manage to reduce the size of your breasts, there's no way you're going to be able to put anything on over these melons..! ")
+ else
+ to_chat(H, "Your bountiful bosom is so rich with mass, you seriously doubt you'll be able to fit any clothes over it. ")
+ return ..()
-/datum/status_effect/chem/breast_enlarger/tick(mob/living/carbon/human/H)//If you try to wear clothes, you fail. Slows you down if you're comically huge
- var/mob/living/carbon/human/o = owner
- var/obj/item/organ/genital/breasts/B = o.getorganslot("breasts")
- moveCalc = 1+((round(B.cached_size) - 9)/3) //Afffects how fast you move, and how often you can click.
+/datum/status_effect/chem/breast_enlarger/tick()//If you try to wear clothes, you fail. Slows you down if you're comically huge
+ var/mob/living/carbon/human/H = owner
+ var/obj/item/organ/genital/breasts/B = H.getorganslot(ORGAN_SLOT_BREASTS)
if(!B)
- o.remove_movespeed_modifier(BREAST_MOVEMENT_SPEED)
- sizeMoveMod(1)
- owner.remove_status_effect(src)
- var/items = o.get_contents()
- for(var/obj/item/W in items)
- if(W == o.w_uniform || W == o.wear_suit)
- o.dropItemToGround(W, TRUE)
- playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
- to_chat(owner, "Your enormous breasts are way too large to fit anything over them! ")
+ H.remove_status_effect(src)
+ return
+ moveCalc = 1+((round(B.cached_size) - 9)/3) //Afffects how fast you move, and how often you can click.
+ var/message = FALSE
+ if(H.w_uniform)
+ H.dropItemToGround(H.w_uniform, TRUE)
+ message = TRUE
+ if(H.wear_suit)
+ H.dropItemToGround(H.wear_suit, TRUE)
+ message = TRUE
+ if(message)
+ playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
+ to_chat(H, "Your enormous breasts are way too large to fit anything over them! ")
+
+ if(last_checked_size != B.cached_size)
+ H.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
+ sizeMoveMod(moveCalc)
+
if (B.size == "huge")
if(prob(1))
to_chat(owner, "Your back is feeling sore. ")
- var/target = o.get_bodypart(BODY_ZONE_CHEST)
- o.apply_damage(0.1, BRUTE, target)
- if(!B.cached_size == B.breast_values[B.prev_size])
- o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
- sizeMoveMod(moveCalc)
- return ..()
- else if (B.breast_values[B.size] > B.breast_values[B.prev_size])
- o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
- sizeMoveMod(moveCalc)
- else if (B.breast_values[B.size] < B.breast_values[B.prev_size])
- o.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
- sizeMoveMod(moveCalc)
- if((B.cached_size) < 16)
- switch(round(B.cached_size))
- if(9)
- if (B.breast_values[B.prev_size] != B.breast_values[B.size])
- to_chat(o, "Your expansive chest has become a more managable size, liberating your movements. ")
- if(10 to INFINITY)
- if (B.breast_values[B.prev_size] != B.breast_values[B.size])
- to_chat(H, "Your indulgent busom is so substantial, it's affecting your movements! ")
+ var/target = H.get_bodypart(BODY_ZONE_CHEST)
+ H.apply_damage(0.1, BRUTE, target)
+ else
if(prob(1))
- to_chat(owner, "Your back is feeling a little sore. ")
- ..()
+ to_chat(H, "Your back is feeling a little sore. ")
+ last_checked_size = B.cached_size
+ ..()
-/datum/status_effect/chem/breast_enlarger/on_remove(mob/living/carbon/M)
+/datum/status_effect/chem/breast_enlarger/on_remove()
log_game("FERMICHEM: [owner]'s breasts has reduced to an acceptable size. ID: [owner.key]")
+ to_chat(owner, "Your expansive chest has become a more managable size, liberating your movements. ")
owner.remove_movespeed_modifier(BREAST_MOVEMENT_SPEED)
sizeMoveMod(1)
@@ -112,51 +110,57 @@
alert_type = null
var/bloodCalc
var/moveCalc
+ var/last_checked_size //used to prevent potential cpu waste, just like the above.
-/datum/status_effect/chem/penis_enlarger/on_apply(mob/living/carbon/human/H)//Removes clothes, they're too small to contain you. You belong to space now.
+/datum/status_effect/chem/penis_enlarger/on_apply()//Removes clothes, they're too small to contain you. You belong to space now.
log_game("FERMICHEM: [owner]'s dick has reached comical sizes. ID: [owner.key]")
- var/mob/living/carbon/human/o = owner
- var/items = o.get_contents()
- if(o.w_uniform || o.wear_suit)
- to_chat(o, "Your clothes give, ripping into peices under the strain of your swelling pecker! Unless you manage to reduce the size of your emancipated trouser snake, there's no way you're going to be able to put anything on over this girth..! ")
- owner.visible_message("[o]'s schlong suddenly bursts forth, ripping their clothes off!' ")
+ var/mob/living/carbon/human/H = owner
+ var/message = FALSE
+ if(H.w_uniform)
+ H.dropItemToGround(H.w_uniform, TRUE)
+ message = TRUE
+ if(H.wear_suit)
+ H.dropItemToGround(H.wear_suit, TRUE)
+ message = TRUE
+ if(message)
+ playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
+ H.visible_message("[H]'s schlong suddenly bursts forth, ripping their clothes off!' ", \
+ "Your clothes give, ripping into peices under the strain of your swelling pecker! Unless you manage to reduce the size of your emancipated trouser snake, there's no way you're going to be able to put anything on over this girth..! ")
else
- to_chat(o, "Your emancipated trouser snake is so ripe with girth, you seriously doubt you'll be able to fit any clothes over it. ")
- for(var/obj/item/W in items)
- if(W == o.w_uniform || W == o.wear_suit)
- o.dropItemToGround(W, TRUE)
- playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
+ to_chat(H, "Your emancipated trouser snake is so ripe with girth, you seriously doubt you'll be able to fit any clothes over it. ")
return ..()
-/datum/status_effect/chem/penis_enlarger/tick(mob/living/carbon/M)
- var/mob/living/carbon/human/o = owner
- var/obj/item/organ/genital/penis/P = o.getorganslot("penis")
+/datum/status_effect/chem/penis_enlarger/tick()
+ var/mob/living/carbon/human/H = owner
+ var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
+ if(!P)
+ owner.remove_status_effect(src)
+ return
moveCalc = 1+((round(P.length) - 21)/3) //effects how fast you can move
bloodCalc = 1+((round(P.length) - 21)/15) //effects how much blood you need (I didn' bother adding an arousal check because I'm spending too much time on this organ already.)
- if(!P)
- o.remove_movespeed_modifier(DICK_MOVEMENT_SPEED)
- o.ResetBloodVol()
- owner.remove_status_effect(src)
- var/items = o.get_contents()
- for(var/obj/item/W in items)
- if(W == o.w_uniform || W == o.wear_suit)
- o.dropItemToGround(W, TRUE)
- playsound(o.loc, 'sound/items/poster_ripped.ogg', 50, 1)
- to_chat(owner, "Your enormous package is way to large to fit anything over! ")
- switch(round(P.cached_length))
- if(21)
- to_chat(o, "Your rascally willy has become a more managable size, liberating your movements. ")
- o.remove_movespeed_modifier(DICK_MOVEMENT_SPEED)
- o.AdjustBloodVol(bloodCalc)
- if(22 to INFINITY)
- if(prob(2))
- to_chat(o, "Your indulgent johnson is so substantial, it's taking all your blood and affecting your movements! ")
- o.add_movespeed_modifier(DICK_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
- o.AdjustBloodVol(bloodCalc)
+
+ var/message = FALSE
+ if(H.w_uniform)
+ H.dropItemToGround(H.w_uniform, TRUE)
+ message = TRUE
+ if(H.wear_suit)
+ H.dropItemToGround(H.wear_suit, TRUE)
+ message = TRUE
+ if(message)
+ playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1)
+ to_chat(H, "Your enormous package is way to large to fit anything over! ")
+
+ if(P.length < 22 && H.has_movespeed_modifier(DICK_MOVEMENT_SPEED))
+ to_chat(owner, "Your rascally willy has become a more managable size, liberating your movements. ")
+ H.remove_movespeed_modifier(DICK_MOVEMENT_SPEED)
+ else if(P.length >= 22 && !H.has_movespeed_modifier(DICK_MOVEMENT_SPEED))
+ to_chat(H, "Your indulgent johnson is so substantial, it's taking all your blood and affecting your movements! ")
+ H.add_movespeed_modifier(DICK_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc)
+ H.AdjustBloodVol(bloodCalc)
..()
-/datum/status_effect/chem/penis_enlarger/on_remove(mob/living/carbon/human/o)
+/datum/status_effect/chem/penis_enlarger/on_remove()
log_game("FERMICHEM: [owner]'s dick has reduced to an acceptable size. ID: [owner.key]")
owner.remove_movespeed_modifier(DICK_MOVEMENT_SPEED)
owner.ResetBloodVol()
@@ -198,7 +202,6 @@
var/enthrallGender //Use master or mistress
var/mental_capacity //Higher it is, lower the cooldown on commands, capacity reduces with resistance.
- var/datum/weakref/redirect_component //resistance
var/distancelist = list(2,1.5,1,0.8,0.6,0.5,0.4,0.3,0.2) //Distance multipliers
@@ -228,10 +231,9 @@
master = get_mob_by_key(enthrallID)
//if(M.ckey == enthrallID)
// owner.remove_status_effect(src)//At the moment, a user can enthrall themselves, toggle this back in if that should be removed.
- redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/owner_resist)))) //Do resistance calc if resist is pressed#
+ RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/owner_resist) //Do resistance calc if resist is pressed#
RegisterSignal(owner, COMSIG_MOVABLE_HEAR, .proc/owner_hear)
- var/obj/item/organ/brain/B = M.getorganslot(ORGAN_SLOT_BRAIN) //It's their brain!
- mental_capacity = 500 - B.get_brain_damage()
+ mental_capacity = 500 - M.getOrganLoss(ORGAN_SLOT_BRAIN)//It's their brain!
var/mob/living/carbon/human/H = owner
if(H)//Prefs
if(!H.canbearoused)
@@ -334,7 +336,7 @@
if(owner.client?.prefs.lewdchem && !customEcho)
to_chat(owner, "[pick("I belong to [enthrallGender].", "[enthrallGender] knows whats best for me.", "Obedence is pleasure.", "I exist to serve [enthrallGender].", "[enthrallGender] is so dominant, it feels right to obey them.")]. ")
if (4) //mindbroken
- if (mental_capacity >= 499 && (owner.getBrainLoss() <=0 || HAS_TRAIT(M, TRAIT_MINDSHIELD)) && !owner.reagents.has_reagent("MKUltra"))
+ if (mental_capacity >= 499 && (owner.getOrganLoss(ORGAN_SLOT_BRAIN) <=0 || HAS_TRAIT(M, TRAIT_MINDSHIELD)) && !owner.reagents.has_reagent("MKUltra"))
phase = 2
mental_capacity = 500
customTriggers = list()
@@ -373,8 +375,8 @@
M.hallucination = max(0, M.hallucination - 5)
M.stuttering = max(0, M.stuttering - 5)
M.jitteriness = max(0, M.jitteriness - 5)
- if(owner.getBrainLoss() >=20)
- owner.adjustBrainLoss(-0.2)
+ if(owner.getOrganLoss(ORGAN_SLOT_BRAIN) >=20)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, -0.2)
if(withdrawal == TRUE)
REMOVE_TRAIT(owner, TRAIT_PACIFISM, "MKUltra")
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing1")
@@ -395,7 +397,7 @@
if(prob(5))
to_chat(owner, "You're starting to miss [(owner.client?.prefs.lewdchem?"your [enthrallGender]":"[master]")]. ")
if(prob(5))
- owner.adjustBrainLoss(0.1)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.1)
to_chat(owner, "[(owner.client?.prefs.lewdchem?"[enthrallGender]":"[master]")] will surely be back soon ") //denial
if(36)
var/message = "[(owner.client?.prefs.lewdchem?"I feel empty when [enthrallGender]'s not around..":"I miss [master]'s presence")]"
@@ -403,11 +405,11 @@
if(37 to 65)//barganing
if(prob(10))
to_chat(owner, "They are coming back, right...? ")
- owner.adjustBrainLoss(0.5)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)
if(prob(10))
if(owner.client?.prefs.lewdchem)
to_chat(owner, "I just need to be a good pet for [enthrallGender], they'll surely return if I'm a good pet. ")
- owner.adjustBrainLoss(-1.5)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1.5)
if(66)
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing1")
var/message = "[(owner.client?.prefs.lewdchem?"I feel so lost in this complicated world without [enthrallGender]..":"I have to return to [master]!")]"
@@ -452,7 +454,7 @@
to_chat(owner, "You're unable to hold back your tears, suddenly sobbing as the desire to see your [enthrallGender] oncemore overwhelms you. ")
else
to_chat(owner, "You are overwheled with withdrawl from [master]. ")
- owner.adjustBrainLoss(1)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
owner.stuttering += 35
owner.jitteriness += 35
if(prob(10))//2% chance
@@ -468,14 +470,14 @@
if(140 to INFINITY) //acceptance
if(prob(15))
deltaResist += 5
- owner.adjustBrainLoss(-1)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, -1)
if(prob(20))
if(owner.client?.prefs.lewdchem)
to_chat(owner, "Maybe you'll be okay without your [enthrallGender]. ")
else
to_chat(owner, "You feel your mental functions slowly begin to return. ")
if(prob(5))
- owner.adjustBrainLoss(1)
+ owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 1)
M.hallucination += 30
withdrawalTick += 0.5//Enough to leave you with a major brain trauma, but not kill you.
@@ -501,7 +503,7 @@
cooldown += 1 //Cooldown doesn't process till status is done
else if(status == "charge")
- ADD_TRAIT(owner, TRAIT_GOTTAGOFAST, "MKUltra")
+ owner.add_movespeed_modifier(MOVESPEED_ID_MKULTRA, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING))
status = "charged"
if(master.client?.prefs.lewdchem)
to_chat(owner, "Your [enthrallGender]'s order fills you with a burst of speed! ")
@@ -511,7 +513,7 @@
else if (status == "charged")
if (statusStrength < 0)
status = null
- REMOVE_TRAIT(owner, TRAIT_GOTTAGOFAST, "MKUltra")
+ owner.remove_movespeed_modifier(MOVESPEED_ID_MKULTRA)
owner.Knockdown(50)
to_chat(owner, "Your body gives out as the adrenaline in your system runs out. ")
else
@@ -567,8 +569,7 @@
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing2")
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing3")
SEND_SIGNAL(M, COMSIG_CLEAR_MOOD_EVENT, "EnthMissing4")
- qdel(redirect_component.resolve())
- redirect_component = null
+ UnregisterSignal(M, COMSIG_LIVING_RESIST)
UnregisterSignal(owner, COMSIG_MOVABLE_HEAR)
REMOVE_TRAIT(owner, TRAIT_PACIFISM, "MKUltra")
to_chat(owner, "You're now free of [master]'s influence, and fully independent!' ")
diff --git a/modular_citadel/code/datums/traits/neutral.dm b/modular_citadel/code/datums/traits/neutral.dm
deleted file mode 100644
index 197c9b94e1..0000000000
--- a/modular_citadel/code/datums/traits/neutral.dm
+++ /dev/null
@@ -1,43 +0,0 @@
-// Citadel-specific Neutral Traits
-
-/datum/quirk/libido
- name = "Nymphomania"
- desc = "You're always feeling a bit in heat. Also, you get aroused faster than usual."
- value = 0
- mob_trait = TRAIT_NYMPHO
- gain_text = "You are feeling extra wild. "
- lose_text = "You don't feel that burning sensation anymore. "
-
-/datum/quirk/libido/add()
- var/mob/living/M = quirk_holder
- M.min_arousal = 16
- M.arousal_rate = 3
-
-/datum/quirk/libido/remove()
- var/mob/living/M = quirk_holder
- M.min_arousal = initial(M.min_arousal)
- M.arousal_rate = initial(M.arousal_rate)
-
-/datum/quirk/libido/on_process()
- var/mob/living/M = quirk_holder
- if(M.canbearoused == FALSE)
- to_chat(quirk_holder, "Having high libido is useless when you can't feel arousal at all! ")
- qdel(src)
-
-/datum/quirk/maso
- name = "Masochism"
- desc = "You are aroused by pain."
- value = 0
- mob_trait = TRAIT_MASO
- gain_text = "You desire to be hurt. "
- lose_text = "Pain has become less exciting for you. "
-
-/datum/quirk/pharmacokinesis //Prevents unwanted organ additions.
- name = "Acute hepatic pharmacokinesis"
- desc = "You've a rare genetic disorder that causes Incubus draft and Sucubus milk to be absorbed by your liver instead."
- value = 0
- mob_trait = TRAIT_PHARMA
- lose_text = "Your liver feels different. "
- var/active = FALSE
- var/power = 0
- var/cachedmoveCalc = 1
diff --git a/modular_citadel/code/game/gamemodes/gangs/dominator.dm b/modular_citadel/code/game/gamemodes/gangs/dominator.dm
index 5ad740ed2e..c590baf62e 100644
--- a/modular_citadel/code/game/gamemodes/gangs/dominator.dm
+++ b/modular_citadel/code/game/gamemodes/gangs/dominator.dm
@@ -1,6 +1,7 @@
#define DOM_BLOCKED_SPAM_CAP 6
//32 instead of 40 for safety reasons. How many turfs aren't walls around dominator for it to work
-#define DOM_REQUIRED_TURFS 32
+//Update ppl somehow fuckup at 32, now we are down to 25. I hope to god they don't try harder to wall it.
+#define DOM_REQUIRED_TURFS 25
#define DOM_HULK_HITS_REQUIRED 10
/obj/machinery/dominator
@@ -52,19 +53,17 @@
/obj/machinery/dominator/update_icon()
cut_overlays()
- if(!(stat & BROKEN))
- icon_state = "dominator-active"
- if(operating)
- var/mutable_appearance/dominator_overlay = mutable_appearance('icons/obj/machines/dominator.dmi', "dominator-overlay")
- if(gang)
- dominator_overlay.color = gang.color
- add_overlay(dominator_overlay)
- else
- icon_state = "dominator"
- if(obj_integrity/max_integrity < 0.66)
- add_overlay("damage")
- else
+ if(stat & BROKEN)
icon_state = "dominator-broken"
+ return
+ icon_state = "dominator"
+ if(operating)
+ var/mutable_appearance/dominator_overlay = mutable_appearance('icons/obj/machines/dominator.dmi', "dominator-overlay")
+ if(gang)
+ dominator_overlay.color = gang.color
+ add_overlay(dominator_overlay)
+ if(obj_integrity/max_integrity < 0.66)
+ add_overlay("damage")
/obj/machinery/dominator/examine(mob/user)
..()
@@ -85,6 +84,9 @@
if(gang && gang.domination_time != NOT_DOMINATING)
var/time_remaining = gang.domination_time_remaining()
if(time_remaining > 0)
+ if(!is_station_level(z))
+ explosion(src, 5, 10, 20, 30) //you now get a nice explosion if this moves off station.
+ qdel(src) //to make sure it doesn't continue to exist.
if(excessive_walls_check())
gang.domination_time += 20
if(spam_prevention < DOM_BLOCKED_SPAM_CAP)
diff --git a/modular_citadel/code/game/machinery/toylathe.dm b/modular_citadel/code/game/machinery/toylathe.dm
index 903235c763..571cdfc82a 100644
--- a/modular_citadel/code/game/machinery/toylathe.dm
+++ b/modular_citadel/code/game/machinery/toylathe.dm
@@ -4,24 +4,34 @@
/obj/machinery/autoylathe
name = "autoylathe"
- desc = "It produces items using plastic, metal and glass."
+ desc = "It produces toys using plastic, metal and glass."
icon_state = "autolathe"
density = TRUE
- anchored = TRUE
use_power = IDLE_POWER_USE
idle_power_usage = 10
active_power_usage = 100
circuit = /obj/item/circuitboard/machine/autoylathe
+ layer = BELOW_OBJ_LAYER
+
+ var/operating = FALSE
+ var/list/L = list()
+ var/list/LL = list()
var/hacked = FALSE
- var/disabled = FALSE
+ var/disabled = 0
var/shocked = FALSE
+ var/hack_wire
+ var/disable_wire
+ var/shock_wire
+
var/busy = FALSE
var/prod_coeff = 1
+
var/datum/design/being_built
var/datum/techweb/stored_research
var/list/datum/design/matching_designs
var/selected_category
var/screen = 1
+
var/list/categories = list(
"Toys",
"Figurines",
@@ -36,8 +46,8 @@
)
/obj/machinery/autoylathe/Initialize()
- . = ..()
AddComponent(/datum/component/material_container, list(MAT_METAL, MAT_GLASS, MAT_PLASTIC), 0, TRUE, null, null, CALLBACK(src, .proc/AfterMaterialInsert))
+ . = ..()
wires = new /datum/wires/autoylathe(src)
stored_research = new /datum/techweb/specialized/autounlocking/autoylathe
@@ -47,7 +57,8 @@
QDEL_NULL(wires)
return ..()
-/obj/machinery/autoylathe/interact(mob/user)
+/obj/machinery/autoylathe/ui_interact(mob/user)
+ . = ..()
if(!is_operational())
return
@@ -69,7 +80,7 @@
popup.open()
/obj/machinery/autoylathe/on_deconstruction()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.retrieve_all()
/obj/machinery/autoylathe/attackby(obj/item/O, mob/user, params)
@@ -81,9 +92,6 @@
updateUsrDialog()
return TRUE
- if(exchange_parts(user, O))
- return TRUE
-
if(default_deconstruction_crowbar(O))
return TRUE
@@ -148,6 +156,7 @@
var/multiplier = text2num(href_list["multiplier"])
var/is_stack = ispath(being_built.build_path, /obj/item/stack)
+ multiplier = CLAMP(multiplier,1,50)
/////////////////
@@ -157,7 +166,7 @@
var/plastic_cost = being_built.materials[MAT_PLASTIC]
var/power = max(2000, (metal_cost+glass_cost+plastic_cost)*multiplier/5)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if((materials.amount(MAT_METAL) >= metal_cost*multiplier*coeff) && (materials.amount(MAT_GLASS) >= glass_cost*multiplier*coeff) && (materials.amount(MAT_PLASTIC) >= plastic_cost*multiplier*coeff))
busy = TRUE
use_power(power)
@@ -181,7 +190,7 @@
return
/obj/machinery/autoylathe/proc/make_item(power, metal_cost, glass_cost, plastic_cost, multiplier, coeff, is_stack)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/atom/A = drop_location()
use_power(power)
var/list/materials_used = list(MAT_METAL=metal_cost*coeff*multiplier, MAT_GLASS=glass_cost*coeff*multiplier, MAT_PLASTIC=plastic_cost*coeff*multiplier)
@@ -194,6 +203,7 @@
else
for(var/i=1, i<=multiplier, i++)
var/obj/item/new_item = new being_built.build_path(A)
+ new_item.materials = new_item.materials.Copy()
for(var/mat in materials_used)
new_item.materials[mat] = materials_used[mat] / multiplier
new_item.autoylathe_crafted(src)
@@ -205,7 +215,7 @@
var/T = 0
for(var/obj/item/stock_parts/matter_bin/MB in component_parts)
T += MB.rating*75000
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
materials.max_amount = T
T=1.2
for(var/obj/item/stock_parts/manipulator/M in component_parts)
@@ -254,7 +264,7 @@
dat += "[D.name] "
if(ispath(D.build_path, /obj/item/stack))
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS] ?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY,D.materials[MAT_PLASTIC] ?round(materials.amount(MAT_PLASTIC)/D.materials[MAT_PLASTIC]):INFINITY)
if (max_multiplier>10 && !disabled)
dat += " x10 "
@@ -286,7 +296,7 @@
dat += "[D.name] "
if(ispath(D.build_path, /obj/item/stack))
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/max_multiplier = min(D.maxstack, D.materials[MAT_METAL] ?round(materials.amount(MAT_METAL)/D.materials[MAT_METAL]):INFINITY,D.materials[MAT_GLASS] ?round(materials.amount(MAT_GLASS)/D.materials[MAT_GLASS]):INFINITY,D.materials[MAT_PLASTIC] ?round(materials.amount(MAT_PLASTIC)/D.materials[MAT_PLASTIC]):INFINITY)
if (max_multiplier>10 && !disabled)
dat += " x10 "
@@ -301,7 +311,7 @@
return dat
/obj/machinery/autoylathe/proc/materials_printout()
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
var/dat = "Total amount: [materials.total_amount] / [materials.max_amount] cm3 "
for(var/mat_id in materials.materials)
var/datum/material/M = materials.materials[mat_id]
@@ -314,7 +324,7 @@
var/coeff = (ispath(D.build_path, /obj/item/stack) ? 1 : prod_coeff)
- GET_COMPONENT(materials, /datum/component/material_container)
+ var/datum/component/material_container/materials = GetComponent(/datum/component/material_container)
if(D.materials[MAT_METAL] && (materials.amount(MAT_METAL) < (D.materials[MAT_METAL] * coeff * amount)))
return FALSE
if(D.materials[MAT_GLASS] && (materials.amount(MAT_GLASS) < (D.materials[MAT_GLASS] * coeff * amount)))
@@ -347,7 +357,7 @@
disabled = FALSE
/obj/machinery/autoylathe/proc/shock(mob/user, prb)
- if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
+ if(stat & (BROKEN|NOPOWER)) // unpowered, no shock
return FALSE
if(!prob(prb))
return FALSE
diff --git a/modular_citadel/code/game/machinery/vending.dm b/modular_citadel/code/game/machinery/vending.dm
index 2de98a3171..a71175c345 100755
--- a/modular_citadel/code/game/machinery/vending.dm
+++ b/modular_citadel/code/game/machinery/vending.dm
@@ -43,46 +43,36 @@
vend_reply = "Have fun, you shameless pervert!"
products = list(
/obj/item/clothing/under/maid = 5,
- /obj/item/clothing/under/stripper_pink = 5,
- /obj/item/clothing/under/stripper_green = 5,
- /obj/item/dildo/custom = 5
- )
- contraband = list(/obj/item/restraints/handcuffs/fake/kinky = 5,
/obj/item/clothing/neck/petcollar = 5,
- /obj/item/clothing/under/mankini = 1,
- /obj/item/dildo/flared/huge = 1
+ /obj/item/clothing/neck/petcollar/choker = 5,
+ /obj/item/clothing/neck/petcollar/leather = 5,
+ /obj/item/restraints/handcuffs/fake/kinky = 5,
+ /obj/item/clothing/glasses/sunglasses/blindfold = 4,
+ /obj/item/clothing/mask/muzzle = 4,
+ /obj/item/clothing/under/stripper_pink = 3,
+ /obj/item/clothing/under/stripper_green = 3,
+ /obj/item/dildo/custom = 5,
+ /obj/item/electropack/shockcollar = 3,
+ /obj/item/assembly/signaler = 3
+ )
+ contraband = list(
+ /obj/item/clothing/neck/petcollar/locked = 2,
+ /obj/item/key/collar = 2,
+ /obj/item/clothing/head/kitty = 3,
+ /obj/item/clothing/head/rabbitears = 3,
+ /obj/item/clothing/under/mankini = 2,
+ /obj/item/clothing/under/jabroni = 2,
+ /obj/item/dildo/flared/huge = 3,
+ /obj/item/reagent_containers/glass/bottle/crocin = 5,
+ /obj/item/reagent_containers/glass/bottle/camphor = 5
)
premium = list(
- /obj/item/electropack/shockcollar = 3,
- /obj/item/clothing/neck/petcollar/locked = 1
+ /obj/item/clothing/accessory/skullcodpiece/fake = 3,
+ /obj/item/clothing/under/gear_harness = 10,
+ /obj/item/reagent_containers/glass/bottle/hexacrocin = 10
)
refill_canister = /obj/item/vending_refill/kink
-/*
-/obj/machinery/vending/nazivend
- name = "Nazivend"
- desc = "A vending machine containing Nazi German supplies. A label reads: \"Remember the gorrilions lost.\""
- icon = 'icons/obj/citvending.dmi'
- icon_state = "nazi"
- vend_reply = "SIEG HEIL!"
- product_slogans = "Das Vierte Reich wird zuruckkehren!;ENTFERNEN JUDEN!;Billiger als die Juden jemals geben!;Rader auf dem adminbus geht rund und rund.;Warten Sie, warum wir wieder hassen Juden?- *BZZT*"
- products = list(
- /obj/item/clothing/head/stalhelm = 20,
- /obj/item/clothing/head/panzer = 20,
- /obj/item/clothing/suit/soldiercoat = 20,
- // /obj/item/clothing/under/soldieruniform = 20,
- /obj/item/clothing/shoes/jackboots = 20
- )
- contraband = list(
- /obj/item/clothing/head/naziofficer = 10,
- // /obj/item/clothing/suit/officercoat = 10,
- // /obj/item/clothing/under/officeruniform = 10,
- /obj/item/clothing/suit/space/hardsuit/nazi = 3,
- /obj/item/gun/energy/plasma/MP40k = 4
- )
- premium = list()
- refill_canister = /obj/item/vending_refill/nazi
-*/
/obj/machinery/vending/sovietvend
name = "KomradeVendtink"
desc = "Rodina-mat' zovyot!"
@@ -122,10 +112,6 @@
icon = 'modular_citadel/icons/vending_restock.dmi'
icon_state = "refill_kink"
-/obj/item/vending_refill/nazi
- machine_name = "nazivend"
- icon_state = "refill_nazi"
-
/obj/item/vending_refill/soviet
machine_name = "sovietvend"
icon_state = "refill_soviet"
diff --git a/modular_citadel/code/game/objects/ids.dm b/modular_citadel/code/game/objects/ids.dm
deleted file mode 100644
index 8ef724581e..0000000000
--- a/modular_citadel/code/game/objects/ids.dm
+++ /dev/null
@@ -1,83 +0,0 @@
-
-//Polychromatic Knight Badge
-
-/obj/item/card/id/knight
- var/id_color = "#00FF00" //defaults to green
- name = "knight badge"
- icon = 'modular_citadel/icons/obj/id.dmi'
- icon_state = "knight"
- desc = "A badge denoting the owner as a knight! It has a strip for swiping like an ID"
-
-/obj/item/card/id/knight/update_label(newname, newjob)
- . = ..()
- if(newname || newjob)
- name = "[(!newname) ? "identification card" : "[newname]'s Knight Badge"][(!newjob) ? "" : " ([newjob])"]"
- return
-
- name = "[(!registered_name) ? "identification card" : "[registered_name]'s Knight Badge"][(!assignment) ? "" : " ([assignment])"]"
-
-/obj/item/card/id/knight/update_icon()
- var/mutable_appearance/id_overlay = mutable_appearance('modular_citadel/icons/obj/id.dmi', "knight_overlay")
-
- if(id_color)
- id_overlay.color = id_color
- cut_overlays()
-
- add_overlay(id_overlay)
-
-/obj/item/card/id/knight/AltClick(mob/living/user)
- if(!in_range(src, user)) //Basic checks to prevent abuse
- return
- if(user.incapacitated() || !istype(user))
- to_chat(user, "You can't do that right now! ")
- return
- if(alert("Are you sure you want to recolor your id?", "Confirm Repaint", "Yes", "No") == "Yes")
- var/energy_color_input = input(usr,"","Choose Energy Color",id_color) as color|null
- if(energy_color_input)
- id_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
- update_icon()
-
-/obj/item/card/id/knight/Initialize()
- . = ..()
- update_icon()
-
-/obj/item/card/id/knight/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to recolor it. ")
-
-//=================================================
-
-/obj/item/emagrecharge
- name = "electromagnet charging device"
- desc = "A small cell with two prongs lazily jabbed into it. It looks like it's made for charging the small batteries found in electromagnetic devices, sadly this can't be recharged like a normal cell."
- icon = 'icons/obj/module.dmi'
- icon_state = "cell_mini"
- item_flags = NOBLUDGEON
- var/uses = 5 //Dictates how many charges the device adds to compatible items
-
-/obj/item/emagrecharge/examine(mob/user)
- . = ..()
- if(uses)
- to_chat(user, "It can add up to [uses] charges to compatible devices ")
- else
- to_chat(user, "It has a small, red, blinking light coming from inside of it. It's spent. ")
-
-/obj/item/card/emag
- var/uses = 15
-
-/obj/item/card/emag/examine(mob/user)
- . = ..()
- to_chat(user, "It has [uses ? uses : "no"] charges left. ")
-
-/obj/item/card/emag/attackby(obj/item/W, mob/user, params)
- if(istype(W, /obj/item/emagrecharge))
- var/obj/item/emagrecharge/ER = W
- if(ER.uses)
- uses += ER.uses
- to_chat(user, "You have added [ER.uses] charges to [src]. It now has [uses] charges. ")
- playsound(src, "sparks", 100, 1)
- ER.uses = 0
- else
- to_chat(user, "[ER] has no charges left. ")
- return
- . = ..()
diff --git a/modular_citadel/code/game/objects/items.dm b/modular_citadel/code/game/objects/items.dm
index c94923f9de..dba460414e 100644
--- a/modular_citadel/code/game/objects/items.dm
+++ b/modular_citadel/code/game/objects/items.dm
@@ -9,7 +9,7 @@
alternate_screams = list('modular_citadel/sound/voice/scream_silicon.ogg')
/obj/item/clothing/head/ushanka
- alternate_screams = list('modular_citadel/sound/misc/cyka1.ogg', 'modular_citadel/sound/misc/cheekibreeki.ogg')
+ alternate_screams = list('sound/voice/human/cyka1.ogg', 'sound/voice/human/cheekibreeki.ogg')
/obj/item/proc/grenade_prime_react(obj/item/grenade/nade)
return
\ No newline at end of file
diff --git a/modular_citadel/code/game/objects/items/devices/aicard.dm b/modular_citadel/code/game/objects/items/devices/aicard.dm
deleted file mode 100644
index a1509e4473..0000000000
--- a/modular_citadel/code/game/objects/items/devices/aicard.dm
+++ /dev/null
@@ -1,4 +0,0 @@
-/obj/item/aicard/potato
- name = "Potat-OS"
- desc = "A storage device for possibly malfunctioning AIs. Go on. Get a big fat eyeful. With your big fat eyes."
- icon = 'modular_citadel/icons/aicards.dmi'
diff --git a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm b/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm
deleted file mode 100644
index 4cf1d326a2..0000000000
--- a/modular_citadel/code/game/objects/items/melee/eutactic_blades.dm
+++ /dev/null
@@ -1,389 +0,0 @@
-/*/////////////////////////////////////////////////////////////////////////
-///////////// The TRUE Energy Sword ///////////////////////////
-*//////////////////////////////////////////////////////////////////////////
-
-/obj/item/melee/transforming/energy/sword/cx
- name = "non-eutactic blade"
- desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable."
- icon_state = "cxsword_hilt"
- icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi'
- item_state = "cxsword"
- lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi'
- righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi'
- force = 3
- force_on = 21
- throwforce = 5
- throwforce_on = 20
- hitsound = "swing_hit" //it starts deactivated
- hitsound_on = 'sound/weapons/nebhit.ogg'
- attack_verb_off = list("tapped", "poked")
- throw_speed = 3
- throw_range = 5
- sharpness = IS_SHARP
- embedding = list("embedded_pain_multiplier" = 6, "embed_chance" = 20, "embedded_fall_chance" = 60)
- armour_penetration = 10
- block_chance = 35
- light_color = "#37FFF7"
- actions_types = list()
-
-/obj/item/melee/transforming/energy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
- altafterattack(A, user, TRUE, params)
- return TRUE
-
-/obj/item/melee/transforming/energy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
- if(istype(user))
- user.visible_message("[user] points the tip of [src] at [target]. ", "You point the tip of [src] at [target]. ")
- return TRUE
-
-/obj/item/melee/transforming/energy/sword/cx/transform_weapon(mob/living/user, supress_message_text)
- active = !active //I'd use a ..() here but it'd inherit from the regular esword's proc instead, so SPAGHETTI CODE
- if(active) //also I'd need to rip out the iconstate changing bits
- force = force_on
- throwforce = throwforce_on
- hitsound = hitsound_on
- throw_speed = 4
- if(attack_verb_on.len)
- attack_verb = attack_verb_on
- w_class = w_class_on
- START_PROCESSING(SSobj, src)
- set_light(brightness_on)
- update_icon()
- else
- force = initial(force)
- throwforce = initial(throwforce)
- hitsound = initial(hitsound)
- throw_speed = initial(throw_speed)
- if(attack_verb_off.len)
- attack_verb = attack_verb_off
- w_class = initial(w_class)
- STOP_PROCESSING(SSobj, src)
- set_light(0)
- update_icon()
- transform_messages(user, supress_message_text)
- add_fingerprint(user)
- return TRUE
-
-/obj/item/melee/transforming/energy/sword/cx/transform_messages(mob/living/user, supress_message_text)
- playsound(user, active ? 'sound/weapons/nebon.ogg' : 'sound/weapons/neboff.ogg', 65, 1)
- if(!supress_message_text)
- to_chat(user, "[src] [active ? "is now active":"can now be concealed"]. ")
-
-/obj/item/melee/transforming/energy/sword/cx/update_icon()
- var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade")
- var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem")
-
- if(light_color)
- blade_overlay.color = light_color
- gem_overlay.color = light_color
-
- cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
-
- add_overlay(gem_overlay)
-
- if(active)
- add_overlay(blade_overlay)
- if(ismob(loc))
- var/mob/M = loc
- M.update_inv_hands()
-
-/obj/item/melee/transforming/energy/sword/cx/AltClick(mob/living/user)
- if(!in_range(src, user)) //Basic checks to prevent abuse
- return
- if(user.incapacitated() || !istype(user))
- to_chat(user, "You can't do that right now! ")
- return
-
- if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
- var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
- if(energy_color_input)
- light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
- update_icon()
- update_light()
-
-/obj/item/melee/transforming/energy/sword/cx/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to recolor it. ")
-
-/obj/item/melee/transforming/energy/sword/cx/worn_overlays(isinhands, icon_file)
- . = ..()
- if(active)
- if(isinhands)
- var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
- blade_inhand.color = light_color
- . += blade_inhand
-//Broken version. Not a toy, but not as strong.
-/obj/item/melee/transforming/energy/sword/cx/broken
- name = "misaligned non-eutactic blade"
- desc = "The Non-Eutactic Blade utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. This one seems to have a damaged handle and misaligned components, causing the blade to be unstable at best"
- force_on = 15 //As strong a survival knife/bone dagger
-
-/obj/item/melee/transforming/energy/sword/cx/attackby(obj/item/W, mob/living/user, params)
- if(istype(W, /obj/item/melee/transforming/energy/sword/cx))
- if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
- to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]! ")
- return
- else
- to_chat(user, "You combine the two light swords, making a single supermassive blade! You're cool. ")
- new /obj/item/twohanded/dualsaber/hypereutactic(user.drop_location())
- qdel(W)
- qdel(src)
- else
- return ..()
-
-//OBLIGATORY TOY MEMES /////////////////////////////////////
-
-/obj/item/toy/sword/cx
- name = "\improper DX Non-Euplastic LightSword"
- desc = "A deluxe toy replica of an energy sword. Realistic visuals and sounds! Ages 8 and up."
- icon = 'modular_citadel/icons/eutactic/item/noneutactic.dmi'
- icon_state = "cxsword_hilt"
- item_state = "cxsword"
- lefthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_left.dmi'
- righthand_file = 'modular_citadel/icons/eutactic/mob/noneutactic_right.dmi'
- active = FALSE
- w_class = WEIGHT_CLASS_SMALL
- attack_verb = list("poked", "jabbed", "hit")
- light_color = "#37FFF7"
- var/light_brightness = 3
- actions_types = list()
-
-/obj/item/toy/sword/cx/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
- altafterattack(A, user, TRUE, params)
- return TRUE
-
-/obj/item/toy/sword/cx/altafterattack(atom/target, mob/living/carbon/user, proximity_flag, click_parameters) //does right click memes
- if(istype(user))
- user.visible_message("[user] points the tip of [src] at [target]. ", "You point the tip of [src] at [target]. ")
- return TRUE
-
-/obj/item/toy/sword/cx/attack_self(mob/user)
- active = !( active )
-
- if (active)
- to_chat(user, "You activate the holographic blade with a press of a button. ")
- playsound(user, 'sound/weapons/nebon.ogg', 50, 1)
- w_class = WEIGHT_CLASS_BULKY
- attack_verb = list("slashed", "stabbed", "ravaged")
- set_light(light_brightness)
- update_icon()
-
- else
- to_chat(user, "You deactivate the holographic blade with a press of a button. ")
- playsound(user, 'sound/weapons/neboff.ogg', 50, 1)
- w_class = WEIGHT_CLASS_SMALL
- attack_verb = list("poked", "jabbed", "hit")
- set_light(0)
- update_icon()
-
- add_fingerprint(user)
-
-/obj/item/toy/sword/cx/update_icon()
- var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_blade")
- var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/noneutactic.dmi', "cxsword_gem")
-
- if(light_color)
- blade_overlay.color = light_color
- gem_overlay.color = light_color
-
- cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
-
- add_overlay(gem_overlay)
-
- if(active)
- add_overlay(blade_overlay)
- if(ismob(loc))
- var/mob/M = loc
- M.update_inv_hands()
-
-/obj/item/toy/sword/cx/AltClick(mob/living/user)
- if(!in_range(src, user)) //Basic checks to prevent abuse
- return
- if(user.incapacitated() || !istype(user))
- to_chat(user, "You can't do that right now! ")
- return
-
- if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
- var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
- if(energy_color_input)
- light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
- update_icon()
- update_light()
-
-/obj/item/toy/sword/cx/worn_overlays(isinhands, icon_file)
- . = ..()
- if(active)
- if(isinhands)
- var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "cxsword_blade")
- blade_inhand.color = light_color
- . += blade_inhand
-
-/obj/item/toy/sword/cx/attackby(obj/item/W, mob/living/user, params)
- if(istype(W, /obj/item/toy/sword/cx))
- if(HAS_TRAIT(W, TRAIT_NODROP) || HAS_TRAIT(src, TRAIT_NODROP))
- to_chat(user, "\the [HAS_TRAIT(src, TRAIT_NODROP) ? src : W] is stuck to your hand, you can't attach it to \the [HAS_TRAIT(src, TRAIT_NODROP) ? W : src]! ")
- return
- else
- to_chat(user, "You combine the two plastic swords, making a single supermassive toy! You're fake-cool. ")
- new /obj/item/twohanded/dualsaber/hypereutactic/toy(user.loc)
- qdel(W)
- qdel(src)
- else
- return ..()
-
-/obj/item/toy/sword/cx/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to recolor it. ")
-
-/////////////////////////////////////////////////////
-// HYPEREUTACTIC Blades /////////////////////////
-/////////////////////////////////////////////////////
-
-/obj/item/twohanded/dualsaber/hypereutactic
- icon = 'modular_citadel/icons/eutactic/item/hypereutactic.dmi'
- icon_state = "hypereutactic"
- lefthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi'
- righthand_file = 'modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi'
- item_state = "hypereutactic"
- inhand_x_dimension = 64
- inhand_y_dimension = 64
- name = "hypereutactic blade"
- desc = "A supermassive weapon envisioned to cleave the very fabric of space and time itself in twain, the hypereutactic blade dynamically flash-forges a hypereutactic crystaline nanostructure capable of passing through most known forms of matter like a hot knife through butter."
- force = 7
- force_unwielded = 7
- force_wielded = 40
- wieldsound = 'sound/weapons/nebon.ogg'
- unwieldsound = 'sound/weapons/neboff.ogg'
- hitsound_on = 'sound/weapons/nebhit.ogg'
- slowdown_wielded = 1
- armour_penetration = 60
- light_color = "#37FFF7"
- rainbow_colors = list("#FF0000", "#FFFF00", "#00FF00", "#00FFFF", "#0000FF","#FF00FF", "#3399ff", "#ff9900", "#fb008b", "#9800ff", "#00ffa3", "#ccff00")
- attack_verb = list("attacked", "slashed", "stabbed", "sliced", "destroyed", "ripped", "devastated", "shredded")
- spinnable = FALSE
- total_mass_on = 4
-
-/obj/item/twohanded/dualsaber/hypereutactic/chaplain
- name = "\improper divine lightblade"
- desc = "A giant blade of bright and holy light, said to cut down the wicked with ease."
- force = 5
- force_unwielded = 5
- force_wielded = 20
- block_chance = 50
- armour_penetration = 0
- var/chaplain_spawnable = TRUE
- obj_flags = UNIQUE_RENAME
-
-/obj/item/twohanded/dualsaber/hypereutactic/chaplain/Initialize()
- . = ..()
- AddComponent(/datum/component/anti_magic, TRUE, TRUE)
-
-/obj/item/twohanded/dualsaber/hypereutactic/pre_altattackby(atom/A, mob/living/user, params) //checks if it can do right click memes
- altafterattack(A, user, TRUE, params)
- return TRUE
-
-/obj/item/twohanded/dualsaber/hypereutactic/altafterattack(atom/target, mob/living/user, proximity_flag, click_parameters) //does right click memes
- if(istype(user))
- user.visible_message("[user] points the tip of [src] at [target]. ", "You point the tip of [src] at [target]. ")
- return TRUE
-
-/obj/item/twohanded/dualsaber/hypereutactic/update_icon()
- var/mutable_appearance/blade_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_blade")
- var/mutable_appearance/gem_overlay = mutable_appearance('modular_citadel/icons/eutactic/item/hypereutactic.dmi', "hypereutactic_gem")
-
- if(light_color)
- blade_overlay.color = light_color
- gem_overlay.color = light_color
-
- cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
-
- add_overlay(gem_overlay)
-
- if(wielded)
- add_overlay(blade_overlay)
- if(ismob(loc))
- var/mob/M = loc
- M.update_inv_hands()
-
- SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)//blood overlays get weird otherwise, because the sprite changes. (retained from original desword because I have no idea what this is)
-
-/obj/item/twohanded/dualsaber/hypereutactic/AltClick(mob/living/user)
- if(!user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
- return
- if(user.incapacitated() || !istype(user))
- to_chat(user, "You can't do that right now! ")
- return
- if(alert("Are you sure you want to recolor your blade?", "Confirm Repaint", "Yes", "No") == "Yes")
- var/energy_color_input = input(usr,"","Choose Energy Color",light_color) as color|null
- if(!energy_color_input || !user.canUseTopic(src, BE_CLOSE, FALSE) || hacked)
- return
- light_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
- update_icon()
- update_light()
-
-/obj/item/twohanded/dualsaber/hypereutactic/worn_overlays(isinhands, icon_file)
- . = ..()
- if(isinhands)
- var/mutable_appearance/gem_inhand = mutable_appearance(icon_file, "hypereutactic_gem")
- gem_inhand.color = light_color
- . += gem_inhand
- if(wielded)
- var/mutable_appearance/blade_inhand = mutable_appearance(icon_file, "hypereutactic_blade")
- blade_inhand.color = light_color
- . += blade_inhand
-
-/obj/item/twohanded/dualsaber/hypereutactic/examine(mob/user)
- ..()
- if(!hacked)
- to_chat(user, "Alt-click to recolor it. ")
-
-/obj/item/twohanded/dualsaber/hypereutactic/rainbow_process()
- . = ..()
- update_icon()
- update_light()
-
-////////////////// TOY VERSION /////////////////////////////
-
-/obj/item/twohanded/dualsaber/hypereutactic/toy
- name = "\improper DX Hyper-Euplastic LightSword"
- desc = "A supermassive toy envisioned to cleave the very fabric of space and time itself in twain. Realistic visuals and sounds! Ages 8 and up."
- force = 0
- throwforce = 0
- throw_speed = 3
- throw_range = 5
- force_unwielded = 0
- force_wielded = 0
- attack_verb = list("attacked", "struck", "hit")
- total_mass_on = TOTAL_MASS_TOY_SWORD
- slowdown_wielded = 0
-
-/obj/item/twohanded/dualsaber/hypereutactic/toy/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
- return FALSE
-
-/obj/item/twohanded/dualsaber/hypereutactic/toy/IsReflect()//Stops it from reflecting energy projectiles
- return FALSE
-
-//////// Tatortot NEB /////////////// (same stats as regular esword)
-/obj/item/melee/transforming/energy/sword/cx/traitor
- name = "\improper Dragon's Tooth Sword"
- desc = "The Dragon's Tooth sword is a blackmarket modification of a Non-Eutactic Blade, \
- which utilizes a hardlight blade that is dynamically 'forged' on demand to create a deadly sharp edge that is unbreakable. \
- It appears to have a wooden grip and a shaved down guard."
- icon_state = "cxsword_hilt_traitor"
- force_on = 30
- armour_penetration = 50
- embedding = list("embedded_pain_multiplier" = 10, "embed_chance" = 75, "embedded_fall_chance" = 0, "embedded_impact_pain_multiplier" = 10)
- block_chance = 50
- hitsound_on = 'sound/weapons/blade1.ogg'
- light_color = "#37F0FF"
-
-/obj/item/melee/transforming/energy/sword/cx/traitor/transform_messages(mob/living/user, supress_message_text)
- playsound(user, active ? 'sound/weapons/saberon.ogg' : 'sound/weapons/saberoff.ogg', 35, 1)
- if(!supress_message_text)
- to_chat(user, "[src] [active ? "is now active":"can now be concealed"]. ")
-
-//RAINBOW MEMES
-
-/obj/item/twohanded/dualsaber/hypereutactic/toy/rainbow
- name = "\improper Hyper-Euclidean Reciprocating Trigonometric Zweihander"
- desc = "A custom-built toy with fancy rainbow lights built-in."
- hacked = TRUE
diff --git a/modular_citadel/code/game/objects/items/storage/firstaid.dm b/modular_citadel/code/game/objects/items/storage/firstaid.dm
index 125330a9b9..95c88ecc86 100755
--- a/modular_citadel/code/game/objects/items/storage/firstaid.dm
+++ b/modular_citadel/code/game/objects/items/storage/firstaid.dm
@@ -49,7 +49,7 @@
/obj/item/storage/hypospraykit/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 12
STR.can_hold = typecacheof(list(
/obj/item/hypospray/mkii,
@@ -151,7 +151,7 @@
/obj/item/storage/hypospraykit/cmo/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 6
STR.can_hold = typecacheof(list(
/obj/item/hypospray/mkii,
diff --git a/modular_citadel/code/game/turfs/cit_turfs.dm b/modular_citadel/code/game/turfs/cit_turfs.dm
deleted file mode 100644
index 76a8e75f9c..0000000000
--- a/modular_citadel/code/game/turfs/cit_turfs.dm
+++ /dev/null
@@ -1,24 +0,0 @@
-//Yes, hi. This is the file that handles Citadel's turf modifications.
-
-/*
-/turf/open/floor/Entered(atom/obj, atom/oldloc)
- . = ..()
- CitDirtify(obj, oldloc)*/
-
-//Baystation-styled tile dirtification.
-/turf/open/floor/proc/CitDirtify(atom/obj, atom/oldloc)
- if(prob(50))
- if(has_gravity(src) && !isobserver(obj))
- var/dirtamount
- var/obj/effect/decal/cleanable/dirt/dirt = locate(/obj/effect/decal/cleanable/dirt, src)
- if(!dirt)
- dirt = new/obj/effect/decal/cleanable/dirt(src)
- dirt.alpha = 0
- dirtamount = 0
- dirtamount = dirt.alpha + 1
- if(oldloc && istype(oldloc, /turf/open/floor))
- var/obj/effect/decal/cleanable/dirt/spreadindirt = locate(/obj/effect/decal/cleanable/dirt, oldloc)
- if(spreadindirt && spreadindirt.alpha)
- dirtamount += round(spreadindirt.alpha * 0.05)
- dirt.alpha = min(dirtamount,255)
- return TRUE
diff --git a/modular_citadel/code/modules/admin/admin.dm b/modular_citadel/code/modules/admin/admin.dm
index 52c787dbdb..529d0c79ec 100644
--- a/modular_citadel/code/modules/admin/admin.dm
+++ b/modular_citadel/code/modules/admin/admin.dm
@@ -15,7 +15,7 @@
return
to_chat(M, "Man up, and deal with it. Move on. ")
- M.playsound_local(M, 'modular_citadel/sound/misc/manup.ogg', 50, FALSE, pressure_affected = FALSE)
+ M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE)
log_admin("Man up: [key_name(usr)] told [key_name(M)] to man up")
var/message = "[key_name_admin(usr)] told [key_name_admin(M)] to man up. "
@@ -32,7 +32,7 @@
to_chat(world, "Man up, and deal with it. Move on. ")
for(var/mob/M in GLOB.player_list)
- M.playsound_local(M, 'modular_citadel/sound/misc/manup.ogg', 50, FALSE, pressure_affected = FALSE)
+ M.playsound_local(M, 'sound/voice/manup.ogg', 50, FALSE, pressure_affected = FALSE)
log_admin("Man up global: [key_name(usr)] told everybody to man up")
message_admins("[key_name_admin(usr)] told everybody to man up. ")
diff --git a/modular_citadel/code/modules/arousal/arousal.dm b/modular_citadel/code/modules/arousal/arousal.dm
index 27f7576e7f..6c9da17289 100644
--- a/modular_citadel/code/modules/arousal/arousal.dm
+++ b/modular_citadel/code/modules/arousal/arousal.dm
@@ -19,11 +19,6 @@
var/hidden_undershirt = FALSE
var/hidden_socks = FALSE
-/mob/living/carbon/human/New()
- ..()
- saved_underwear = underwear
- saved_undershirt = undershirt
-
//Species vars
/datum/species
var/arousal_gain_rate = AROUSAL_START_VALUE //Rate at which this species becomes aroused
@@ -35,60 +30,51 @@
//Mob procs
/mob/living/carbon/human/proc/underwear_toggle()
set name = "Toggle undergarments"
- set category = "Object"
- if(ishuman(src))
- var/mob/living/carbon/human/humz = src
- var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling", "Cancel") in list("Top", "Bottom", "Socks", "All", "Cancel")
- if(confirm == "Top")
- humz.hidden_undershirt = !humz.hidden_undershirt
+ set category = "IC"
- if(confirm == "Bottom")
- humz.hidden_underwear = !humz.hidden_underwear
+ var/confirm = input(src, "Select what part of your form to alter", "Undergarment Toggling") as null|anything in list("Top", "Bottom", "Socks", "All")
+ if(!confirm)
+ return
+ if(confirm == "Top")
+ hidden_undershirt = !hidden_undershirt
- if(confirm == "Socks")
- humz.hidden_socks = !humz.hidden_socks
+ if(confirm == "Bottom")
+ hidden_underwear = !hidden_underwear
- if(confirm == "All")
- humz.hidden_undershirt = !humz.hidden_undershirt
- humz.hidden_underwear = !humz.hidden_underwear
- humz.hidden_socks = !humz.hidden_socks
+ if(confirm == "Socks")
+ hidden_socks = !hidden_socks
- if(confirm == "Cancel")
- return
- src.update_body()
+ if(confirm == "All")
+ var/on_off = (hidden_undershirt || hidden_underwear || hidden_socks) ? FALSE : TRUE
+ hidden_undershirt = on_off
+ hidden_underwear = on_off
+ hidden_socks = on_off
- else
- to_chat(src, "Humans only. How the fuck did you get this verb anyway.")
+ update_body()
-/mob/living/proc/handle_arousal()
-
-
-/mob/living/carbon/handle_arousal()
- if(canbearoused && dna)
- var/datum/species/S
- S = dna.species
- if(S && !(SSmobs.times_fired % 36) && getArousalLoss() < max_arousal)//Totally stolen from breathing code. Do this every 36 ticks.
- adjustArousalLoss(arousal_rate * S.arousal_gain_rate)
- if(dna.features["exhibitionist"] && client)
- var/amt_nude = 0
- if(is_chest_exposed() && (getorganslot("breasts")))
- amt_nude++
- if(is_groin_exposed())
- if(getorganslot("penis"))
- amt_nude++
- if(getorganslot("vagina"))
- amt_nude++
- if(amt_nude)
- var/watchers = 0
- for(var/mob/_M in view(world.view, src))
- var/mob/living/M = _M
- if(!istype(M))
- continue
- if(M.client && !M.stat && !M.eye_blind && (locate(src) in viewers(world.view,M)))
- watchers++
- if(watchers)
- adjustArousalLoss((amt_nude * watchers) + S.arousal_gain_rate)
+/mob/living/proc/handle_arousal(times_fired)
+ return
+/mob/living/carbon/handle_arousal(times_fired)
+ if(!canbearoused || !dna)
+ return
+ var/datum/species/S = dna.species
+ if(!S || (times_fired % 36) || !getArousalLoss() >= max_arousal)//Totally stolen from breathing code. Do this every 36 ticks.
+ return
+ var/our_loss = arousal_rate * S.arousal_gain_rate
+ if(HAS_TRAIT(src, TRAIT_EXHIBITIONIST) && client)
+ var/amt_nude = 0
+ for(var/obj/item/organ/genital/G in internal_organs)
+ if(G.is_exposed())
+ amt_nude++
+ if(amt_nude)
+ var/watchers = 0
+ for(var/mob/living/L in view(src))
+ if(L.client && !L.stat && !L.eye_blind && (src in view(L)))
+ watchers++
+ if(watchers)
+ our_loss += (amt_nude * watchers) + S.arousal_gain_rate
+ adjustArousalLoss(our_loss)
/mob/living/proc/getArousalLoss()
return arousalloss
@@ -138,8 +124,6 @@
S = GLOB.breasts_shapes_list[G.shape]
if(S?.alt_aroused)
G.aroused_state = isPercentAroused(G.aroused_amount)
- if(getArousalLoss() >= ((max_arousal / 100) * 33))
- G.aroused_state = TRUE
else
G.aroused_state = FALSE
G.update_appearance()
@@ -147,54 +131,16 @@
/mob/living/proc/update_arousal_hud()
return FALSE
-/datum/species/proc/update_arousal_hud(mob/living/carbon/human/H)
- return FALSE
-
/mob/living/carbon/human/update_arousal_hud()
- if(!client || !hud_used)
- return FALSE
- if(dna.species.update_arousal_hud())
+ if(!client || !(hud_used?.arousal))
return FALSE
if(!canbearoused)
hud_used.arousal.icon_state = ""
return FALSE
else
- if(hud_used.arousal)
- if(stat == DEAD)
- hud_used.arousal.icon_state = "arousal0"
- return TRUE
- if(getArousalLoss() == max_arousal)
- hud_used.arousal.icon_state = "arousal100"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 90)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal90"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 80)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal80"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 70)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal70"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 60)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal60"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 50)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal50"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 40)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal40"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 30)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal30"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 20)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal10"
- return TRUE
- if(getArousalLoss() >= (max_arousal / 100) * 10)//M O D U L A R , W O W
- hud_used.arousal.icon_state = "arousal10"
- return TRUE
- else
- hud_used.arousal.icon_state = "arousal0"
+ var/value = FLOOR(getPercentAroused(), 10)
+ hud_used.arousal.icon_state = "arousal[value]"
+ return TRUE
/obj/screen/arousal
name = "arousal"
@@ -213,7 +159,6 @@
to_chat(M, "Arousal is disabled. Feature is unavailable. ")
-
/mob/living/proc/mob_climax()//This is just so I can test this shit without being forced to add actual content to get rid of arousal. Will be a very basic proc for a while.
set name = "Masturbate"
set category = "IC"
@@ -221,225 +166,187 @@
if(mb_cd_timer <= world.time)
//start the cooldown even if it fails
mb_cd_timer = world.time + mb_cd_length
- if(getArousalLoss() >= ((max_arousal / 100) * 33))//33% arousal or greater required
- src.visible_message("[src] starts masturbating! ", \
+ if(getArousalLoss() >= 33)//one third of average max_arousal or greater required
+ visible_message("[src] starts masturbating! ", \
"You start masturbating. ")
if(do_after(src, 30, target = src))
- src.visible_message("[src] relieves [p_them()]self! ", \
+ visible_message("[src] relieves [p_them()]self! ", \
"You have relieved yourself. ")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
setArousalLoss(min_arousal)
else
to_chat(src, "You aren't aroused enough for that. ")
+/obj/item/organ/genital/proc/climaxable(mob/living/carbon/human/H, silent = FALSE) //returns the fluid source (ergo reagents holder) if found.
+ if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
+ . = reagents
+ else
+ if(linked_organ)
+ . = linked_organ.reagents
+ if(!. && !silent)
+ to_chat(H, "Your [name] is unable to produce it's own fluids, it's missing the organs for it. ")
+
+/mob/living/carbon/human/proc/do_climax(datum/reagents/R, atom/target, obj/item/organ/genital/G, spill = TRUE)
+ if(!G)
+ return
+ SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
+ setArousalLoss(min_arousal)
+ if(!target || !R)
+ return
+ var/turfing = isturf(target)
+ if(spill & R.total_volume >= 5)
+ R.reaction(turfing ? target : target.loc, TOUCH, 1, 0)
+ if(!turfing)
+ R.trans_to(target, R.total_volume * (spill ? G.fluid_transfer_factor : 1))
+ R.clear_reagents()
//These are various procs that we'll use later, split up for readability instead of having one, huge proc.
//For all of these, we assume the arguments given are proper and have been checked beforehand.
/mob/living/carbon/human/proc/mob_masturbate(obj/item/organ/genital/G, mb_time = 30) //Masturbation, keep it gender-neutral
- var/total_fluids = 0
- var/datum/reagents/fluid_source = null
-
- if(G.producing) //Can it produce its own fluids, such as breasts?
- fluid_source = G.reagents
- else
- if(!G.linked_organ)
- to_chat(src, "Your [G.name] is unable to produce it's own fluids, it's missing the organs for it. ")
- return
- fluid_source = G.linked_organ.reagents
- total_fluids = fluid_source.total_volume
+ var/datum/reagents/fluid_source = G.climaxable(src)
+ if(!fluid_source)
+ return
+ var/obj/item/organ/genital/PP = CHECK_BITFIELD(G.genital_flags, MASTURBATE_LINKED_ORGAN) ? G.linked_organ : G
+ if(!PP)
+ to_chat(src, "You shudder, unable to cum with your [name]. ")
if(mb_time)
- src.visible_message("[src] starts to [G.masturbation_verb] [p_their()] [G.name]. ", \
- "You start to [G.masturbation_verb] your [G.name]. ", \
+ visible_message("[src] starts to [G.masturbation_verb] [p_their()] [G.name]. ", \
"You start to [G.masturbation_verb] your [G.name]. ")
-
- if(do_after(src, mb_time, target = src))
- if(total_fluids > 5)
- fluid_source.reaction(src.loc, TOUCH, 1, 0)
- fluid_source.clear_reagents()
- src.visible_message("[src] orgasms, cumming[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]! ", \
- "You cum[istype(src.loc, /turf/open/floor) ? " onto [src.loc]" : ""]. ", \
- "You have relieved yourself. ")
- SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
- if(G.can_climax)
- setArousalLoss(min_arousal)
-
+ if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
+ return
+ visible_message("[src] orgasms, [PP.orgasm_verb][isturf(loc) ? " onto [loc]" : ""] with [p_their()] [PP.name]! ", \
+ "You orgasm, [PP.orgasm_verb][isturf(loc) ? " onto [loc]" : ""] with your [PP.name]. ")
+ do_climax(fluid_source, loc, G)
/mob/living/carbon/human/proc/mob_climax_outside(obj/item/organ/genital/G, mb_time = 30) //This is used for forced orgasms and other hands-free climaxes
- var/total_fluids = 0
- var/datum/reagents/fluid_source = null
- var/unable_to_come = FALSE
-
- if(G.producing) //Can it produce its own fluids, such as breasts?
- fluid_source = G.reagents
- total_fluids = fluid_source.total_volume
- else
- if(!G.linked_organ)
- unable_to_come = TRUE
- else
- fluid_source = G.linked_organ.reagents
- total_fluids = fluid_source.total_volume
-
- if(unable_to_come)
- src.visible_message("[src] shudders, their [G.name] unable to cum. ", \
- "Your [G.name] cannot cum, giving no relief. ", \
+ var/datum/reagents/fluid_source = G.climaxable(src, TRUE)
+ if(!fluid_source)
+ visible_message("[src] shudders, their [G.name] unable to cum. ", \
"Your [G.name] cannot cum, giving no relief. ")
- else
- total_fluids = fluid_source.total_volume
- if(mb_time) //as long as it's not instant, give a warning
- src.visible_message("[src] looks like they're about to cum. ", \
- "You feel yourself about to orgasm. ", \
- "You feel yourself about to orgasm. ")
- if(do_after(src, mb_time, target = src))
- if(total_fluids > 5)
- fluid_source.reaction(src.loc, TOUCH, 1, 0)
- fluid_source.clear_reagents()
- src.visible_message("[src] orgasms[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""], using [p_their()] [G.name]! ", \
- "You climax[istype(src.loc, /turf/open/floor) ? ", spilling onto [src.loc]" : ""] with your [G.name]. ", \
- "You climax using your [G.name]. ")
- SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
- if(G.can_climax)
- setArousalLoss(min_arousal)
-
+ return
+ if(mb_time) //as long as it's not instant, give a warning
+ visible_message("[src] looks like they're about to cum. ", \
+ "You feel yourself about to orgasm. ")
+ if(!do_after(src, mb_time, target = src) || !G.climaxable(src, TRUE))
+ return
+ visible_message("[src] orgasms[isturf(loc) ? " onto [loc]" : ""], using [p_their()] [G.name]! ", \
+ "You climax[isturf(loc) ? " onto [loc]" : ""] with your [G.name]. ")
+ do_climax(fluid_source, loc, G)
/mob/living/carbon/human/proc/mob_climax_partner(obj/item/organ/genital/G, mob/living/L, spillage = TRUE, mb_time = 30) //Used for climaxing with any living thing
- var/total_fluids = 0
- var/datum/reagents/fluid_source = null
-
- if(G.producing) //Can it produce its own fluids, such as breasts?
- fluid_source = G.reagents
- else
- if(!G.linked_organ)
- to_chat(src, "Your [G.name] is unable to produce it's own fluids, it's missing the organs for it. ")
- return
- fluid_source = G.linked_organ.reagents
- total_fluids = fluid_source.total_volume
+ var/datum/reagents/fluid_source = G.climaxable(src)
+ if(!fluid_source)
+ return
if(mb_time) //Skip warning if this is an instant climax.
- src.visible_message("[src] is about to climax with [L]! ", \
- "You're about to climax with [L]! ", \
- "You're preparing to climax with someone! ")
+ visible_message("[src] is about to climax with [L]! ", \
+ "You're about to climax with [L]! ")
+ if(!do_after(src, mb_time, target = src) || !in_range(src, L) || !G.climaxable(src, TRUE))
+ return
if(spillage)
- if(do_after(src, mb_time, target = src) && in_range(src, L))
- fluid_source.trans_to(L, total_fluids*G.fluid_transfer_factor)
- total_fluids -= total_fluids*G.fluid_transfer_factor
- if(total_fluids > 5)
- fluid_source.reaction(L.loc, TOUCH, 1, 0)
- fluid_source.clear_reagents()
- src.visible_message("[src] climaxes with [L][spillage ? ", overflowing and spilling":""], using [p_their()] [G.name]! ", \
- "You orgasm with [L][spillage ? ", spilling out of them":""], using your [G.name]. ", \
- "You have climaxed with someone[spillage ? ", spilling out of them":""], using your [G.name]. ")
- SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
- SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
- if(G.can_climax)
- setArousalLoss(min_arousal)
+ visible_message("[src] climaxes with [L], overflowing and spilling, using [p_their()] [G.name]! ", \
+ "You orgasm with [L], spilling out of them, using your [G.name]. ")
else //knots and other non-spilling orgasms
- if(do_after(src, mb_time, target = src) && in_range(src, L))
- fluid_source.trans_to(L, total_fluids)
- total_fluids = 0
- src.visible_message("[src] climaxes with [L], [p_their()] [G.name] spilling nothing! ", \
- "You ejaculate with [L], your [G.name] spilling nothing. ", \
- "You have climaxed inside someone, your [G.name] spilling nothing. ")
- SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
- SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
- if(G.can_climax)
- setArousalLoss(min_arousal)
+ visible_message("[src] climaxes with [L], [p_their()] [G.name] spilling nothing! ", \
+ "You ejaculate with [L], your [G.name] spilling nothing. ")
+ SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
+ do_climax(fluid_source, spillage ? loc : L, G, spillage)
/mob/living/carbon/human/proc/mob_fill_container(obj/item/organ/genital/G, obj/item/reagent_containers/container, mb_time = 30) //For beaker-filling, beware the bartender
- var/total_fluids = 0
- var/datum/reagents/fluid_source = null
-
- if(G.producing) //Can it produce its own fluids, such as breasts?
- fluid_source = G.reagents
- else
- if(!G.linked_organ)
- to_chat(src, "Your [G.name] is unable to produce it's own fluids, it's missing the organs for it. ")
+ var/datum/reagents/fluid_source = G.climaxable(src)
+ if(!fluid_source)
+ return
+ if(mb_time)
+ visible_message("[src] starts to [G.masturbation_verb] their [G.name] over [container]. ", \
+ "You start to [G.masturbation_verb] your [G.name] over [container]. ")
+ if(!do_after(src, mb_time, target = src) || !in_range(src, container) || !G.climaxable(src, TRUE))
return
- fluid_source = G.linked_organ.reagents
- total_fluids = fluid_source.total_volume
+ visible_message("[src] uses [p_their()] [G.name] to fill [container]! ", \
+ "You used your [G.name] to fill [container]. ")
+ do_climax(fluid_source, container, G, FALSE)
- //if(!container) //Something weird happened
- // to_chat(src, "You need a container to do this! ")
- // return
-
- src.visible_message("[src] starts to [G.masturbation_verb] their [G.name] over [container]. ", \
- "You start to [G.masturbation_verb] your [G.name] over [container]. ", \
- "You start to [G.masturbation_verb] your [G.name] over something. ")
- if(do_after(src, mb_time, target = src) && in_range(src, container))
- fluid_source.trans_to(container, total_fluids)
- src.visible_message("[src] uses [p_their()] [G.name] to fill [container]! ", \
- "You used your [G.name] to fill [container]. ", \
- "You have relieved some pressure. ")
- SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "orgasm", /datum/mood_event/orgasm)
- if(G.can_climax)
- setArousalLoss(min_arousal)
-
-/mob/living/carbon/human/proc/pick_masturbate_genitals()
- var/obj/item/organ/genital/ret_organ
- var/list/genitals_list = list()
+/mob/living/carbon/human/proc/pick_masturbate_genitals(silent = FALSE)
+ var/list/genitals_list
var/list/worn_stuff = get_equipped_items()
for(var/obj/item/organ/genital/G in internal_organs)
- if(G.can_masturbate_with) //filter out what you can't masturbate with
- if(G.is_exposed(worn_stuff)) //Nude or through_clothing
- genitals_list += G
- if(genitals_list.len)
- ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
+ if(CHECK_BITFIELD(G.genital_flags, CAN_MASTURBATE_WITH) && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with
+ if(CHECK_BITFIELD(G.genital_flags, MASTURBATE_LINKED_ORGAN) && !G.linked_organ)
+ continue
+ LAZYADD(genitals_list, G)
+ if(LAZYLEN(genitals_list))
+ var/obj/item/organ/genital/ret_organ = input(src, "with what?", "Masturbate", null) as null|obj in genitals_list
return ret_organ
- return null //error stuff
+ else if(!silent)
+ to_chat(src, "You cannot masturbate without available genitals. ")
-
-/mob/living/carbon/human/proc/pick_climax_genitals()
- var/obj/item/organ/genital/ret_organ
- var/list/genitals_list = list()
+/mob/living/carbon/human/proc/pick_climax_genitals(silent = FALSE)
+ var/list/genitals_list
var/list/worn_stuff = get_equipped_items()
for(var/obj/item/organ/genital/G in internal_organs)
- if(G.can_climax) //filter out what you can't masturbate with
- if(G.is_exposed(worn_stuff)) //Nude or through_clothing
- genitals_list += G
- if(genitals_list.len)
- ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
+ if(CHECK_BITFIELD(G.genital_flags, CAN_CLIMAX_WITH) && G.is_exposed(worn_stuff)) //filter out what you can't masturbate with
+ LAZYADD(genitals_list, G)
+ if(LAZYLEN(genitals_list))
+ var/obj/item/organ/genital/ret_organ = input(src, "with what?", "Climax", null) as null|obj in genitals_list
return ret_organ
- return null //error stuff
+ else if(!silent)
+ to_chat(src, "You cannot climax without available genitals. ")
-
-/mob/living/carbon/human/proc/pick_partner()
+/mob/living/carbon/human/proc/pick_partner(silent = FALSE)
var/list/partners = list()
- if(src.pulling)
- partners += src.pulling //Yes, even objects for now
- if(src.pulledby)
- partners += src.pulledby
+ if(pulling)
+ partners += pulling
+ if(pulledby)
+ partners += pulledby
//Now we got both of them, let's check if they're proper
- for(var/I in partners)
- if(isliving(I))
- if(iscarbon(I))
- var/mob/living/carbon/C = I
- if(!C.exposed_genitals.len) //Nothing through_clothing
- if(!C.is_groin_exposed()) //No pants undone
- if(!C.is_chest_exposed()) //No chest exposed
- partners -= I //Then not proper, remove them
- else
- partners -= I //No fucking objects
+ for(var/mob/living/L in partners)
+ if(iscarbon(L))
+ var/mob/living/carbon/C = L
+ if(!C.exposed_genitals.len && !C.is_groin_exposed() && !C.is_chest_exposed()) //Nothing through_clothing, no proper partner.
+ partners -= C
//NOW the list should only contain correct partners
if(!partners.len)
- return null //No one left.
- return input(src, "With whom?", "Sexual partner", null) in partners //pick one, default to null
+ if(!silent)
+ to_chat(src, "You cannot do this alone. ")
+ return //No one left.
+ var/mob/living/target = input(src, "With whom?", "Sexual partner", null) as null|anything in partners //pick one, default to null
+ if(target && in_range(src, target))
+ return target
-/mob/living/carbon/human/proc/pick_climax_container()
- var/obj/item/reagent_containers/SC = null
+/mob/living/carbon/human/proc/pick_climax_container(silent = FALSE)
var/list/containers_list = list()
- for(var/obj/item/reagent_containers/container in held_items)
- if(container.is_open_container() || istype(container, /obj/item/reagent_containers/food/snacks))
- containers_list += container
+ for(var/obj/item/reagent_containers/C in held_items)
+ if(C.is_open_container() || istype(C, /obj/item/reagent_containers/food/snacks))
+ containers_list += C
+ for(var/obj/item/reagent_containers/C in range(1, src))
+ if((C.is_open_container() || istype(C, /obj/item/reagent_containers/food/snacks)) && CanReach(C))
+ containers_list += C
if(containers_list.len)
- SC = input(src, "Into or onto what?(Cancel for nowhere)", null) as null|obj in containers_list
- if(SC)
- if(in_range(src, SC))
- return SC
- return null //If nothing correct, give null.
+ var/obj/item/reagent_containers/SC = input(src, "Into or onto what?(Cancel for nowhere)", null) as null|obj in containers_list
+ if(SC && CanReach(SC))
+ return SC
+ else if(!silent)
+ to_chat(src, "You cannot do this without an appropriate container. ")
+/mob/living/carbon/human/proc/available_rosie_palms(silent = FALSE, list/whitelist_typepaths = list(/obj/item/dildo))
+ if(restrained(TRUE)) //TRUE ignores grabs
+ if(!silent)
+ to_chat(src, "You can't do that while restrained! ")
+ return FALSE
+ if(!get_num_arms() || !get_empty_held_indexes())
+ if(whitelist_typepaths)
+ if(!islist(whitelist_typepaths))
+ whitelist_typepaths = list(whitelist_typepaths)
+ for(var/path in whitelist_typepaths)
+ if(is_holding_item_of_type(path))
+ return TRUE
+ if(!silent)
+ to_chat(src, "You need at least one free arm. ")
+ return FALSE
+ return TRUE
//Here's the main proc itself
/mob/living/carbon/human/mob_climax(forced_climax=FALSE) //Forced is instead of the other proc, makes you cum if you have the tools for it, ignoring restraints
@@ -447,156 +354,97 @@
if(!forced_climax) //Don't spam the message to the victim if forced to come too fast
to_chat(src, "You need to wait [DisplayTimeText((mb_cd_timer - world.time), TRUE)] before you can do that again! ")
return
- mb_cd_timer = (world.time + mb_cd_length)
-
- if(canbearoused && has_dna())
- if(stat==2)
+ if(!canbearoused || !has_dna())
+ return
+ if(stat == DEAD)
+ if(!forced_climax)
to_chat(src, "You can't do that while dead! ")
- return
- if(forced_climax) //Something forced us to cum, this is not a masturbation thing and does not progress to the other checks
- for(var/obj/item/organ/O in internal_organs)
- if(istype(O, /obj/item/organ/genital))
- var/obj/item/organ/genital/G = O
- if(!G.can_climax) //Skip things like wombs and testicles
- continue
- var/mob/living/partner
- var/check_target
- var/list/worn_stuff = get_equipped_items()
+ return
+ if(forced_climax) //Something forced us to cum, this is not a masturbation thing and does not progress to the other checks
+ for(var/obj/item/organ/genital/G in internal_organs)
+ if(!CHECK_BITFIELD(G.genital_flags, CAN_CLIMAX_WITH)) //Skip things like wombs and testicles
+ continue
+ var/mob/living/partner
+ var/check_target
+ var/list/worn_stuff = get_equipped_items()
- if(G.is_exposed(worn_stuff))
- if(src.pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
- if(isliving(src.pulling)) //Don't fuck objects
- check_target = src.pulling
- if(src.pulledby && !check_target) //prioritise pulled over pulledby
- if(isliving(src.pulledby))
- check_target = src.pulledby
- //Now we should have a partner, or else we have to come alone
- if(check_target)
- if(iscarbon(check_target)) //carbons can have clothes
- var/mob/living/carbon/C = check_target
- if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
- partner = C
- else //A cat is fine too
- partner = check_target
- if(partner) //Did they pass the clothing checks?
- mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
- continue //You've climaxed once with this organ, continue on
- //not exposed OR if no partner was found while exposed, climax alone
- mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
- //Now all genitals that could climax, have.
- //Since this was a forced climax, we do not need to continue with the other stuff
- return
- //If we get here, then this is not a forced climax and we gotta check a few things.
+ if(G.is_exposed(worn_stuff))
+ if(pulling) //Are we pulling someone? Priority target, we can't be making option menus for this, has to be quick
+ if(isliving(pulling)) //Don't fuck objects
+ check_target = pulling
+ if(pulledby && !check_target) //prioritise pulled over pulledby
+ if(isliving(pulledby))
+ check_target = pulledby
+ //Now we should have a partner, or else we have to come alone
+ if(check_target)
+ if(iscarbon(check_target)) //carbons can have clothes
+ var/mob/living/carbon/C = check_target
+ if(C.exposed_genitals.len || C.is_groin_exposed() || C.is_chest_exposed()) //Are they naked enough?
+ partner = C
+ else //A cat is fine too
+ partner = check_target
+ if(partner) //Did they pass the clothing checks?
+ mob_climax_partner(G, partner, mb_time = 0) //Instant climax due to forced
+ continue //You've climaxed once with this organ, continue on
+ //not exposed OR if no partner was found while exposed, climax alone
+ mob_climax_outside(G, mb_time = 0) //removed climax timer for sudden, forced orgasms
+ //Now all genitals that could climax, have.
+ //Since this was a forced climax, we do not need to continue with the other stuff
+ mb_cd_timer = world.time + mb_cd_length
+ return
+ //If we get here, then this is not a forced climax and we gotta check a few things.
- if(stat==1) //No sleep-masturbation, you're unconscious.
- to_chat(src, "You must be conscious to do that! ")
- return
- if(getArousalLoss() < 33) //flat number instead of percentage
- to_chat(src, "You aren't aroused enough for that! ")
- return
+ if(stat == UNCONSCIOUS) //No sleep-masturbation, you're unconscious.
+ to_chat(src, "You must be conscious to do that! ")
+ return
+ if(getArousalLoss() < 33) //flat number instead of percentage
+ to_chat(src, "You aren't aroused enough for that! ")
+ return
- //Ok, now we check what they want to do.
- var/choice = input(src, "Select sexual activity", "Sexual activity:") in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
+ //Ok, now we check what they want to do.
+ var/choice = input(src, "Select sexual activity", "Sexual activity:") as null|anything in list("Masturbate", "Climax alone", "Climax with partner", "Fill container")
+ if(!choice)
+ return
- switch(choice)
- if("Masturbate")
- if(restrained(TRUE)) //TRUE ignores grabs
- to_chat(src, "You can't do that while restrained! ")
- return
- var/free_hands = get_num_arms()
- if(!free_hands)
- to_chat(src, "You need at least one free arm. ")
- return
- for(var/helditem in held_items)//how many hands are free
- if(isobj(helditem))
- free_hands--
- if(free_hands <= 0)
- to_chat(src, "You're holding too many things. ")
- return
- //We got hands, let's pick an organ
- var/obj/item/organ/genital/picked_organ
- picked_organ = pick_masturbate_genitals()
- if(picked_organ)
- mob_masturbate(picked_organ)
- return
- else //They either lack organs that can masturbate, or they didn't pick one.
- to_chat(src, "You cannot masturbate without choosing genitals. ")
- return
+ switch(choice)
+ if("Masturbate")
+ if(!available_rosie_palms())
+ return
+ //We got hands, let's pick an organ
+ var/obj/item/organ/genital/picked_organ = pick_masturbate_genitals()
+ if(picked_organ && available_rosie_palms(TRUE))
+ mob_masturbate(picked_organ)
+ return
- if("Climax alone")
- if(restrained(TRUE)) //TRUE ignores grabs
- to_chat(src, "You can't do that while restrained! ")
- return
- var/free_hands = get_num_arms()
- if(!free_hands)
- to_chat(src, "You need at least one free arm. ")
- return
- for(var/helditem in held_items)//how many hands are free
- if(isobj(helditem))
- free_hands--
- if(free_hands <= 0)
- to_chat(src, "You're holding too many things. ")
- return
- //We got hands, let's pick an organ
- var/obj/item/organ/genital/picked_organ
- picked_organ = pick_climax_genitals()
- if(picked_organ)
- mob_climax_outside(picked_organ)
- return
- else //They either lack organs that can masturbate, or they didn't pick one.
- to_chat(src, "You cannot climax without choosing genitals. ")
- return
+ if("Climax alone")
+ if(!available_rosie_palms())
+ return
+ var/obj/item/organ/genital/picked_organ = pick_climax_genitals()
+ if(picked_organ && available_rosie_palms(TRUE))
+ mob_climax_outside(picked_organ)
- if("Climax with partner")
- //We need no hands, we can be restrained and so on, so let's pick an organ
- var/obj/item/organ/genital/picked_organ
- picked_organ = pick_climax_genitals()
- if(picked_organ)
- var/mob/living/partner = pick_partner() //Get someone
- if(partner)
- var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as anything in list("Yes", "No")
- if(spillage == "Yes")
- mob_climax_partner(picked_organ, partner, TRUE)
- else
- mob_climax_partner(picked_organ, partner, FALSE)
- return
- else
- to_chat(src, "You cannot do this alone. ")
- return
- else //They either lack organs that can masturbate, or they didn't pick one.
- to_chat(src, "You cannot climax without choosing genitals. ")
- return
+ if("Climax with partner")
+ //We need no hands, we can be restrained and so on, so let's pick an organ
+ var/obj/item/organ/genital/picked_organ = pick_climax_genitals()
+ if(picked_organ)
+ var/mob/living/partner = pick_partner() //Get someone
+ if(partner)
+ var/spillage = input(src, "Would your fluids spill outside?", "Choose overflowing option", "Yes") as null|anything in list("Yes", "No")
+ if(spillage && in_range(src, partner))
+ mob_climax_partner(picked_organ, partner, spillage == "Yes" ? TRUE : FALSE)
- if("Fill container")
- //We'll need hands and no restraints.
- if(restrained(TRUE)) //TRUE ignores grabs
- to_chat(src, "You can't do that while restrained! ")
- return
- var/free_hands = get_num_arms()
- if(!free_hands)
- to_chat(src, "You need at least one free arm. ")
- return
- for(var/helditem in held_items)//how many hands are free
- if(isobj(helditem))
- free_hands--
- if(free_hands <= 0)
- to_chat(src, "You're holding too many things. ")
- return
- //We got hands, let's pick an organ
- var/obj/item/organ/genital/picked_organ
- picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
- if(picked_organ)
- //Good, got an organ, time to pick a container
- var/obj/item/reagent_containers/fluid_container = pick_climax_container()
- if(fluid_container)
- mob_fill_container(picked_organ, fluid_container)
- return
- else
- to_chat(src, "You cannot do this without anything to fill. ")
- return
- else //They either lack organs that can climax, or they didn't pick one.
- to_chat(src, "You cannot fill anything without choosing genitals. ")
- return
- else //Somehow another option was taken, maybe something interrupted the selection or it was cancelled
- return //Just end it in that case.
+ if("Fill container")
+ //We'll need hands and no restraints.
+ if(!available_rosie_palms(FALSE, /obj/item/reagent_containers))
+ return
+ //We got hands, let's pick an organ
+ var/obj/item/organ/genital/picked_organ
+ picked_organ = pick_climax_genitals() //Gotta be climaxable, not just masturbation, to fill with fluids.
+ if(picked_organ)
+ //Good, got an organ, time to pick a container
+ var/obj/item/reagent_containers/fluid_container = pick_climax_container()
+ if(fluid_container && available_rosie_palms(TRUE, /obj/item/reagent_containers))
+ mob_fill_container(picked_organ, fluid_container)
+
+ mb_cd_timer = world.time + mb_cd_length
\ No newline at end of file
diff --git a/modular_citadel/code/modules/arousal/genitals.dm b/modular_citadel/code/modules/arousal/genitals.dm
new file mode 100644
index 0000000000..9ecf67e4b0
--- /dev/null
+++ b/modular_citadel/code/modules/arousal/genitals.dm
@@ -0,0 +1,339 @@
+/obj/item/organ/genital
+ color = "#fcccb3"
+ w_class = WEIGHT_CLASS_NORMAL
+ var/shape = "human"
+ var/sensitivity = AROUSAL_START_VALUE
+ var/genital_flags //see citadel_defines.dm
+ var/masturbation_verb = "masturbate"
+ var/orgasm_verb = "cumming" //present continous
+ var/fluid_transfer_factor = 0 //How much would a partner get in them if they climax using this?
+ var/size = 2 //can vary between num or text, just used in icon_state strings
+ var/fluid_id = null
+ var/fluid_max_volume = 50
+ var/fluid_efficiency = 1
+ var/fluid_rate = CUM_RATE
+ var/fluid_mult = 1
+ var/aroused_state = FALSE //Boolean used in icon_state strings
+ var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons.
+ var/obj/item/organ/genital/linked_organ
+ var/linked_organ_slot //used for linking an apparatus' organ to its other half on update_link().
+ var/layer_index = GENITAL_LAYER_INDEX //Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
+
+/obj/item/organ/genital/Initialize(mapload, mob/living/carbon/human/H)
+ . = ..()
+ if(fluid_id)
+ create_reagents(fluid_max_volume)
+ if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
+ reagents.add_reagent(fluid_id, fluid_max_volume)
+ if(H)
+ get_features(H)
+ Insert(H)
+ else
+ update()
+
+/obj/item/organ/genital/Destroy()
+ if(linked_organ)
+ update_link(TRUE)//this should remove any other links it has
+ if(owner)
+ Remove(owner, TRUE)//this should remove references to it, so it can be GCd correctly
+ return ..()
+
+/obj/item/organ/genital/proc/update(removing = FALSE)
+ if(QDELETED(src))
+ return
+ update_size()
+ update_appearance()
+ if(linked_organ_slot || (linked_organ && removing))
+ update_link(removing)
+
+//exposure and through-clothing code
+/mob/living/carbon
+ var/list/exposed_genitals = list() //Keeping track of them so we don't have to iterate through every genitalia and see if exposed
+
+/obj/item/organ/genital/proc/is_exposed()
+ if(!owner || CHECK_BITFIELD(genital_flags, GENITAL_INTERNAL) || CHECK_BITFIELD(genital_flags, GENITAL_HIDDEN))
+ return FALSE
+ if(CHECK_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES))
+ return TRUE
+
+ switch(zone) //update as more genitals are added
+ if(BODY_ZONE_CHEST)
+ return owner.is_chest_exposed()
+ if(BODY_ZONE_PRECISE_GROIN)
+ return owner.is_groin_exposed()
+
+/obj/item/organ/genital/proc/toggle_visibility(visibility)
+ switch(visibility)
+ if("Always visible")
+ ENABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
+ DISABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
+ if(!(src in owner.exposed_genitals))
+ owner.exposed_genitals += src
+ if("Hidden by clothes")
+ DISABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
+ DISABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
+ if(src in owner.exposed_genitals)
+ owner.exposed_genitals -= src
+ if("Always hidden")
+ DISABLE_BITFIELD(genital_flags, GENITAL_THROUGH_CLOTHES)
+ ENABLE_BITFIELD(genital_flags, GENITAL_HIDDEN)
+ if(src in owner.exposed_genitals)
+ owner.exposed_genitals -= src
+
+ if(ishuman(owner)) //recast to use update genitals proc
+ var/mob/living/carbon/human/H = owner
+ H.update_genitals()
+
+/mob/living/carbon/verb/toggle_genitals()
+ set category = "IC"
+ set name = "Expose/Hide genitals"
+ set desc = "Allows you to toggle which genitals should show through clothes or not."
+
+ var/list/genital_list = list()
+ for(var/obj/item/organ/O in internal_organs)
+ if(isgenital(O))
+ var/obj/item/organ/genital/G = O
+ if(!CHECK_BITFIELD(G.genital_flags, GENITAL_INTERNAL))
+ genital_list += G
+ if(!genital_list.len) //There is nothing to expose
+ return
+ //Full list of exposable genitals created
+ var/obj/item/organ/genital/picked_organ
+ picked_organ = input(src, "Choose which genitalia to expose/hide", "Expose/Hide genitals", null) in genital_list
+ if(picked_organ)
+ var/picked_visibility = input(src, "Choose visibility setting", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
+ picked_organ.toggle_visibility(picked_visibility)
+ return
+
+/obj/item/organ/genital/proc/modify_size(modifier, min = -INFINITY, max = INFINITY)
+ return
+
+/obj/item/organ/genital/proc/update_size()
+ return
+
+/obj/item/organ/genital/proc/update_appearance()
+ if(!owner || owner.stat == DEAD)
+ aroused_state = FALSE
+
+/obj/item/organ/genital/on_life()
+ if(!reagents || !owner)
+ return
+ reagents.maximum_volume = fluid_max_volume
+ if(fluid_id && CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION))
+ generate_fluid()
+
+/obj/item/organ/genital/proc/generate_fluid()
+ var/amount = fluid_rate
+ if(!reagents.total_volume && amount < 0.1) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
+ amount += 0.1
+ var/multiplier = fluid_mult
+ if(reagents.total_volume >= 5)
+ multiplier *= 0.5
+ if(reagents.total_volume < reagents.maximum_volume)
+ reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
+ reagents.add_reagent(fluid_id, (amount * multiplier))//generate the cum
+ return TRUE
+ return FALSE
+
+/obj/item/organ/genital/proc/update_link(removing = FALSE)
+ if(!removing && owner)
+ if(linked_organ)
+ return
+ linked_organ = owner.getorganslot(linked_organ_slot)
+ if(linked_organ)
+ linked_organ.linked_organ = src
+ linked_organ.upon_link()
+ upon_link()
+ return TRUE
+ else
+ if(linked_organ)
+ linked_organ.linked_organ = null
+ linked_organ = null
+ return FALSE
+
+//post organ duo making arrangements.
+/obj/item/organ/genital/proc/upon_link()
+ return
+
+/obj/item/organ/genital/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
+ . = ..()
+ if(.)
+ update()
+ RegisterSignal(owner, COMSIG_MOB_DEATH, .proc/update_appearance)
+
+/obj/item/organ/genital/Remove(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE)
+ . = ..()
+ if(.)
+ update(TRUE)
+ UnregisterSignal(M, COMSIG_MOB_DEATH)
+
+//proc to give a player their genitals and stuff when they log in
+/mob/living/carbon/human/proc/give_genitals(clean = FALSE)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
+ if(clean)
+ for(var/obj/item/organ/genital/G in internal_organs)
+ qdel(G)
+ if (NOGENITALS in dna.species.species_traits)
+ return
+ if(dna.features["has_vag"])
+ give_genital(/obj/item/organ/genital/vagina)
+ if(dna.features["has_womb"])
+ give_genital(/obj/item/organ/genital/womb)
+ if(dna.features["has_balls"])
+ give_genital(/obj/item/organ/genital/testicles)
+ if(dna.features["has_breasts"])
+ give_genital(/obj/item/organ/genital/breasts)
+ if(dna.features["has_cock"])
+ give_genital(/obj/item/organ/genital/penis)
+ /*
+ if(dna.features["has_ovi"])
+ give_genital(/obj/item/organ/genital/ovipositor)
+ if(dna.features["has_eggsack"])
+ give_genital(/obj/item/organ/genital/eggsack)
+ */
+
+/mob/living/carbon/human/proc/give_genital(obj/item/organ/genital/G)
+ if(!dna || (NOGENITALS in dna.species.species_traits) || getorganslot(initial(G.slot)))
+ return FALSE
+ G = new G(null, src)
+ return G
+
+/obj/item/organ/genital/proc/get_features(mob/living/carbon/human/H)
+ return
+
+/datum/species/proc/genitals_layertext(layer)
+ switch(layer)
+ if(GENITALS_BEHIND_LAYER)
+ return "BEHIND"
+ if(GENITALS_FRONT_LAYER)
+ return "FRONT"
+
+//procs to handle sprite overlays being applied to humans
+
+/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
+ . = ..()
+ if(!. && I && slot && !(slot in GLOB.no_genitals_update_slots)) //the item was successfully equipped, and the chosen slot wasn't merely storage, hands or cuffs.
+ update_genitals()
+
+/mob/living/carbon/human/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE)
+ var/no_update = FALSE
+ if(!I || I == l_store || I == r_store || I == s_store || I == handcuffed || I == legcuffed || get_held_index_of_item(I)) //stops storages, cuffs and held items from triggering it.
+ no_update = TRUE
+ . = ..()
+ if(!. || no_update)
+ return
+ update_genitals()
+
+/mob/living/carbon/human/proc/update_genitals()
+ if(!QDELETED(src))
+ dna.species.handle_genitals(src)
+
+//Checks to see if organs are new on the mob, and changes their colours so that they don't get crazy colours.
+/mob/living/carbon/human/proc/emergent_genital_call()
+ if(!canbearoused)
+ return FALSE
+
+ var/organCheck = locate(/obj/item/organ/genital) in internal_organs
+ var/breastCheck = getorganslot(ORGAN_SLOT_BREASTS)
+ var/willyCheck = getorganslot(ORGAN_SLOT_PENIS)
+
+ if(organCheck == FALSE)
+ if(ishuman(src) && dna.species.id == "human")
+ dna.features["genitals_use_skintone"] = TRUE
+ dna.species.use_skintones = TRUE
+ if(MUTCOLORS)
+ if(src.dna.species.fixed_mut_color)
+ dna.features["cock_color"] = "[dna.species.fixed_mut_color]"
+ dna.features["breasts_color"] = "[dna.species.fixed_mut_color]"
+ return
+ //So people who haven't set stuff up don't get rainbow surprises.
+ dna.features["cock_color"] = "[dna.features["mcolor"]]"
+ dna.features["breasts_color"] = "[dna.features["mcolor"]]"
+ else //If there's a new organ, make it the same colour.
+ if(breastCheck == FALSE)
+ dna.features["breasts_color"] = dna.features["cock_color"]
+ else if (willyCheck == FALSE)
+ dna.features["cock_color"] = dna.features["breasts_color"]
+ return TRUE
+
+/datum/species/proc/handle_genitals(mob/living/carbon/human/H)//more like handle sadness
+ if(!H)//no args
+ CRASH("H = null")
+ if(!LAZYLEN(H.internal_organs) || ((NOGENITALS in species_traits) && !H.genital_override) || HAS_TRAIT(H, TRAIT_HUSK))
+ return
+ var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_FRONT_LAYER)
+
+ for(var/L in relevant_layers) //Less hardcode
+ H.remove_overlay(L)
+ H.remove_overlay(GENITALS_EXPOSED_LAYER)
+ //start scanning for genitals
+
+ var/list/gen_index[GENITAL_LAYER_INDEX_LENGTH]
+ var/list/genitals_to_add
+ var/list/fully_exposed
+ for(var/obj/item/organ/genital/G in H.internal_organs)
+ if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
+ LAZYADD(gen_index[G.layer_index], G)
+ for(var/L in gen_index)
+ if(L) //skip nulls
+ LAZYADD(genitals_to_add, L)
+ if(!genitals_to_add)
+ return
+ //Now we added all genitals that aren't internal and should be rendered
+ //start applying overlays
+ for(var/layer in relevant_layers)
+ var/list/standing = list()
+ var/layertext = genitals_layertext(layer)
+ for(var/A in genitals_to_add)
+ var/obj/item/organ/genital/G = A
+ var/datum/sprite_accessory/S
+ var/size = G.size
+ var/aroused_state = G.aroused_state
+ switch(G.type)
+ if(/obj/item/organ/genital/penis)
+ S = GLOB.cock_shapes_list[G.shape]
+ if(/obj/item/organ/genital/testicles)
+ S = GLOB.balls_shapes_list[G.shape]
+ if(/obj/item/organ/genital/vagina)
+ S = GLOB.vagina_shapes_list[G.shape]
+ if(/obj/item/organ/genital/breasts)
+ S = GLOB.breasts_shapes_list[G.shape]
+
+ if(!S || S.icon_state == "none")
+ continue
+
+ var/mutable_appearance/genital_overlay = mutable_appearance(S.icon, layer = -layer)
+ genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]_[aroused_state]_[layertext]"
+
+ if(S.center)
+ genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
+
+ if(use_skintones && H.dna.features["genitals_use_skintone"])
+ genital_overlay.color = "#[skintone2hex(H.skin_tone)]"
+ genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]"
+ else
+ switch(S.color_src)
+ if("cock_color")
+ genital_overlay.color = "#[H.dna.features["cock_color"]]"
+ if("balls_color")
+ genital_overlay.color = "#[H.dna.features["balls_color"]]"
+ if("breasts_color")
+ genital_overlay.color = "#[H.dna.features["breasts_color"]]"
+ if("vag_color")
+ genital_overlay.color = "#[H.dna.features["vag_color"]]"
+
+ if(layer == GENITALS_FRONT_LAYER && CHECK_BITFIELD(G.genital_flags, GENITAL_THROUGH_CLOTHES))
+ genital_overlay.layer = -GENITALS_EXPOSED_LAYER
+ LAZYADD(fully_exposed, genital_overlay) // to be added to a layer with higher priority than clothes, hence the name of the bitflag.
+ else
+ standing += genital_overlay
+
+ if(LAZYLEN(standing))
+ H.overlays_standing[layer] = standing
+
+ if(LAZYLEN(fully_exposed))
+ H.overlays_standing[GENITALS_EXPOSED_LAYER] = fully_exposed
+ H.apply_overlay(GENITALS_EXPOSED_LAYER)
+
+ for(var/L in relevant_layers)
+ H.apply_overlay(L)
+
diff --git a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm b/modular_citadel/code/modules/arousal/genitals_sprite_accessories.dm
similarity index 89%
rename from modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm
rename to modular_citadel/code/modules/arousal/genitals_sprite_accessories.dm
index f4af8a40ba..15d84fa008 100644
--- a/modular_citadel/code/modules/arousal/organs/genitals_sprite_accessories.dm
+++ b/modular_citadel/code/modules/arousal/genitals_sprite_accessories.dm
@@ -5,11 +5,9 @@
//DICKS,COCKS,PENISES,WHATEVER YOU WANT TO CALL THEM
/datum/sprite_accessory/penis
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
- icon_state = null
name = "penis" //the preview name of the accessory
- gender_specific = 0 //Might be needed somewhere down the list.
color_src = "cock_color"
- locked = 0
+ alt_aroused = TRUE
/datum/sprite_accessory/penis/human
icon_state = "human"
@@ -75,27 +73,21 @@
icon_state = "testicle"
name = "testicle" //the preview name of the accessory
color_src = "balls_color"
- locked = 0
/datum/sprite_accessory/testicles/hidden
- icon_state = "hidden"
+ icon_state = "none"
name = "Hidden"
- alt_aroused = TRUE
/datum/sprite_accessory/testicles/single
icon_state = "single"
name = "Single"
- alt_aroused = TRUE
//Vaginas
/datum/sprite_accessory/vagina
icon = 'modular_citadel/icons/obj/genitals/vagina_onmob.dmi'
icon_state = null
name = "vagina"
- gender_specific = 0
color_src = "vag_color"
- locked = 0
- alt_aroused = FALSE //if this is TRUE, then the genitals will use an alternate sprite for aroused states
/datum/sprite_accessory/vagina/human
icon_state = "human"
@@ -131,35 +123,28 @@
//BREASTS BE HERE
/datum/sprite_accessory/breasts
icon = 'modular_citadel/icons/obj/genitals/breasts_onmob.dmi'
- icon_state = null
name = "breasts"
- gender_specific = 0
color_src = "breasts_color"
- locked = 0
+ alt_aroused = TRUE
/datum/sprite_accessory/breasts/pair
icon_state = "pair"
name = "Pair"
- alt_aroused = TRUE
/datum/sprite_accessory/breasts/quad
icon_state = "quad"
name = "Quad"
- alt_aroused = TRUE
/datum/sprite_accessory/breasts/sextuple
icon_state = "sextuple"
name = "Sextuple"
- alt_aroused = TRUE
//OVIPOSITORS BE HERE
/datum/sprite_accessory/ovipositor
icon = 'modular_citadel/icons/obj/genitals/penis_onmob.dmi'
icon_state = null
name = "Ovipositor" //the preview name of the accessory
- gender_specific = 0 //Might be needed somewhere down the list.
color_src = "cock_color"
- locked = 0
/datum/sprite_accessory/ovipositor/knotted
icon_state = "knotted"
diff --git a/modular_citadel/code/modules/arousal/organs/breasts.dm b/modular_citadel/code/modules/arousal/organs/breasts.dm
index 3df2218766..6299f68b6c 100644
--- a/modular_citadel/code/modules/arousal/organs/breasts.dm
+++ b/modular_citadel/code/modules/arousal/organs/breasts.dm
@@ -1,50 +1,29 @@
/obj/item/organ/genital/breasts
- name = "breasts"
- desc = "Female milk producing organs."
- icon_state = "breasts"
- icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
- zone = "chest"
- slot = "breasts"
- w_class = 3
- size = BREASTS_SIZE_DEF //SHOULD BE A LETTER, starts as a number...???
- var/cached_size = null //for enlargement SHOULD BE A NUMBER
- var/prev_size //For flavour texts SHOULD BE A LETTER
- //var/breast_sizes = list ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "huge", "flat")
- var/breast_values = list ("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "flat" = 0)
- var/statuscheck = FALSE
- fluid_id = "milk"
- var/amount = 2
- producing = TRUE
- shape = "Pair"
- can_masturbate_with = TRUE
- masturbation_verb = "massage"
- can_climax = TRUE
- fluid_transfer_factor = 0.5
+ name = "breasts"
+ desc = "Female milk producing organs."
+ icon_state = "breasts"
+ icon = 'modular_citadel/icons/obj/genitals/breasts.dmi'
+ zone = BODY_ZONE_CHEST
+ slot = ORGAN_SLOT_BREASTS
+ size = "c" //refer to the breast_values static list below for the cups associated number values
+ fluid_id = "milk"
+ shape = "pair"
+ genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH|GENITAL_FUID_PRODUCTION
+ masturbation_verb = "massage"
+ orgasm_verb = "leaking"
+ fluid_transfer_factor = 0.5
+ var/static/list/breast_values = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "flat" = 0)
+ var/cached_size //these two vars pertain size modifications and so should be expressed in NUMBERS.
+ var/prev_size //former cached_size value, to allow update_size() to early return should be there no significant changes.
-/obj/item/organ/genital/breasts/on_life()
- if(QDELETED(src))
- return
- if(!reagents || !owner)
- return
- reagents.maximum_volume = fluid_max_volume
- if(fluid_id && producing)
- if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
- fluid_rate = 0.1
- else
- fluid_rate = CUM_RATE
- if(reagents.total_volume >= 5)
- fluid_mult = 0.5
- else
- fluid_mult = 1
- generate_milk()
-
-/obj/item/organ/genital/breasts/proc/generate_milk()
- if(owner.stat == DEAD)
- return FALSE
- reagents.isolate_reagent(fluid_id)
- reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))
+/obj/item/organ/genital/breasts/Initialize(mapload, mob/living/carbon/human/H)
+ if(!H)
+ cached_size = breast_values[size]
+ prev_size = cached_size
+ return ..()
/obj/item/organ/genital/breasts/update_appearance()
+ . = ..()
var/lowershape = lowertext(shape)
switch(lowershape)
if("pair")
@@ -55,16 +34,15 @@
desc = "You see three sets of breasts, running from their chest to their belly."
else
desc = "You see some breasts, they seem to be quite exotic."
- if(cached_size > 16)
+ if(size == "huge")
desc = "You see [pick("some serious honkers", "a real set of badonkers", "some dobonhonkeros", "massive dohoonkabhankoloos", "two big old tonhongerekoogers", "a couple of giant bonkhonagahoogs", "a pair of humongous hungolomghnonoloughongous")]. Their volume is way beyond cupsize now, measuring in about [round(cached_size)]cm in diameter."
- else if (!isnum(size))
+ else
if (size == "flat")
desc += " They're very small and flatchested, however."
else
desc += " You estimate that they're [uppertext(size)]-cups."
- //string = "breasts_[lowertext(shape)]_[size]-s"
- if(producing && aroused_state)
+ if(CHECK_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION) && aroused_state)
desc += " They're leaking [fluid_id]."
var/string
if(owner)
@@ -80,57 +58,70 @@
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
-
icon_state = sanitize_text(string)
-
//Allows breasts to grow and change size, with sprite changes too.
//maximum wah
//Comical sizes slow you down in movement and actions.
//Rediculous sizes makes you more cumbersome.
//this is far too lewd wah
-/obj/item/organ/genital/breasts/update_size()//wah
-
- if(!ishuman(owner) || !owner)
+/obj/item/organ/genital/breasts/modify_size(modifier, min = -INFINITY, max = INFINITY)
+ var/new_value = CLAMP(cached_size + modifier, min, max)
+ if(new_value == cached_size)
return
- if(cached_size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!fixed
- to_chat(owner, "You feel your breasts shrinking away from your body as your chest flattens out. ")
- src.Remove(owner)
- switch(round(cached_size))
- if(0) //If flatchested
- size = "flat"
- if(owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
- owner.remove_status_effect(/datum/status_effect/chem/breast_enlarger)
- statuscheck = FALSE
- if(1 to 8) //If modest size
- size = breast_values[round(cached_size)]
- if(owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
- owner.remove_status_effect(/datum/status_effect/chem/breast_enlarger)
- statuscheck = FALSE
- if(9 to 15) //If massive
- size = breast_values[round(cached_size)]
- if(!owner.has_status_effect(/datum/status_effect/chem/breast_enlarger))
- owner.apply_status_effect(/datum/status_effect/chem/breast_enlarger)
- statuscheck = TRUE
- if(16 to INFINITY) //if Rediculous
- size = cached_size
+ prev_size = cached_size
+ cached_size = new_value
+ update()
- if(round(cached_size) < 16)//Because byond doesn't count from 0, I have to do this.
- if (prev_size == 0)
- prev_size = "flat"
- if(size == 0)//Bloody byond with it's counting from 1
+/obj/item/organ/genital/breasts/update_size()//wah
+ var/rounded_cached = round(cached_size)
+ if(cached_size < 0)//I don't actually know what round() does to negative numbers, so to be safe!!fixed
+ if(owner)
+ to_chat(owner, "You feel your breasts shrinking away from your body as your chest flattens out. ")
+ QDEL_IN(src, 1)
+ return
+ var/enlargement = FALSE
+ switch(rounded_cached)
+ if(0) //flatchested
size = "flat"
- if(isnum(prev_size))
- prev_size = breast_values[prev_size]
- if (breast_values[size] > breast_values[prev_size])
- to_chat(owner, "Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [uppertext(size)]-cup. ")
- var/mob/living/carbon/human/H = owner
- H.Force_update_genitals()
- else if ((breast_values[size] < breast_values[prev_size]) && (breast_values[size] > 0.5))
- to_chat(owner, "Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [uppertext(size)]-cup. ")
- var/mob/living/carbon/human/H = owner
- H.Force_update_genitals()
- prev_size = size
- else if (cached_size >= 16)
- size = "huge"
+ if(1 to 8) //modest
+ size = breast_values[rounded_cached]
+ if(9 to 15) //massive
+ size = breast_values[rounded_cached]
+ enlargement = TRUE
+ if(16 to INFINITY) //rediculous
+ size = "huge"
+ enlargement = TRUE
+ if(owner)
+ var/status_effect = owner.has_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
+ if(enlargement && !status_effect)
+ owner.apply_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
+ else if(!enlargement && status_effect)
+ owner.remove_status_effect(STATUS_EFFECT_BREASTS_ENLARGEMENT)
+
+ if(rounded_cached < 16 && owner)//Because byond doesn't count from 0, I have to do this.
+ var/mob/living/carbon/human/H = owner
+ var/r_prev_size = round(prev_size)
+ if (rounded_cached > r_prev_size)
+ to_chat(H, "Your breasts [pick("swell up to", "flourish into", "expand into", "burst forth into", "grow eagerly into", "amplify into")] a [uppertext(size)]-cup. ")
+ else if (rounded_cached < r_prev_size)
+ to_chat(H, "Your breasts [pick("shrink down to", "decrease into", "diminish into", "deflate into", "shrivel regretfully into", "contracts into")] a [uppertext(size)]-cup. ")
+
+/obj/item/organ/genital/breasts/get_features(mob/living/carbon/human/H)
+ var/datum/dna/D = H.dna
+ if(D.species.use_skintones && D.features["genitals_use_skintone"])
+ color = "#[skintone2hex(H.skin_tone)]"
+ else
+ color = "#[D.features["breasts_color"]]"
+ size = D.features["breasts_size"]
+ shape = D.features["breasts_shape"]
+ fluid_id = D.features["breasts_fluid"]
+ if(!D.features["breasts_producing"])
+ DISABLE_BITFIELD(genital_flags, GENITAL_FUID_PRODUCTION)
+ if(!isnum(size))
+ cached_size = breast_values[size]
+ else
+ cached_size = size
+ size = breast_values[size]
+ prev_size = cached_size
diff --git a/modular_citadel/code/modules/arousal/organs/eggsack.dm b/modular_citadel/code/modules/arousal/organs/eggsack.dm
index 402d246e40..ebdefd2371 100644
--- a/modular_citadel/code/modules/arousal/organs/eggsack.dm
+++ b/modular_citadel/code/modules/arousal/organs/eggsack.dm
@@ -1,14 +1,14 @@
/obj/item/organ/genital/eggsack
- name = "Egg sack"
- desc = "An egg producing reproductive organ."
- icon_state = "egg_sack"
- icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
- zone = "groin"
- slot = "testicles"
- color = null //don't use the /genital color since it already is colored
- internal = TRUE
+ name = "Egg sack"
+ desc = "An egg producing reproductive organ."
+ icon_state = "egg_sack"
+ icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
+ zone = BODY_ZONE_PRECISE_GROIN
+ slot = ORGAN_SLOT_TESTICLES
+ genital_flags = GENITAL_INTERNAL|GENITAL_BLACKLISTED //unimplemented
+ linked_organ_slot = ORGAN_SLOT_PENIS
+ color = null //don't use the /genital color since it already is colored
var/egg_girth = EGG_GIRTH_DEF
var/cum_mult = CUM_RATE_MULT
var/cum_rate = CUM_RATE
var/cum_efficiency = CUM_EFFICIENCY
- var/obj/item/organ/ovipositor/linked_ovi
diff --git a/modular_citadel/code/modules/arousal/organs/genitals.dm b/modular_citadel/code/modules/arousal/organs/genitals.dm
deleted file mode 100644
index 3abe7ecb1f..0000000000
--- a/modular_citadel/code/modules/arousal/organs/genitals.dm
+++ /dev/null
@@ -1,414 +0,0 @@
-/obj/item/organ/genital
- color = "#fcccb3"
- w_class = WEIGHT_CLASS_NORMAL
- var/shape = "Human" //Changed to be uppercase, let me know if this breaks everything..!!
- var/sensitivity = AROUSAL_START_VALUE
- var/list/genital_flags = list()
- var/can_masturbate_with = FALSE
- var/masturbation_verb = "masturbate"
- var/can_climax = FALSE
- var/fluid_transfer_factor = 0.0 //How much would a partner get in them if they climax using this?
- var/size = 2 //can vary between num or text, just used in icon_state strings
- var/fluid_id = null
- var/fluid_max_volume = 15
- var/fluid_efficiency = 1
- var/fluid_rate = 1
- var/fluid_mult = 1
- var/producing = FALSE
- var/aroused_state = FALSE //Boolean used in icon_state strings
- var/aroused_amount = 50 //This is a num from 0 to 100 for arousal percentage for when to use arousal state icons.
- var/obj/item/organ/genital/linked_organ
- var/through_clothes = FALSE
- var/internal = FALSE
- var/hidden = FALSE
-
-/obj/item/organ/genital/Initialize()
- . = ..()
- if(!reagents)
- create_reagents(fluid_max_volume)
- update()
-
-/obj/item/organ/genital/Destroy()
- remove_ref()
- if(owner)
- Remove(owner, 1)//this should remove references to it, so it can be GCd correctly
- update_link()//this should remove any other links it has
- return ..()
-
-/obj/item/organ/genital/proc/update()
- if(QDELETED(src))
- return
- update_size()
- update_appearance()
- update_link()
-
-//exposure and through-clothing code
-/mob/living/carbon
- var/list/exposed_genitals = list() //Keeping track of them so we don't have to iterate through every genitalia and see if exposed
-
-/obj/item/organ/genital/proc/is_exposed()
- if(!owner)
- return FALSE
- if(hidden)
- return FALSE
- if(internal)
- return FALSE
- if(through_clothes)
- return TRUE
-
- switch(zone) //update as more genitals are added
- if("chest")
- return owner.is_chest_exposed()
- if("groin")
- return owner.is_groin_exposed()
-
- return FALSE
-
-/obj/item/organ/genital/proc/toggle_visibility(visibility)
- switch(visibility)
- if("Always visible")
- through_clothes = TRUE
- hidden = FALSE
- if(!(src in owner.exposed_genitals))
- owner.exposed_genitals += src
- if("Hidden by clothes")
- through_clothes = FALSE
- hidden = TRUE
- if(src in owner.exposed_genitals)
- owner.exposed_genitals -= src
- if("Always hidden")
- through_clothes = FALSE
- hidden = TRUE
- if(src in owner.exposed_genitals)
- owner.exposed_genitals -= src
-
- if(ishuman(owner)) //recast to use update genitals proc
- var/mob/living/carbon/human/H = owner
- H.update_genitals()
-
-/mob/living/carbon/verb/toggle_genitals()
- set category = "IC"
- set name = "Expose/Hide genitals"
- set desc = "Allows you to toggle which genitals should show through clothes or not."
-
- var/list/genital_list = list()
- for(var/obj/item/organ/O in internal_organs)
- if(isgenital(O))
- var/obj/item/organ/genital/G = O
- if(!G.internal)
- genital_list += G
- if(!genital_list.len) //There is nothing to expose
- return
- //Full list of exposable genitals created
- var/obj/item/organ/genital/picked_organ
- picked_organ = input(src, "Choose which genitalia to expose/hide", "Expose/Hide genitals", null) in genital_list
- if(picked_organ)
- var/picked_visibility = input(src, "Choose visibility setting", "Expose/Hide genitals", "Hidden by clothes") in list("Always visible", "Hidden by clothes", "Always hidden")
- picked_organ.toggle_visibility(picked_visibility)
- return
-
-
-
-
-/obj/item/organ/genital/proc/update_size()
- return
-
-/obj/item/organ/genital/proc/update_appearance()
- return
-
-/obj/item/organ/genital/proc/update_link()
- return
-
-/obj/item/organ/genital/proc/remove_ref()
- if(linked_organ)
- linked_organ.linked_organ = null
- linked_organ = null
-
-/obj/item/organ/genital/Insert(mob/living/carbon/M, special = 0)
- ..()
- update()
-
-/obj/item/organ/genital/Remove(mob/living/carbon/M, special = 0)
- ..()
- update()
-
-//proc to give a player their genitals and stuff when they log in
-/mob/living/carbon/human/proc/give_genitals(clean=0)//clean will remove all pre-existing genitals. proc will then give them any genitals that are enabled in their DNA
- if(clean)
- var/obj/item/organ/genital/GtoClean
- for(GtoClean in internal_organs)
- qdel(GtoClean)
- if (NOGENITALS in dna.species.species_traits)
- return
- //Order should be very important. FIRST vagina, THEN testicles, THEN penis, as this affects the order they are rendered in.
- if(dna.features["has_vag"])
- give_vagina()
- if(dna.features["has_womb"])
- give_womb()
- if(dna.features["has_balls"])
- give_balls()
- if(dna.features["has_breasts"]) // since we have multi-boobs as a thing, we'll want to at least draw over these. but not over the pingas.
- give_breasts()
- if(dna.features["has_cock"])
- give_penis()
- if(dna.features["has_ovi"])
- give_ovipositor()
- if(dna.features["has_eggsack"])
- give_eggsack()
-
-/mob/living/carbon/human/proc/give_penis()
- if(!dna)
- return FALSE
- if(NOGENITALS in dna.species.species_traits)
- return FALSE
- if(!getorganslot("penis"))
- var/obj/item/organ/genital/penis/P = new
- P.Insert(src)
- if(P)
- if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
- P.color = "#[skintone2hex(skin_tone)]"
- else
- P.color = "#[dna.features["cock_color"]]"
- P.length = dna.features["cock_length"]
- P.girth_ratio = dna.features["cock_girth_ratio"]
- P.shape = dna.features["cock_shape"]
- P.prev_length = P.length
- P.cached_length = P.length
- P.update()
-
-/mob/living/carbon/human/proc/give_balls()
- if(!dna)
- return FALSE
- if(NOGENITALS in dna.species.species_traits)
- return FALSE
- if(!getorganslot("testicles"))
- var/obj/item/organ/genital/testicles/T = new
- T.Insert(src)
- if(T)
- if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
- T.color = "#[skintone2hex(skin_tone)]"
- else
- T.color = "#[dna.features["balls_color"]]"
- T.size = dna.features["balls_size"]
- T.sack_size = dna.features["balls_sack_size"]
- T.shape = dna.features["balls_shape"]
- if(dna.features["balls_shape"] == "Hidden")
- T.internal = TRUE
- else
- T.internal = FALSE
- T.fluid_id = dna.features["balls_fluid"]
- T.fluid_rate = dna.features["balls_cum_rate"]
- T.fluid_mult = dna.features["balls_cum_mult"]
- T.fluid_efficiency = dna.features["balls_efficiency"]
- T.update()
-
-/mob/living/carbon/human/proc/give_breasts()
- if(!dna)
- return FALSE
- if(NOGENITALS in dna.species.species_traits)
- return FALSE
- if(!getorganslot("breasts"))
- var/obj/item/organ/genital/breasts/B = new
- B.Insert(src)
- if(B)
- if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
- B.color = "#[skintone2hex(skin_tone)]"
- else
- B.color = "#[dna.features["breasts_color"]]"
- B.size = dna.features["breasts_size"]
- if(!isnum(B.size))
- if(B.size == "flat")
- B.cached_size = 0
- B.prev_size = 0
- else if (B.cached_size == "huge")
- B.prev_size = "huge"
- else
- B.cached_size = B.breast_values[B.size]
- B.prev_size = B.size
- else
- B.cached_size = B.size
- B.prev_size = B.size
- B.shape = dna.features["breasts_shape"]
- B.fluid_id = dna.features["breasts_fluid"]
- B.producing = dna.features["breasts_producing"]
- B.update()
-
-
-/mob/living/carbon/human/proc/give_ovipositor()
- return
-/mob/living/carbon/human/proc/give_eggsack()
- return
-
-/mob/living/carbon/human/proc/give_vagina()
- if(!dna)
- return FALSE
- if(NOGENITALS in dna.species.species_traits)
- return FALSE
- if(!getorganslot("vagina"))
- var/obj/item/organ/genital/vagina/V = new
- V.Insert(src)
- if(V)
- if(dna.species.use_skintones && dna.features["genitals_use_skintone"])
- V.color = "#[skintone2hex(skin_tone)]"
- else
- V.color = "[dna.features["vag_color"]]"
- V.shape = "[dna.features["vag_shape"]]"
- V.update()
-
-/mob/living/carbon/human/proc/give_womb()
- if(!dna)
- return FALSE
- if(NOGENITALS in dna.species.species_traits)
- return FALSE
- if(!getorganslot("womb"))
- var/obj/item/organ/genital/womb/W = new
- W.Insert(src)
- if(W)
- W.update()
-
-
-/datum/species/proc/genitals_layertext(layer)
- switch(layer)
- if(GENITALS_BEHIND_LAYER)
- return "BEHIND"
- /*if(GENITALS_ADJ_LAYER)
- return "ADJ"*/
- if(GENITALS_FRONT_LAYER)
- return "FRONT"
-
-//procs to handle sprite overlays being applied to humans
-
-/obj/item/equipped(mob/user, slot)
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- H.update_genitals()
- ..()
-
-/mob/living/carbon/human/doUnEquip(obj/item/I, force)
- . = ..()
- if(!.)
- return
- update_genitals()
-
-/mob/living/carbon/human/proc/update_genitals()
- if(src && !QDELETED(src))
- dna.species.handle_genitals(src)
-
-//fermichem procs
-/mob/living/carbon/human/proc/Force_update_genitals(mob/living/carbon/human/H) //called in fermiChem
- dna.species.handle_genitals(src)//should work.
- //dna.species.handle_breasts(src)
-
-//Checks to see if organs are new on the mob, and changes their colours so that they don't get crazy colours.
-/mob/living/carbon/human/proc/emergent_genital_call()
- var/organCheck = FALSE
- var/breastCheck = FALSE
- var/willyCheck = FALSE
- if(!canbearoused)
- ADD_TRAIT(src, TRAIT_PHARMA, "pharma")//Prefs prevent unwanted organs.
- return
- for(var/obj/item/organ/O in internal_organs)
- if(istype(O, /obj/item/organ/genital))
- organCheck = TRUE
- if(/obj/item/organ/genital/penis)
- //dna.features["has_cock"] = TRUE
- willyCheck = TRUE
- if(/obj/item/organ/genital/breasts)
- //dna.features["has_breasts"] = TRUE//Goddamnit get in there.
- breastCheck = TRUE
- if(organCheck == FALSE)
- if(ishuman(src) && dna.species.id == "human")
- dna.features["genitals_use_skintone"] = TRUE
- dna.species.use_skintones = TRUE
- if(MUTCOLORS)
- if(src.dna.species.fixed_mut_color)
- dna.features["cock_color"] = "[src.dna.species.fixed_mut_color]"
- dna.features["breasts_color"] = "[src.dna.species.fixed_mut_color]"
- return
- //So people who haven't set stuff up don't get rainbow surprises.
- dna.features["cock_color"] = "[dna.features["mcolor"]]"
- dna.features["breasts_color"] = "[dna.features["mcolor"]]"
- else //If there's a new organ, make it the same colour.
- if(breastCheck == FALSE)
- dna.features["breasts_color"] = dna.features["cock_color"]
- else if (willyCheck == FALSE)
- dna.features["cock_color"] = dna.features["breasts_color"]
- return
-
-/datum/species/proc/handle_genitals(mob/living/carbon/human/H)//more like handle sadness
- if(!H)//no args
- CRASH("H = null")
- if(!LAZYLEN(H.internal_organs))//if they have no organs, we're done
- return
- if((NOGENITALS in species_traits) && (H.genital_override = FALSE))//golems and such - things that shouldn't
- return
- if(HAS_TRAIT(H, TRAIT_HUSK))
- return
- var/list/genitals_to_add = list()
- var/list/relevant_layers = list(GENITALS_BEHIND_LAYER, GENITALS_FRONT_LAYER) //GENITALS_ADJ_LAYER removed
- var/list/standing = list()
- var/size
- var/aroused_state
-
- for(var/L in relevant_layers) //Less hardcode
- H.remove_overlay(L)
- //start scanning for genitals
- for(var/obj/item/organ/O in H.internal_organs)
- if(isgenital(O))
- var/obj/item/organ/genital/G = O
- if(G.hidden)
- return //we're gunna just hijack this for updates.
- if(G.is_exposed()) //Checks appropriate clothing slot and if it's through_clothes
- genitals_to_add += H.getorganslot(G.slot)
- //Now we added all genitals that aren't internal and should be rendered
- //start applying overlays
- for(var/layer in relevant_layers)
- var/layertext = genitals_layertext(layer)
- for(var/obj/item/organ/genital/G in genitals_to_add)
- var/datum/sprite_accessory/S
- size = G.size
- aroused_state = G.aroused_state
- switch(G.type)
- if(/obj/item/organ/genital/penis)
- S = GLOB.cock_shapes_list[G.shape]
- if(/obj/item/organ/genital/testicles)
- S = GLOB.balls_shapes_list[G.shape]
- if(/obj/item/organ/genital/vagina)
- S = GLOB.vagina_shapes_list[G.shape]
- if(/obj/item/organ/genital/breasts)
- S = GLOB.breasts_shapes_list[G.shape]
-
-
-
-
- if(!S || S.icon_state == "none")
- continue
-
- var/mutable_appearance/genital_overlay = mutable_appearance(S.icon, layer = -layer)
- genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]_[aroused_state]_[layertext]"
-
- if(S.center)
- genital_overlay = center_image(genital_overlay, S.dimension_x, S.dimension_y)
-
- if(use_skintones && H.dna.features["genitals_use_skintone"])
- genital_overlay.color = "#[skintone2hex(H.skin_tone)]"
- genital_overlay.icon_state = "[G.slot]_[S.icon_state]_[size]-s_[aroused_state]_[layertext]"
- else
- switch(S.color_src)
- if("cock_color")
- genital_overlay.color = "#[H.dna.features["cock_color"]]"
- if("balls_color")
- genital_overlay.color = "#[H.dna.features["balls_color"]]"
- if("breasts_color")
- genital_overlay.color = "#[H.dna.features["breasts_color"]]"
- if("vag_color")
- genital_overlay.color = "#[H.dna.features["vag_color"]]"
-
- standing += genital_overlay
-
- if(LAZYLEN(standing))
- H.overlays_standing[layer] = standing.Copy()
- standing = list()
-
- for(var/L in relevant_layers)
- H.apply_overlay(L)
diff --git a/modular_citadel/code/modules/arousal/organs/ovipositor.dm b/modular_citadel/code/modules/arousal/organs/ovipositor.dm
index 76bf60d93c..c26424d296 100644
--- a/modular_citadel/code/modules/arousal/organs/ovipositor.dm
+++ b/modular_citadel/code/modules/arousal/organs/ovipositor.dm
@@ -3,14 +3,14 @@
desc = "An egg laying reproductive organ."
icon_state = "ovi_knotted_2"
icon = 'modular_citadel/icons/obj/genitals/ovipositor.dmi'
- zone = "groin"
- slot = "penis"
- w_class = 3
+ zone = BODY_ZONE_PRECISE_GROIN
+ slot = ORGAN_SLOT_PENIS
+ genital_flags = GENITAL_BLACKLISTED //unimplemented
shape = "knotted"
size = 3
+ layer_index = PENIS_LAYER_INDEX
var/length = 6 //inches
var/girth = 0
var/girth_ratio = COCK_GIRTH_RATIO_DEF //citadel_defines.dm for these defines
var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
var/list/oviflags = list()
- var/obj/item/organ/eggsack/linked_eggsack
diff --git a/modular_citadel/code/modules/arousal/organs/penis.dm b/modular_citadel/code/modules/arousal/organs/penis.dm
index 43a512acf6..17cd35c144 100644
--- a/modular_citadel/code/modules/arousal/organs/penis.dm
+++ b/modular_citadel/code/modules/arousal/organs/penis.dm
@@ -1,77 +1,78 @@
/obj/item/organ/genital/penis
- name = "penis"
- desc = "A male reproductive organ."
- icon_state = "penis"
- icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
- zone = "groin"
- slot = ORGAN_SLOT_PENIS
- can_masturbate_with = TRUE
- masturbation_verb = "stroke"
- can_climax = TRUE
- fluid_transfer_factor = 0.5
- size = 2 //arbitrary value derived from length and girth for sprites.
- var/length = 6 //inches
- var/cached_length //used to detect a change in length
- var/girth = 4.38
- var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
- var/knot_girth_ratio = KNOT_GIRTH_RATIO_DEF
- var/list/dickflags = list()
- var/list/knotted_types = list("knotted", "barbed, knotted")
- var/prev_length = 6 //really should be renamed to prev_length
+ name = "penis"
+ desc = "A male reproductive organ."
+ icon_state = "penis"
+ icon = 'modular_citadel/icons/obj/genitals/penis.dmi'
+ zone = BODY_ZONE_PRECISE_GROIN
+ slot = ORGAN_SLOT_PENIS
+ masturbation_verb = "stroke"
+ genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
+ linked_organ_slot = ORGAN_SLOT_TESTICLES
+ fluid_transfer_factor = 0.5
+ size = 2 //arbitrary value derived from length and girth for sprites.
+ layer_index = PENIS_LAYER_INDEX
+ var/length = 6 //inches
+ var/prev_length = 6 //really should be renamed to prev_length
+ var/girth = 4.38
+ var/girth_ratio = COCK_GIRTH_RATIO_DEF //0.73; check citadel_defines.dm
-/obj/item/organ/genital/penis/Initialize()
- . = ..()
- /* I hate genitals.*/
-
-/obj/item/organ/genital/penis/update_size()
- var/mob/living/carbon/human/o = owner
- if(!ishuman(o) || !o)
+/obj/item/organ/genital/penis/modify_size(modifier, min = -INFINITY, max = INFINITY)
+ var/new_value = CLAMP(length + modifier, min, max)
+ if(new_value == length)
return
- if(cached_length < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
- var/obj/item/organ/genital/penis/P = o.getorganslot("penis")
- to_chat(o, "You feel your tallywacker shrinking away from your body as your groin flattens out! ")
- P.Remove(o)
- switch(round(cached_length))
- if(0 to 4) //If modest size
- length = cached_length
- size = 1
- if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
- o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
- if(5 to 10) //If modest size
- length = cached_length
- size = 2
- if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
- o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
- if(11 to 20) //If massive
- length = cached_length
- size = 3
- if(owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
- o.remove_status_effect(/datum/status_effect/chem/penis_enlarger)
- if(21 to 35) //If massive and due for large effects
- length = cached_length
- size = 3
- if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
- o.apply_status_effect(/datum/status_effect/chem/penis_enlarger)
- if(36 to INFINITY) //If comical
- length = cached_length
- size = 4 //no new sprites for anything larger yet
- if(!owner.has_status_effect(/datum/status_effect/chem/penis_enlarger))
- o.apply_status_effect(/datum/status_effect/chem/penis_enlarger)
-
- if (round(length) > round(prev_length))
- to_chat(o, "Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis. ")
- else if ((round(length) < round(prev_length)) && (length > 0.5))
- to_chat(o, "Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis. ")
prev_length = length
+ length = CLAMP(length + modifier, min, max)
+ update()
+
+/obj/item/organ/genital/penis/update_size(modified = FALSE)
+ if(length < 0)//I don't actually know what round() does to negative numbers, so to be safe!!
+ if(owner)
+ to_chat(owner, "You feel your tallywacker shrinking away from your body as your groin flattens out! ")
+ QDEL_IN(src, 1)
+ if(linked_organ)
+ QDEL_IN(linked_organ, 1)
+ return
+ var/rounded_length = round(length)
+ var/new_size
+ var/enlargement = FALSE
+ switch(rounded_length)
+ if(0 to 6) //If modest size
+ new_size = 1
+ if(7 to 11) //If large
+ new_size = 2
+ if(12 to 20) //If massive
+ new_size = 3
+ if(21 to 34) //If massive and due for large effects
+ new_size = 3
+ enlargement = TRUE
+ if(35 to INFINITY) //If comical
+ new_size = 4 //no new sprites for anything larger yet
+ enlargement = TRUE
+ if(owner)
+ var/status_effect = owner.has_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
+ if(enlargement && !status_effect)
+ owner.apply_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
+ else if(!enlargement && status_effect)
+ owner.remove_status_effect(STATUS_EFFECT_PENIS_ENLARGEMENT)
+ if(linked_organ)
+ linked_organ.size = CLAMP(size + new_size, BALLS_SIZE_MIN, BALLS_SIZE_MAX)
+ linked_organ.update()
+ size = new_size
+
+ if(owner)
+ if (round(length) > round(prev_length))
+ to_chat(owner, "Your [pick(GLOB.gentlemans_organ_names)] [pick("swells up to", "flourishes into", "expands into", "bursts forth into", "grows eagerly into", "amplifys into")] a [uppertext(round(length))] inch penis. ")
+ else if ((round(length) < round(prev_length)) && (length > 0.5))
+ to_chat(owner, "Your [pick(GLOB.gentlemans_organ_names)] [pick("shrinks down to", "decreases into", "diminishes into", "deflates into", "shrivels regretfully into", "contracts into")] a [uppertext(round(length))] inch penis. ")
icon_state = sanitize_text("penis_[shape]_[size]")
girth = (length * girth_ratio)//Is it just me or is this ludicous, why not make it exponentially decay?
- //I have no idea on how to update sprites and I hate it
/obj/item/organ/genital/penis/update_appearance()
+ . = ..()
var/string
var/lowershape = lowertext(shape)
- desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] penis. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
+ desc = "You see [aroused_state ? "an erect" : "a flaccid"] [lowershape] [name]. You estimate it's about [round(length, 0.25)] inch[round(length, 0.25) != 1 ? "es" : ""] long and [round(girth, 0.25)] inch[round(girth, 0.25) != 1 ? "es" : ""] in girth."
if(owner)
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
@@ -87,13 +88,13 @@
icon_state = sanitize_text(string)
H.update_genitals()
-/obj/item/organ/genital/penis/update_link()
- if(owner)
- linked_organ = (owner.getorganslot("testicles"))
- if(linked_organ)
- linked_organ.linked_organ = src
- linked_organ.size = size
+/obj/item/organ/genital/penis/get_features(mob/living/carbon/human/H)
+ var/datum/dna/D = H.dna
+ if(D.species.use_skintones && D.features["genitals_use_skintone"])
+ color = "#[skintone2hex(H.skin_tone)]"
else
- if(linked_organ)
- linked_organ.linked_organ = null
- linked_organ = null
+ color = "#[D.features["cock_color"]]"
+ length = D.features["cock_length"]
+ girth_ratio = D.features["cock_girth_ratio"]
+ shape = D.features["cock_shape"]
+ prev_length = length
diff --git a/modular_citadel/code/modules/arousal/organs/testicles.dm b/modular_citadel/code/modules/arousal/organs/testicles.dm
index f4ef4b5064..547674a5f1 100644
--- a/modular_citadel/code/modules/arousal/organs/testicles.dm
+++ b/modular_citadel/code/modules/arousal/organs/testicles.dm
@@ -1,82 +1,46 @@
/obj/item/organ/genital/testicles
- name = "testicles"
- desc = "A male reproductive organ."
- icon_state = "testicles"
- icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
- zone = "groin"
- slot = "testicles"
- size = BALLS_SIZE_MIN
- var/size_name = "average"
- shape = "single"
- var/sack_size = BALLS_SACK_SIZE_DEF
- fluid_id = "semen"
- producing = TRUE
- can_masturbate_with = FALSE
- masturbation_verb = "massage"
- can_climax = TRUE
- var/sent_full_message = TRUE //defaults to 1 since they're full to start
+ name = "testicles"
+ desc = "A male reproductive organ."
+ icon_state = "testicles"
+ icon = 'modular_citadel/icons/obj/genitals/testicles.dmi'
+ zone = BODY_ZONE_PRECISE_GROIN
+ slot = ORGAN_SLOT_TESTICLES
+ size = BALLS_SIZE_MIN
+ linked_organ_slot = ORGAN_SLOT_PENIS
+ genital_flags = CAN_MASTURBATE_WITH|MASTURBATE_LINKED_ORGAN|GENITAL_FUID_PRODUCTION
+ var/size_name = "average"
+ shape = "Single"
+ var/sack_size = BALLS_SACK_SIZE_DEF
+ fluid_id = "semen"
+ masturbation_verb = "massage"
+ layer_index = TESTICLES_LAYER_INDEX
-/obj/item/organ/genital/testicles/on_life()
- if(QDELETED(src))
- return
- if(reagents && producing)
- if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
- fluid_rate = 0.1
- else
- fluid_rate = CUM_RATE
- if(reagents.total_volume >= 5)
- fluid_mult = 0.5
- else
- fluid_mult = 1
- generate_cum()
-
-/obj/item/organ/genital/testicles/proc/generate_cum()
- reagents.maximum_volume = fluid_max_volume
- if(reagents.total_volume >= reagents.maximum_volume)
- if(!sent_full_message)
- send_full_message()
- sent_full_message = TRUE
+/obj/item/organ/genital/testicles/generate_fluid()
+ if(!linked_organ && !update_link())
return FALSE
- sent_full_message = FALSE
- update_link()
- if(!linked_organ)
- return FALSE
- reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
- reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
+ . = ..()
+ if(. && reagents.holder_full())
+ to_chat(owner, "Your balls finally feel full, again.")
-/obj/item/organ/genital/testicles/update_link()
- if(owner && !QDELETED(src))
- linked_organ = (owner.getorganslot("penis"))
- if(linked_organ)
- linked_organ.linked_organ = src
- size = linked_organ.size
+/obj/item/organ/genital/testicles/upon_link()
+ size = linked_organ.size
+ update_size()
+ update_appearance()
- else
- if(linked_organ)
- linked_organ.linked_organ = null
- linked_organ = null
-
-/obj/item/organ/genital/testicles/proc/send_full_message(msg = "Your balls finally feel full, again.")
- if(owner && istext(msg))
- to_chat(owner, msg)
- return TRUE
-
-/obj/item/organ/genital/testicles/update_appearance()
+/obj/item/organ/genital/testicles/update_size(modified = FALSE)
switch(size)
- if(0.1 to 1)
+ if(BALLS_SIZE_MIN)
size_name = "average"
- if(1.1 to 2)
+ if(BALLS_SIZE_DEF)
size_name = "enlarged"
- if(2.1 to INFINITY)
+ if(BALLS_SIZE_MAX)
size_name = "engorged"
else
size_name = "nonexistant"
- if(!internal)
- desc = "You see an [size_name] pair of testicles."
- else
- desc = "They don't have any testicles you can see."
-
+/obj/item/organ/genital/testicles/update_appearance()
+ . = ..()
+ desc = "You see an [size_name] pair of testicles."
if(owner)
var/string
if(owner.dna.species.use_skintones && owner.dna.features["genitals_use_skintone"])
@@ -91,3 +55,18 @@
var/mob/living/carbon/human/H = owner
icon_state = sanitize_text(string)
H.update_genitals()
+
+/obj/item/organ/genital/testicles/get_features(mob/living/carbon/human/H)
+ var/datum/dna/D = H.dna
+ if(D.species.use_skintones && D.features["genitals_use_skintone"])
+ color = "#[skintone2hex(H.skin_tone)]"
+ else
+ color = "#[D.features["balls_color"]]"
+ sack_size = D.features["balls_sack_size"]
+ shape = D.features["balls_shape"]
+ if(D.features["balls_shape"] == "Hidden")
+ ENABLE_BITFIELD(genital_flags, GENITAL_INTERNAL)
+ fluid_id = D.features["balls_fluid"]
+ fluid_rate = D.features["balls_cum_rate"]
+ fluid_mult = D.features["balls_cum_mult"]
+ fluid_efficiency = D.features["balls_efficiency"]
diff --git a/modular_citadel/code/modules/arousal/organs/vagina.dm b/modular_citadel/code/modules/arousal/organs/vagina.dm
index 8c15aa5437..0df954fd79 100644
--- a/modular_citadel/code/modules/arousal/organs/vagina.dm
+++ b/modular_citadel/code/modules/arousal/organs/vagina.dm
@@ -1,26 +1,25 @@
/obj/item/organ/genital/vagina
- name = "vagina"
- desc = "A female reproductive organ."
- icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
- icon_state = "vagina"
- zone = "groin"
- slot = "vagina"
- size = 1 //There is only 1 size right now
- can_masturbate_with = TRUE
- masturbation_verb = "finger"
- can_climax = TRUE
+ name = "vagina"
+ desc = "A female reproductive organ."
+ icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
+ icon_state = ORGAN_SLOT_VAGINA
+ zone = BODY_ZONE_PRECISE_GROIN
+ slot = "vagina"
+ size = 1 //There is only 1 size right now
+ genital_flags = CAN_MASTURBATE_WITH|CAN_CLIMAX_WITH
+ masturbation_verb = "finger"
fluid_transfer_factor = 0.1 //Yes, some amount is exposed to you, go get your AIDS
- w_class = 3
- var/cap_length = 8//D E P T H (cap = capacity)
- var/cap_girth = 12
+ layer_index = VAGINA_LAYER_INDEX
+ var/cap_length = 8//D E P T H (cap = capacity)
+ var/cap_girth = 12
var/cap_girth_ratio = 1.5
- var/clits = 1
- var/clit_diam = 0.25
- var/clit_len = 0.25
+ var/clits = 1
+ var/clit_diam = 0.25
+ var/clit_len = 0.25
var/list/vag_types = list("tentacle", "dentata", "hairy", "spade", "furred")
-
/obj/item/organ/genital/vagina/update_appearance()
+ . = ..()
var/string //Keeping this code here, so making multiple sprites for the different kinds is easier.
var/lowershape = lowertext(shape)
var/details
@@ -63,12 +62,10 @@
icon_state = sanitize_text(string)
H.update_genitals()
-/obj/item/organ/genital/vagina/update_link()
- if(owner)
- linked_organ = (owner.getorganslot("womb"))
- if(linked_organ)
- linked_organ.linked_organ = src
+/obj/item/organ/genital/vagina/get_features(mob/living/carbon/human/H)
+ var/datum/dna/D = H.dna
+ if(D.species.use_skintones && D.features["genitals_use_skintone"])
+ color = "#[skintone2hex(H.skin_tone)]"
else
- if(linked_organ)
- linked_organ.linked_organ = null
- linked_organ = null
+ color = "[D.features["vag_color"]]"
+ shape = "[D.features["vag_shape"]]"
diff --git a/modular_citadel/code/modules/arousal/organs/womb.dm b/modular_citadel/code/modules/arousal/organs/womb.dm
index 3f190b72ac..9dfe811571 100644
--- a/modular_citadel/code/modules/arousal/organs/womb.dm
+++ b/modular_citadel/code/modules/arousal/organs/womb.dm
@@ -1,45 +1,10 @@
/obj/item/organ/genital/womb
- name = "womb"
- desc = "A female reproductive organ."
- icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
- icon_state = "womb"
- zone = "groin"
- slot = "womb"
- internal = TRUE
- fluid_id = "femcum"
- producing = TRUE
-
-/obj/item/organ/genital/womb/on_life()
- if(QDELETED(src))
- return
- if(reagents && producing)
- if(reagents.total_volume == 0) // Apparently, 0.015 gets rounded down to zero and no reagents are created if we don't start it with 0.1 in the tank.
- fluid_rate = 0.1
- else
- fluid_rate = CUM_RATE
- if(reagents.total_volume >= 5)
- fluid_mult = 0.5
- else
- fluid_mult = 1
- generate_femcum()
-
-/obj/item/organ/genital/womb/proc/generate_femcum()
- reagents.maximum_volume = fluid_max_volume
- update_link()
- if(!linked_organ)
- return FALSE
- reagents.isolate_reagent(fluid_id)//remove old reagents if it changed and just clean up generally
- reagents.add_reagent(fluid_id, (fluid_mult * fluid_rate))//generate the cum
-
-/obj/item/organ/genital/womb/update_link()
- if(owner)
- linked_organ = (owner.getorganslot("vagina"))
- if(linked_organ)
- linked_organ.linked_organ = src
- else
- if(linked_organ)
- linked_organ.linked_organ = null
- linked_organ = null
-
-/obj/item/organ/genital/womb/Destroy()
- return ..()
+ name = "womb"
+ desc = "A female reproductive organ."
+ icon = 'modular_citadel/icons/obj/genitals/vagina.dmi'
+ icon_state = "womb"
+ zone = BODY_ZONE_PRECISE_GROIN
+ slot = ORGAN_SLOT_WOMB
+ genital_flags = GENITAL_INTERNAL|GENITAL_FUID_PRODUCTION
+ fluid_id = "femcum"
+ linked_organ_slot = ORGAN_SLOT_VAGINA
diff --git a/modular_citadel/code/modules/awaymissions/citadel_ghostrole_spawners.dm b/modular_citadel/code/modules/awaymissions/citadel_ghostrole_spawners.dm
deleted file mode 100644
index ccbf9a42fe..0000000000
--- a/modular_citadel/code/modules/awaymissions/citadel_ghostrole_spawners.dm
+++ /dev/null
@@ -1,73 +0,0 @@
-/obj/effect/mob_spawn/human/lavaknight
- name = "odd cryogenics pod"
- desc = "A humming cryo pod. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant."
- mob_name = "a displaced knight from another dimension"
- icon = 'icons/obj/machines/sleeper.dmi'
- icon_state = "sleeper"
- roundstart = FALSE
- job_description = "Cydonian Knight"
- death = FALSE
- random = TRUE
- outfit = /datum/outfit/lavaknight
- mob_species = /datum/species/human
- flavour_text = "Y ou are a knight who conveniently has some form of retrograde amnesia. \
- You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \
- Remember: hostile creatures and such are fair game for attacking, but under no circumstances are you to attack anything capable of thought and/or speech unless it has made it its life's calling to chase you to the ends of the earth."
- assignedrole = "Cydonian Knight"
-
-/obj/effect/mob_spawn/human/lavaknight/special(mob/living/new_spawn)
- if(ishuman(new_spawn))
- var/mob/living/carbon/human/H = new_spawn
- H.dna.features["mam_ears"] = "Cat, Big" //cat people
- H.dna.features["mcolor"] = H.hair_color
- H.update_body()
-
-/obj/effect/mob_spawn/human/lavaknight/Destroy()
- new/obj/structure/showcase/machinery/oldpod/used(drop_location())
- return ..()
-
-/datum/outfit/lavaknight
- name = "Cydonian Knight"
- uniform = /obj/item/clothing/under/assistantformal
- mask = /obj/item/clothing/mask/breath
- shoes = /obj/item/clothing/shoes/sneakers/black
- r_pocket = /obj/item/melee/transforming/energy/sword/cx
- suit = /obj/item/clothing/suit/space/hardsuit/lavaknight
- suit_store = /obj/item/tank/internals/oxygen
- id = /obj/item/card/id/knight
-
-/datum/outfit/lavaknight/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
- return
-
- var/obj/item/card/id/knight/W = H.wear_id
- W.assignment = "Knight"
- W.registered_name = H.real_name
- W.id_color = "#0000FF" //Regular knights get simple blue. Doesn't matter much because it's variable anyway
- W.update_label(H.real_name)
- W.update_icon()
-
-/datum/outfit/lavaknight/captain
- name ="Cydonian Knight Captain"
- l_pocket = /obj/item/twohanded/dualsaber/hypereutactic
-
-/datum/outfit/lavaknight/captain/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
- if(visualsOnly)
- return
-
- var/obj/item/card/id/knight/W = H.wear_id
- W.assignment = "Knight Captain"
- W.registered_name = H.real_name
- W.id_color = "#FFD700" //Captains get gold, duh. Doesn't matter because it's variable anyway
- W.update_label(H.real_name)
- W.update_icon()
-
-
-/obj/effect/mob_spawn/human/lavaknight/captain
- name = "odd gilded cryogenics pod"
- desc = "A humming cryo pod that appears to be gilded. You can barely recognise a faint glow underneath the built up ice. The machine is attempting to wake up its occupant."
- flavour_text = "Y ou are a knight who conveniently has some form of retrograde amnesia. \
- You cannot remember where you came from. However, a few things remain burnt into your mind, most prominently a vow to never harm another sapient being under any circumstances unless it is hellbent on ending your life. \
- Remember: hostile creatures and such are fair game for attacking, but under no circumstances are you to attack anything capable of thought and/or speech unless it has made it its life's calling to chase you to the ends of the earth. \
- You feel a natural instict to lead, and as such, you should strive to lead your comrades to safety, and hopefully home. You also feel a burning determination to uphold your vow, as well as your fellow comrade's."
- outfit = /datum/outfit/lavaknight/captain
diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm
index cc75e1bff9..6dff621271 100644
--- a/modular_citadel/code/modules/client/loadout/__donator.dm
+++ b/modular_citadel/code/modules/client/loadout/__donator.dm
@@ -447,4 +447,14 @@ datum/gear/darksabresheath
path = /obj/item/clothing/head/blueberet
ckeywhitelist = list("foxystalin")
+/datum/gear/donorgoggles
+ name = "Flight Goggles"
+ category = SLOT_HEAD
+ path = /obj/item/clothing/head/flight
+ ckeywhitelist = list("maxlynchy")
+/datum/gear/onionneck
+ name = "Onion Necklace"
+ category = SLOT_NECK
+ path = /obj/item/clothing/neck/necklace/onion
+ ckeywhitelist = list("cdrcross")
diff --git a/modular_citadel/code/modules/client/loadout/glasses.dm b/modular_citadel/code/modules/client/loadout/glasses.dm
index 9e7b68bf0d..57270d8e57 100644
--- a/modular_citadel/code/modules/client/loadout/glasses.dm
+++ b/modular_citadel/code/modules/client/loadout/glasses.dm
@@ -1,3 +1,8 @@
+/datum/gear/blindfold
+ name = "Blindfold"
+ category = SLOT_GLASSES
+ path = /obj/item/clothing/glasses/sunglasses/blindfold
+
/datum/gear/cold
name = "Cold goggles"
category = SLOT_GLASSES
diff --git a/modular_citadel/code/modules/client/loadout/shoes.dm b/modular_citadel/code/modules/client/loadout/shoes.dm
index 95675ccaeb..6688529c73 100644
--- a/modular_citadel/code/modules/client/loadout/shoes.dm
+++ b/modular_citadel/code/modules/client/loadout/shoes.dm
@@ -37,3 +37,23 @@
name = "White shoes"
category = SLOT_SHOES
path = /obj/item/clothing/shoes/sneakers/white
+
+/datum/gear/gildedcuffs
+ name = "Gilded leg wraps"
+ category = SLOT_SHOES
+ path= /obj/item/clothing/shoes/wraps
+
+/datum/gear/silvercuffs
+ name = "Silver leg wraps"
+ category = SLOT_SHOES
+ path= /obj/item/clothing/shoes/wraps/silver
+
+/datum/gear/redcuffs
+ name = "Red leg wraps"
+ category = SLOT_SHOES
+ path= /obj/item/clothing/shoes/wraps/red
+
+/datum/gear/bluecuffs
+ name = "Blue leg wraps"
+ category = SLOT_SHOES
+ path= /obj/item/clothing/shoes/wraps/blue
\ No newline at end of file
diff --git a/modular_citadel/code/modules/client/loadout/suit.dm b/modular_citadel/code/modules/client/loadout/suit.dm
index 5a12a6bf0b..d3a8258fc0 100644
--- a/modular_citadel/code/modules/client/loadout/suit.dm
+++ b/modular_citadel/code/modules/client/loadout/suit.dm
@@ -64,6 +64,64 @@
category = SLOT_WEAR_SUIT
path = /obj/item/clothing/suit/hooded/wintercoat
+/* Commented out until it is "balanced"
+/datum/gear/coat/sec
+ name = "Security winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/security
+ restricted_roles = list("Head of Security", "Warden", "Detective", "Security Officer") // Reserve it to the Security Departement
+*/
+
+/datum/gear/coat/med
+ name = "Medical winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/medical
+ restricted_roles = list("Chief Medical Officer", "Medical Doctor") // Reserve it to Medical Doctors and their boss, the Chief Medical Officer
+
+/* Commented out until there is a Chemistry Winter Coat
+/datum/gear/coat/med/chem
+ name = "Chemistry winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/medical/chemistry
+ restricted_roles = list("Chief Medical Officer", "Chemist") // Reserve it to Chemists and their boss, the Chief Medical Officer
+*/
+
+/datum/gear/coat/sci
+ name = "Science winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/science
+ restricted_roles = list("Research Director", "Scientist", "Roboticist") // Reserve it to the Science Departement
+
+/datum/gear/coat/eng
+ name = "Engineering winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/engineering
+ restricted_roles = list("Chief Engineer", "Station Engineer") // Reserve it to Station Engineers and their boss, the Chief Engineer
+
+/datum/gear/coat/eng/atmos
+ name = "Atmospherics winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/engineering/atmos
+ restricted_roles = list("Chief Engineer", "Atmospheric Technician") // Reserve it to Atmos Techs and their boss, the Chief Engineer
+
+/datum/gear/coat/hydro
+ name = "Hydroponics winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/hydro
+ restricted_roles = list("Head of Personnel", "Botanist") // Reserve it to Botanists and their boss, the Head of Personnel
+
+/datum/gear/coat/cargo
+ name = "Cargo winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/cargo
+ restricted_roles = list("Quartermaster", "Cargo Technician") // Reserve it to Cargo Techs and their boss, the Quartermaster
+
+/datum/gear/coat/miner
+ name = "Mining winter coat"
+ category = SLOT_WEAR_SUIT
+ path = /obj/item/clothing/suit/hooded/wintercoat/miner
+ restricted_roles = list("Quartermaster", "Shaft Miner") // Reserve it to Miners and their boss, the Quartermaster
+
/datum/gear/militaryjacket
name = "Military Jacket"
category = SLOT_WEAR_SUIT
diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm
index 0a353e3f5d..5584181a70 100644
--- a/modular_citadel/code/modules/client/preferences_savefile.dm
+++ b/modular_citadel/code/modules/client/preferences_savefile.dm
@@ -32,7 +32,6 @@
WRITE_FILE(S["feature_ipc_antenna"], features["ipc_antenna"])
//Citadel
WRITE_FILE(S["feature_genitals_use_skintone"], features["genitals_use_skintone"])
- WRITE_FILE(S["feature_exhibitionist"], features["exhibitionist"])
WRITE_FILE(S["feature_mcolor2"], features["mcolor2"])
WRITE_FILE(S["feature_mcolor3"], features["mcolor3"])
WRITE_FILE(S["feature_mam_body_markings"], features["mam_body_markings"])
diff --git a/modular_citadel/code/modules/clothing/clothing.dm b/modular_citadel/code/modules/clothing/clothing.dm
index fc71d5bdde..7f366ecf35 100644
--- a/modular_citadel/code/modules/clothing/clothing.dm
+++ b/modular_citadel/code/modules/clothing/clothing.dm
@@ -38,6 +38,8 @@
var/secondary_color = "#FFFFFF"
var/tertiary_color = "#808080"
+ var/force_alternate_icon = FALSE
+
/obj/item/clothing/update_icon() // picks the colored overlays from the ICON file
..()
if(hasprimary) //Checks if the overlay is enabled
diff --git a/modular_citadel/code/modules/clothing/glasses/phantomthief.dm b/modular_citadel/code/modules/clothing/glasses/phantomthief.dm
index 49eb089afa..353b0afb14 100644
--- a/modular_citadel/code/modules/clothing/glasses/phantomthief.dm
+++ b/modular_citadel/code/modules/clothing/glasses/phantomthief.dm
@@ -6,41 +6,39 @@
icon_state = "s-ninja"
item_state = "s-ninja"
-/obj/item/clothing/glasses/phantomthief/Initialize()
+/obj/item/clothing/glasses/phantomthief/ComponentInitialize()
. = ..()
- AddComponent(/datum/component/phantomthief)
+ AddComponent(/datum/component/wearertargeting/phantomthief)
/obj/item/clothing/glasses/phantomthief/syndicate
name = "suspicious plastic mask"
desc = "A cheap, bulky, Syndicate-branded plastic face mask. You have to break in to break out."
var/nextadrenalinepop
- var/datum/component/redirect/combattoggle_redir
-/obj/item/clothing/glasses/phantomthief/syndicate/examine(user)
+/obj/item/clothing/glasses/phantomthief/syndicate/examine(mob/user)
. = ..()
- if(combattoggle_redir)
+ if(user.get_item_by_slot(SLOT_GLASSES) == src)
if(world.time >= nextadrenalinepop)
to_chat(user, "The built-in adrenaline injector is ready for use. ")
else
to_chat(user, "[DisplayTimeText(nextadrenalinepop - world.time)] left before the adrenaline injector can be used again.")
/obj/item/clothing/glasses/phantomthief/syndicate/proc/injectadrenaline(mob/user, combatmodestate)
- if(istype(user))
- if(combatmodestate && world.time >= nextadrenalinepop)
- nextadrenalinepop = world.time + 5 MINUTES
- user.reagents.add_reagent("syndicateadrenals", 5)
- user.playsound_local(user, 'modular_citadel/sound/misc/adrenalinject.ogg', 100, 0, pressure_affected = FALSE)
+ if(istype(user) && combatmodestate && world.time >= nextadrenalinepop)
+ nextadrenalinepop = world.time + 5 MINUTES
+ user.reagents.add_reagent("syndicateadrenals", 5)
+ user.playsound_local(user, 'sound/misc/adrenalinject.ogg', 100, 0, pressure_affected = FALSE)
/obj/item/clothing/glasses/phantomthief/syndicate/equipped(mob/user, slot)
. = ..()
if(!istype(user))
return
- if(!combattoggle_redir)
- combattoggle_redir = user.AddComponent(/datum/component/redirect, list(COMSIG_COMBAT_TOGGLED = CALLBACK(src, .proc/injectadrenaline)))
+ if(slot != SLOT_GLASSES)
+ return
+ RegisterSignal(user, COMSIG_COMBAT_TOGGLED, .proc/injectadrenaline)
/obj/item/clothing/glasses/phantomthief/syndicate/dropped(mob/user)
. = ..()
if(!istype(user))
return
- if(combattoggle_redir)
- QDEL_NULL(combattoggle_redir)
+ UnregisterSignal(user, COMSIG_COMBAT_TOGGLED)
diff --git a/modular_citadel/code/modules/clothing/neck.dm b/modular_citadel/code/modules/clothing/neck.dm
index 8d7d4747b7..20324516f6 100644
--- a/modular_citadel/code/modules/clothing/neck.dm
+++ b/modular_citadel/code/modules/clothing/neck.dm
@@ -15,7 +15,7 @@
/datum/action/item_action/zanderlocket/Trigger()
new/obj/effect/temp_visual/souldeath(owner.loc, owner)
- playsound(owner, 'modular_citadel/sound/misc/souldeath.ogg', 100, FALSE)
+ playsound(owner, 'sound/misc/souldeath.ogg', 100, FALSE)
/obj/item/clothing/neck/undertale/Initialize()
diff --git a/modular_citadel/code/modules/clothing/spacesuits/cydonian_armor.dm b/modular_citadel/code/modules/clothing/spacesuits/cydonian_armor.dm
deleted file mode 100644
index 423bc536ac..0000000000
--- a/modular_citadel/code/modules/clothing/spacesuits/cydonian_armor.dm
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- CYDONIAN ARMOR THAT IS RGB AND STUFF WOOOOOOOOOO
-*/
-
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight
- name = "cydonian helmet"
- desc = "A helmet designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
- icon = 'modular_citadel/icons/lavaknight/item/head.dmi'
- icon_state = "knight_cydonia"
- item_state = "knight_yellow"
- item_color = null
- alternate_worn_icon = 'modular_citadel/icons/lavaknight/mob/head.dmi'
- max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
- resistance_flags = FIRE_PROOF | LAVA_PROOF
- heat_protection = HEAD
- armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
- brightness_on = 7
- allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/resonator, /obj/item/mining_scanner, /obj/item/t_scanner/adv_mining_scanner, /obj/item/gun/energy/kinetic_accelerator)
- var/energy_color = "#35FFF0"
- var/obj/item/clothing/suit/space/hardsuit/lavaknight/linkedsuit = null
- mutantrace_variation = NO_MUTANTRACE_VARIATION
-
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/New()
- ..()
- if(istype(loc, /obj/item/clothing/suit/space/hardsuit/lavaknight))
- linkedsuit = loc
-
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/attack_self(mob/user)
- on = !on
-
- if(on)
- set_light(brightness_on)
- else
- set_light(0)
- for(var/X in actions)
- var/datum/action/A = X
- A.UpdateButtonIcon()
-
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/update_icon()
- var/mutable_appearance/helm_overlay = mutable_appearance('modular_citadel/icons/lavaknight/item/head.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
-
- if(energy_color)
- helm_overlay.color = energy_color
-
- helm_overlay.plane = LIGHTING_PLANE + 1 //Magic number is used here because we have no ABOVE_LIGHTING_PLANE plane defined. Lighting plane is 15, HUD is 18
-
- cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
-
- add_overlay(helm_overlay)
-
- emissivelights()
-
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/equipped(mob/user, slot)
- ..()
- if(slot == SLOT_HEAD)
- emissivelights()
-
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/dropped(mob/user)
- ..()
- emissivelightsoff()
-
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/proc/emissivelights(mob/user = usr)
- var/mutable_appearance/energy_overlay = mutable_appearance('modular_citadel/icons/lavaknight/mob/head.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
- energy_overlay.color = energy_color
- energy_overlay.plane = LIGHTING_PLANE + 1
- user.cut_overlay(energy_overlay) //honk
- user.add_overlay(energy_overlay) //honk
-
-/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/proc/emissivelightsoff(mob/user = usr)
- user.cut_overlay()
- linkedsuit.emissivelights() //HONK HONK HONK MAXIMUM SPAGHETTI
- user.regenerate_icons() //honk
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight
- icon = 'modular_citadel/icons/lavaknight/item/suit.dmi'
- icon_state = "knight_cydonia"
- name = "cydonian armor"
- desc = "A suit designed with both form and function in mind, it protects the user against physical trauma and hazardous conditions while also having polychromic light strips."
- item_state = "swat_suit"
- alternate_worn_icon = 'modular_citadel/icons/lavaknight/mob/suit.dmi'
- max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT
- resistance_flags = FIRE_PROOF | LAVA_PROOF
- armor = list(melee = 50, bullet = 10, laser = 10, energy = 10, bomb = 50, bio = 100, rad = 50, fire = 100, acid = 100)
- allowed = list(/obj/item/flashlight, /obj/item/tank/internals, /obj/item/storage/bag/ore, /obj/item/pickaxe)
- helmettype = /obj/item/clothing/head/helmet/space/hardsuit/lavaknight
- heat_protection = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
- actions_types = list(/datum/action/item_action/toggle_helmet)
- var/obj/item/clothing/head/helmet/space/hardsuit/lavaknight/linkedhelm
- tauric = TRUE //Citadel Add for tauric hardsuits
-
- var/energy_color = "#35FFF0"
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/New()
- ..()
- if(helmet)
- linkedhelm = helmet
- light_color = energy_color
- set_light(1)
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/Initialize()
- ..()
- update_icon()
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/update_icon()
- var/mutable_appearance/suit_overlay
-
- if(taurmode == SNEK_TAURIC)
- suit_overlay = mutable_appearance('modular_citadel/icons/mob/taur_naga.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
- else if(taurmode == PAW_TAURIC)
- suit_overlay = mutable_appearance('modular_citadel/icons/mob/taur_canine.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
- else
- suit_overlay = mutable_appearance('modular_citadel/icons/lavaknight/item/suit.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
-
- if(energy_color)
- suit_overlay.color = energy_color
-
- suit_overlay.plane = LIGHTING_PLANE + 1 //Magic number is used here because we have no ABOVE_LIGHTING_PLANE plane defined. Lighting plane is 15.
-
- cut_overlays() //So that it doesn't keep stacking overlays non-stop on top of each other
-
- add_overlay(suit_overlay)
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/equipped(mob/user, slot)
- ..()
- if(slot == SLOT_WEAR_SUIT)
- emissivelights()
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/dropped(mob/user)
- ..()
- emissivelightsoff()
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/proc/emissivelights(mob/user = usr)
- var/mutable_appearance/energy_overlay
- if(taurmode == SNEK_TAURIC)
- energy_overlay = mutable_appearance('modular_citadel/icons/mob/taur_naga.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
- else if(taurmode == PAW_TAURIC)
- energy_overlay = mutable_appearance('modular_citadel/icons/mob/taur_canine.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
- else
- energy_overlay = mutable_appearance('modular_citadel/icons/lavaknight/mob/suit.dmi', "knight_cydonia_overlay", LIGHTING_LAYER + 1)
-
- energy_overlay.color = energy_color
- energy_overlay.plane = LIGHTING_PLANE + 1
- user.cut_overlay(energy_overlay) //honk
- user.add_overlay(energy_overlay) //honk
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/proc/emissivelightsoff(mob/user = usr)
- user.cut_overlays()
- user.regenerate_icons() //honk
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/AltClick(mob/living/user)
- if(user.incapacitated() || !istype(user))
- to_chat(user, "You can't do that right now! ")
- return
- if(!in_range(src, user))
- return
- if(user.incapacitated() || !istype(user) || !in_range(src, user))
- return
-
- if(alert("Are you sure you want to recolor your armor stripes?", "Confirm Repaint", "Yes", "No") == "Yes")
- var/energy_color_input = input(usr,"","Choose Energy Color",energy_color) as color|null
- if(energy_color_input)
- energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
- user.update_inv_wear_suit()
- if(linkedhelm)
- linkedhelm.energy_color = sanitize_hexcolor(energy_color_input, desired_format=6, include_crunch=1)
- user.update_inv_head()
- linkedhelm.update_icon()
- update_icon()
- user.update_inv_wear_suit()
- light_color = energy_color
- emissivelights()
- update_light()
-
-/obj/item/clothing/suit/space/hardsuit/lavaknight/examine(mob/user)
- ..()
- to_chat(user, "Alt-click to recolor it. ")
\ No newline at end of file
diff --git a/modular_citadel/code/modules/clothing/under/trek_under.dm b/modular_citadel/code/modules/clothing/under/trek_under.dm
index a60f7653c5..5cd0620a9d 100644
--- a/modular_citadel/code/modules/clothing/under/trek_under.dm
+++ b/modular_citadel/code/modules/clothing/under/trek_under.dm
@@ -14,6 +14,7 @@
desc = "Oooh... right."
icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi'
alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi'
+ force_alternate_icon = TRUE
item_state = ""
can_adjust = FALSE //to prevent you from "wearing it casually"
@@ -23,7 +24,7 @@
desc = "The uniform worn by command officers in the mid 2260s."
icon_state = "trek_command"
item_state = "trek_command"
- armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
+ armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
/obj/item/clothing/under/rank/trek/engsec
name = "Operations Uniform"
@@ -94,6 +95,7 @@
icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi'
icon_state = "trek_ds9_coat"
alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi'
+ force_alternate_icon = TRUE
item_state = "trek_ds9_coat"
body_parts_covered = CHEST|GROIN|ARMS
mutantrace_variation = NO_MUTANTRACE_VARIATION
@@ -138,6 +140,7 @@
desc = "A uniform jacket from the United Federation. Set phasers to awesome."
icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi'
alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi'
+ force_alternate_icon = TRUE
icon_state = "fedcoat"
item_state = "fedcoat"
mutantrace_variation = NO_MUTANTRACE_VARIATION
@@ -204,6 +207,7 @@
desc = "A modern uniform jacket from the United Federation."
icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi'
alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi'
+ force_alternate_icon = TRUE
icon_state = "fedmodern"
item_state = "fedmodern"
body_parts_covered = CHEST|GROIN|ARMS
@@ -236,6 +240,7 @@
icon = 'modular_citadel/icons/obj/clothing/trek_item_icon.dmi'
icon_state = "fedcapofficer"
alternate_worn_icon = 'modular_citadel/icons/mob/clothing/trek_mob_icon.dmi'
+ force_alternate_icon = TRUE
item_state = "fedcapofficer"
//Variants
diff --git a/modular_citadel/code/modules/custom_loadout/custom_items.dm b/modular_citadel/code/modules/custom_loadout/custom_items.dm
index 5d81dbfa49..11dbb4dc80 100644
--- a/modular_citadel/code/modules/custom_loadout/custom_items.dm
+++ b/modular_citadel/code/modules/custom_loadout/custom_items.dm
@@ -493,3 +493,19 @@
item_state = "blueberet"
icon = 'icons/obj/custom.dmi'
alternate_worn_icon = 'icons/mob/custom_w.dmi'
+
+/obj/item/clothing/head/flight
+ name = "flight goggles"
+ desc = "Old style flight goggles with a leather cap attached."
+ icon_state = "flight-g"
+ item_state = "flight-g"
+ icon = 'icons/obj/custom.dmi'
+ alternate_worn_icon = 'icons/mob/custom_w.dmi'
+
+/obj/item/clothing/neck/necklace/onion
+ name = "Onion Necklace"
+ desc = "A string of onions sequenced together to form a necklace."
+ icon = 'icons/obj/custom.dmi'
+ icon_state = "onion"
+ item_state = "onion"
+ alternate_worn_icon = 'icons/mob/custom_w.dmi'
diff --git a/modular_citadel/code/modules/events/blob.dm b/modular_citadel/code/modules/events/blob.dm
deleted file mode 100644
index e8e7106f5e..0000000000
--- a/modular_citadel/code/modules/events/blob.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/datum/round_event_control/blob
- earliest_start = 60 MINUTES
diff --git a/modular_citadel/code/modules/events/wizard/magicarp.dm b/modular_citadel/code/modules/events/wizard/magicarp.dm
deleted file mode 100644
index 10d269c698..0000000000
--- a/modular_citadel/code/modules/events/wizard/magicarp.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/mob/living/simple_animal/hostile/carp/ranged
- gold_core_spawnable = NO_SPAWN
diff --git a/modular_citadel/code/modules/jobs/dresscode_values.dm b/modular_citadel/code/modules/jobs/dresscode_values.dm
deleted file mode 100644
index 24cd5c5ac9..0000000000
--- a/modular_citadel/code/modules/jobs/dresscode_values.dm
+++ /dev/null
@@ -1,8 +0,0 @@
-//This file controls whether or not a job complies with dresscodes.
-//If a job complies with dresscodes, loadout items will not be equipped instead of the job's outfit, instead placing the items into the player's backpack.
-
-/datum/job
- var/dresscodecompliant = TRUE
-
-/datum/job/assistant
- dresscodecompliant = FALSE
\ No newline at end of file
diff --git a/modular_citadel/code/modules/jobs/job_types/captain.dm b/modular_citadel/code/modules/jobs/job_types/captain.dm
deleted file mode 100644
index 7135e86507..0000000000
--- a/modular_citadel/code/modules/jobs/job_types/captain.dm
+++ /dev/null
@@ -1,21 +0,0 @@
-/datum/job/captain
- minimal_player_age = 20
- exp_type = EXP_TYPE_COMMAND
-
-/datum/job/hop
- minimal_player_age = 20
- exp_type_department = EXP_TYPE_SERVICE
-
- access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
- ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
- ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
- ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER,
- ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
- ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_SECURITY, ACCESS_SEC_DOORS, ACCESS_COURT, ACCESS_WEAPONS,
- ACCESS_MEDICAL, ACCESS_ENGINE, ACCESS_CHANGE_IDS, ACCESS_AI_UPLOAD, ACCESS_EVA, ACCESS_HEADS,
- ACCESS_ALL_PERSONAL_LOCKERS, ACCESS_MAINT_TUNNELS, ACCESS_BAR, ACCESS_JANITOR, ACCESS_CONSTRUCTION, ACCESS_MORGUE,
- ACCESS_CREMATORIUM, ACCESS_KITCHEN, ACCESS_HYDROPONICS, ACCESS_LAWYER,
- ACCESS_THEATRE, ACCESS_CHAPEL_OFFICE, ACCESS_LIBRARY, ACCESS_RESEARCH, ACCESS_MINING, ACCESS_VAULT, ACCESS_MINING_STATION,
- ACCESS_HOP, ACCESS_RC_ANNOUNCE, ACCESS_KEYCARD_AUTH, ACCESS_GATEWAY, ACCESS_MINERAL_STOREROOM)
-
diff --git a/modular_citadel/code/modules/jobs/job_types/cargo_service.dm b/modular_citadel/code/modules/jobs/job_types/cargo_service.dm
deleted file mode 100644
index 965b554f3c..0000000000
--- a/modular_citadel/code/modules/jobs/job_types/cargo_service.dm
+++ /dev/null
@@ -1,31 +0,0 @@
-/datum/job/bartender
- access = list(ACCESS_HYDROPONICS, ACCESS_BAR, ACCESS_KITCHEN, ACCESS_MORGUE, ACCESS_WEAPONS, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_BAR, ACCESS_MINERAL_STOREROOM)
-
-/datum/job/qm
- department_head = list("Captain")
- supervisors = "the captain"
- req_admin_notify = 1
- minimal_player_age = 10
- exp_requirements = 180
- exp_type_department = EXP_TYPE_SUPPLY
-
- access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE, ACCESS_SEC_DOORS, ACCESS_HEADS)
- minimal_access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_QM, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM, ACCESS_KEYCARD_AUTH, ACCESS_RC_ANNOUNCE, ACCESS_SEC_DOORS, ACCESS_HEADS)
-
-/datum/outfit/job/quartermaster
- id = /obj/item/card/id/silver
- ears = /obj/item/radio/headset/heads/qm
- backpack_contents = list(/obj/item/melee/classic_baton/telescopic=1, /obj/item/modular_computer/tablet/preset/advanced = 1)
-
-/datum/job/cargo_tech
- department_head = list("Quartermaster")
- supervisors = "the quartermaster"
-
- access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
-
-/datum/job/mining
- department_head = list("Quartermaster")
- supervisors = "the quartermaster"
-
- access = list(ACCESS_MAINT_TUNNELS, ACCESS_MAILSORTING, ACCESS_CARGO, ACCESS_CARGO_BOT, ACCESS_MINING, ACCESS_MINING_STATION, ACCESS_MINERAL_STOREROOM)
\ No newline at end of file
diff --git a/modular_citadel/code/modules/jobs/job_types/engineering.dm b/modular_citadel/code/modules/jobs/job_types/engineering.dm
deleted file mode 100644
index 4d6aa4119d..0000000000
--- a/modular_citadel/code/modules/jobs/job_types/engineering.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/datum/job/chief_engineer
- minimal_player_age = 10
-
-/datum/job/engineer
- access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS,
- ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS,
- ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_TCOMSAT, ACCESS_MINERAL_STOREROOM)
-
-/datum/job/atmos
- access = list(ACCESS_ENGINE, ACCESS_ENGINE_EQUIP, ACCESS_TECH_STORAGE, ACCESS_MAINT_TUNNELS,
- ACCESS_EXTERNAL_AIRLOCKS, ACCESS_CONSTRUCTION, ACCESS_ATMOSPHERICS, ACCESS_MINERAL_STOREROOM)
- minimal_access = list(ACCESS_ATMOSPHERICS, ACCESS_MAINT_TUNNELS, ACCESS_EXTERNAL_AIRLOCKS, ACCESS_ENGINE,
- ACCESS_ENGINE_EQUIP, ACCESS_EMERGENCY_STORAGE, ACCESS_CONSTRUCTION, ACCESS_MINERAL_STOREROOM)
diff --git a/modular_citadel/code/modules/jobs/job_types/medical.dm b/modular_citadel/code/modules/jobs/job_types/medical.dm
deleted file mode 100644
index 15841ad9d5..0000000000
--- a/modular_citadel/code/modules/jobs/job_types/medical.dm
+++ /dev/null
@@ -1,8 +0,0 @@
-/datum/job/cmo
- minimal_player_age = 10
-
-/datum/outfit/job/doctor
- backpack_contents = list(/obj/item/storage/hypospraykit/regular)
-
-/datum/outfit/job/chemist
- backpack_contents = list(/obj/item/storage/hypospraykit/regular)
diff --git a/modular_citadel/code/modules/jobs/job_types/science.dm b/modular_citadel/code/modules/jobs/job_types/science.dm
deleted file mode 100644
index 94272d24a6..0000000000
--- a/modular_citadel/code/modules/jobs/job_types/science.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/datum/job/rd
- minimal_player_age = 10
diff --git a/modular_citadel/code/modules/jobs/job_types/security.dm b/modular_citadel/code/modules/jobs/job_types/security.dm
deleted file mode 100644
index de00f2d948..0000000000
--- a/modular_citadel/code/modules/jobs/job_types/security.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/datum/job/hos
- minimal_player_age = 10
-
-/datum/outfit/job/warden
- suit_store = /obj/item/gun/energy/pumpaction/defender
diff --git a/modular_citadel/code/modules/mob/cit_emotes.dm b/modular_citadel/code/modules/mob/cit_emotes.dm
index a34b7b0526..7e7a77538a 100644
--- a/modular_citadel/code/modules/mob/cit_emotes.dm
+++ b/modular_citadel/code/modules/mob/cit_emotes.dm
@@ -213,3 +213,18 @@
user.nextsoundemote = world.time + 7
playsound(user, 'modular_citadel/sound/voice/merp.ogg', 50, 1, -1)
. = ..()
+
+/datum/emote/living/bark
+ key = "bark"
+ key_third_person = "barks"
+ message = "barks!"
+ emote_type = EMOTE_AUDIBLE
+
+/datum/emote/living/bark/run_emote(mob/living/user, params)
+ if(ishuman(user))
+ if(user.nextsoundemote >= world.time)
+ return
+ user.nextsoundemote = world.time + 7
+ var/sound = pick('modular_citadel/sound/voice/bark1.ogg', 'modular_citadel/sound/voice/bark2.ogg')
+ playsound(user, sound, 50, 1, -1)
+ . = ..()
\ No newline at end of file
diff --git a/modular_citadel/code/modules/mob/living/carbon/carbon.dm b/modular_citadel/code/modules/mob/living/carbon/carbon.dm
index 43931db689..4cc8edac1b 100644
--- a/modular_citadel/code/modules/mob/living/carbon/carbon.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/carbon.dm
@@ -18,16 +18,20 @@
return FALSE
return .
-/mob/living/carbon/proc/toggle_combat_mode()
+/mob/living/carbon/proc/toggle_combat_mode(forced)
if(recoveringstam)
return TRUE
+ if(!forced)
+ for(var/datum/status_effect/S in status_effects)
+ if(S.blocks_combatmode)
+ return TRUE
combatmode = !combatmode
if(voremode)
toggle_vore_mode()
if(combatmode)
- playsound_local(src, 'modular_citadel/sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
+ playsound_local(src, 'sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
else
- playsound_local(src, 'modular_citadel/sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
+ playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
if(client)
client.show_popup_menus = !combatmode // So we can right-click for alternate actions and all that other good shit. Also moves examine to shift+rightclick to make it possible to attack while sprinting
if(hud_used && hud_used.static_inventory)
diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human.dm b/modular_citadel/code/modules/mob/living/carbon/human/human.dm
index e0d592827e..e5d386b56b 100644
--- a/modular_citadel/code/modules/mob/living/carbon/human/human.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/human/human.dm
@@ -1,12 +1,3 @@
-/mob/living/carbon/human/species/mammal
- race = /datum/species/mammal
-
-/mob/living/carbon/human/species/insect
- race = /datum/species/insect
-
-/mob/living/carbon/human/species/xeno
- race = /datum/species/xeno
-
/mob/living/proc/resist_embedded()
return
diff --git a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm
index 409864c900..badda6b239 100644
--- a/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm
+++ b/modular_citadel/code/modules/mob/living/carbon/human/human_movement.dm
@@ -24,9 +24,9 @@
sprinting = !sprinting
if(!resting && m_intent == MOVE_INTENT_RUN && canmove)
if(sprinting)
- playsound_local(src, 'modular_citadel/sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
+ playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
else
- playsound_local(src, 'modular_citadel/sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
+ playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
if(hud_used && hud_used.static_inventory)
for(var/obj/screen/sprintbutton/selector in hud_used.static_inventory)
selector.insert_witty_toggle_joke_here(src)
diff --git a/modular_citadel/code/modules/mob/living/living.dm b/modular_citadel/code/modules/mob/living/living.dm
index ac79ea7f25..16bf776171 100644
--- a/modular_citadel/code/modules/mob/living/living.dm
+++ b/modular_citadel/code/modules/mob/living/living.dm
@@ -13,7 +13,7 @@
var/sprint_buffer_max = 42
var/sprint_buffer_regen_ds = 0.3 //Tiles per world.time decisecond
var/sprint_buffer_regen_last = 0 //last world.time this was regen'd for math.
- var/sprint_stamina_cost = 0.55 //stamina loss per tile while insufficient sprint buffer.
+ var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer.
//---End
/mob/living/movement_delay(ignorewalk = 0)
@@ -116,7 +116,7 @@
to_chat(src, "You're too exhausted to keep going... ")
resting = TRUE
if(combatmode)
- toggle_combat_mode()
+ toggle_combat_mode(TRUE)
recoveringstam = TRUE
filters += CIT_FILTER_STAMINACRIT
update_canmove()
diff --git a/modular_citadel/code/modules/mob/living/silicon/ai/vox_sounds.dm b/modular_citadel/code/modules/mob/living/silicon/ai/vox_sounds.dm
deleted file mode 100644
index b1e112aac5..0000000000
--- a/modular_citadel/code/modules/mob/living/silicon/ai/vox_sounds.dm
+++ /dev/null
@@ -1,633 +0,0 @@
-// List is required to compile the resources into the game when it loads.
-// Dynamically loading it has bad results with sounds overtaking each other, even with the wait variable.
-#ifdef AI_VOX
-
-GLOBAL_LIST_INIT(vox_sounds_male, list("," = 'modular_citadel/sound/vox/_comma.ogg',
-"." = 'modular_citadel/sound/vox/_period.ogg',
-"a" = 'modular_citadel/sound/vox/a.ogg',
-"accelerating" = 'modular_citadel/sound/vox/accelerating.ogg',
-"accelerator" = 'modular_citadel/sound/vox/accelerator.ogg',
-"accepted" = 'modular_citadel/sound/vox/accepted.ogg',
-"access" = 'modular_citadel/sound/vox/access.ogg',
-"acknowledge" = 'modular_citadel/sound/vox/acknowledge.ogg',
-"acknowledged" = 'modular_citadel/sound/vox/acknowledged.ogg',
-"acquired" = 'modular_citadel/sound/vox/acquired.ogg',
-"acquisition" = 'modular_citadel/sound/vox/acquisition.ogg',
-"across" = 'modular_citadel/sound/vox/across.ogg',
-"activate" = 'modular_citadel/sound/vox/activate.ogg',
-"activated" = 'modular_citadel/sound/vox/activated.ogg',
-"activity" = 'modular_citadel/sound/vox/activity.ogg',
-"adios" = 'modular_citadel/sound/vox/adios.ogg',
-"administration" = 'modular_citadel/sound/vox/administration.ogg',
-"advanced" = 'modular_citadel/sound/vox/advanced.ogg',
-"after" = 'modular_citadel/sound/vox/after.ogg',
-"agent" = 'modular_citadel/sound/vox/agent.ogg',
-"alarm" = 'modular_citadel/sound/vox/alarm.ogg',
-"alert" = 'modular_citadel/sound/vox/alert.ogg',
-"alien" = 'modular_citadel/sound/vox/alien.ogg',
-"aligned" = 'modular_citadel/sound/vox/aligned.ogg',
-"all" = 'modular_citadel/sound/vox/all.ogg',
-"alpha" = 'modular_citadel/sound/vox/alpha.ogg',
-"am" = 'modular_citadel/sound/vox/am.ogg',
-"amigo" = 'modular_citadel/sound/vox/amigo.ogg',
-"ammunition" = 'modular_citadel/sound/vox/ammunition.ogg',
-"an" = 'modular_citadel/sound/vox/an.ogg',
-"and" = 'modular_citadel/sound/vox/and.ogg',
-"announcement" = 'modular_citadel/sound/vox/announcement.ogg',
-"anomalous" = 'modular_citadel/sound/vox/anomalous.ogg',
-"antenna" = 'modular_citadel/sound/vox/antenna.ogg',
-"any" = 'modular_citadel/sound/vox/any.ogg',
-"apprehend" = 'modular_citadel/sound/vox/apprehend.ogg',
-"approach" = 'modular_citadel/sound/vox/approach.ogg',
-"are" = 'modular_citadel/sound/vox/are.ogg',
-"area" = 'modular_citadel/sound/vox/area.ogg',
-"arm" = 'modular_citadel/sound/vox/arm.ogg',
-"armed" = 'modular_citadel/sound/vox/armed.ogg',
-"armor" = 'modular_citadel/sound/vox/armor.ogg',
-"armory" = 'modular_citadel/sound/vox/armory.ogg',
-"arrest" = 'modular_citadel/sound/vox/arrest.ogg',
-"ass" = 'modular_citadel/sound/vox/ass.ogg',
-"at" = 'modular_citadel/sound/vox/at.ogg',
-"atomic" = 'modular_citadel/sound/vox/atomic.ogg',
-"attention" = 'modular_citadel/sound/vox/attention.ogg',
-"authorize" = 'modular_citadel/sound/vox/authorize.ogg',
-"authorized" = 'modular_citadel/sound/vox/authorized.ogg',
-"automatic" = 'modular_citadel/sound/vox/automatic.ogg',
-"away" = 'modular_citadel/sound/vox/away.ogg',
-"b" = 'modular_citadel/sound/vox/b.ogg',
-"back" = 'modular_citadel/sound/vox/back.ogg',
-"backman" = 'modular_citadel/sound/vox/backman.ogg',
-"bad" = 'modular_citadel/sound/vox/bad.ogg',
-"bag" = 'modular_citadel/sound/vox/bag.ogg',
-"bailey" = 'modular_citadel/sound/vox/bailey.ogg',
-"barracks" = 'modular_citadel/sound/vox/barracks.ogg',
-"base" = 'modular_citadel/sound/vox/base.ogg',
-"bay" = 'modular_citadel/sound/vox/bay.ogg',
-"be" = 'modular_citadel/sound/vox/be.ogg',
-"been" = 'modular_citadel/sound/vox/been.ogg',
-"before" = 'modular_citadel/sound/vox/before.ogg',
-"beyond" = 'modular_citadel/sound/vox/beyond.ogg',
-"biohazard" = 'modular_citadel/sound/vox/biohazard.ogg',
-"biological" = 'modular_citadel/sound/vox/biological.ogg',
-"birdwell" = 'modular_citadel/sound/vox/birdwell.ogg',
-"bizwarn" = 'modular_citadel/sound/vox/bizwarn.ogg',
-"black" = 'modular_citadel/sound/vox/black.ogg',
-"blast" = 'modular_citadel/sound/vox/blast.ogg',
-"blocked" = 'modular_citadel/sound/vox/blocked.ogg',
-"bloop" = 'modular_citadel/sound/vox/bloop.ogg',
-"blue" = 'modular_citadel/sound/vox/blue.ogg',
-"bottom" = 'modular_citadel/sound/vox/bottom.ogg',
-"bravo" = 'modular_citadel/sound/vox/bravo.ogg',
-"breach" = 'modular_citadel/sound/vox/breach.ogg',
-"breached" = 'modular_citadel/sound/vox/breached.ogg',
-"break" = 'modular_citadel/sound/vox/break.ogg',
-"bridge" = 'modular_citadel/sound/vox/bridge.ogg',
-"bust" = 'modular_citadel/sound/vox/bust.ogg',
-"but" = 'modular_citadel/sound/vox/but.ogg',
-"button" = 'modular_citadel/sound/vox/button.ogg',
-"buzwarn" = 'modular_citadel/sound/vox/buzwarn.ogg',
-"bypass" = 'modular_citadel/sound/vox/bypass.ogg',
-"c" = 'modular_citadel/sound/vox/c.ogg',
-"cable" = 'modular_citadel/sound/vox/cable.ogg',
-"call" = 'modular_citadel/sound/vox/call.ogg',
-"called" = 'modular_citadel/sound/vox/called.ogg',
-"canal" = 'modular_citadel/sound/vox/canal.ogg',
-"cap" = 'modular_citadel/sound/vox/cap.ogg',
-"captain" = 'modular_citadel/sound/vox/captain.ogg',
-"capture" = 'modular_citadel/sound/vox/capture.ogg',
-"captured" = 'modular_citadel/sound/vox/captured.ogg',
-"ceiling" = 'modular_citadel/sound/vox/ceiling.ogg',
-"celsius" = 'modular_citadel/sound/vox/celsius.ogg',
-"center" = 'modular_citadel/sound/vox/center.ogg',
-"centi" = 'modular_citadel/sound/vox/centi.ogg',
-"central" = 'modular_citadel/sound/vox/central.ogg',
-"chamber" = 'modular_citadel/sound/vox/chamber.ogg',
-"charlie" = 'modular_citadel/sound/vox/charlie.ogg',
-"check" = 'modular_citadel/sound/vox/check.ogg',
-"checkpoint" = 'modular_citadel/sound/vox/checkpoint.ogg',
-"chemical" = 'modular_citadel/sound/vox/chemical.ogg',
-"cleanup" = 'modular_citadel/sound/vox/cleanup.ogg',
-"clear" = 'modular_citadel/sound/vox/clear.ogg',
-"clearance" = 'modular_citadel/sound/vox/clearance.ogg',
-"close" = 'modular_citadel/sound/vox/close.ogg',
-"clown" = 'modular_citadel/sound/vox/clown.ogg',
-"code" = 'modular_citadel/sound/vox/code.ogg',
-"coded" = 'modular_citadel/sound/vox/coded.ogg',
-"collider" = 'modular_citadel/sound/vox/collider.ogg',
-"command" = 'modular_citadel/sound/vox/command.ogg',
-"communication" = 'modular_citadel/sound/vox/communication.ogg',
-"complex" = 'modular_citadel/sound/vox/complex.ogg',
-"computer" = 'modular_citadel/sound/vox/computer.ogg',
-"condition" = 'modular_citadel/sound/vox/condition.ogg',
-"containment" = 'modular_citadel/sound/vox/containment.ogg',
-"contamination" = 'modular_citadel/sound/vox/contamination.ogg',
-"control" = 'modular_citadel/sound/vox/control.ogg',
-"coolant" = 'modular_citadel/sound/vox/coolant.ogg',
-"coomer" = 'modular_citadel/sound/vox/coomer.ogg',
-"core" = 'modular_citadel/sound/vox/core.ogg',
-"correct" = 'modular_citadel/sound/vox/correct.ogg',
-"corridor" = 'modular_citadel/sound/vox/corridor.ogg',
-"crew" = 'modular_citadel/sound/vox/crew.ogg',
-"cross" = 'modular_citadel/sound/vox/cross.ogg',
-"cryogenic" = 'modular_citadel/sound/vox/cryogenic.ogg',
-"d" = 'modular_citadel/sound/vox/d.ogg',
-"dadeda" = 'modular_citadel/sound/vox/dadeda.ogg',
-"damage" = 'modular_citadel/sound/vox/damage.ogg',
-"damaged" = 'modular_citadel/sound/vox/damaged.ogg',
-"danger" = 'modular_citadel/sound/vox/danger.ogg',
-"day" = 'modular_citadel/sound/vox/day.ogg',
-"deactivated" = 'modular_citadel/sound/vox/deactivated.ogg',
-"decompression" = 'modular_citadel/sound/vox/decompression.ogg',
-"decontamination" = 'modular_citadel/sound/vox/decontamination.ogg',
-"deeoo" = 'modular_citadel/sound/vox/deeoo.ogg',
-"defense" = 'modular_citadel/sound/vox/defense.ogg',
-"degrees" = 'modular_citadel/sound/vox/degrees.ogg',
-"delta" = 'modular_citadel/sound/vox/delta.ogg',
-"denied" = 'modular_citadel/sound/vox/denied.ogg',
-"deploy" = 'modular_citadel/sound/vox/deploy.ogg',
-"deployed" = 'modular_citadel/sound/vox/deployed.ogg',
-"destroy" = 'modular_citadel/sound/vox/destroy.ogg',
-"destroyed" = 'modular_citadel/sound/vox/destroyed.ogg',
-"detain" = 'modular_citadel/sound/vox/detain.ogg',
-"detected" = 'modular_citadel/sound/vox/detected.ogg',
-"detonation" = 'modular_citadel/sound/vox/detonation.ogg',
-"device" = 'modular_citadel/sound/vox/device.ogg',
-"did" = 'modular_citadel/sound/vox/did.ogg',
-"die" = 'modular_citadel/sound/vox/die.ogg',
-"dimensional" = 'modular_citadel/sound/vox/dimensional.ogg',
-"dirt" = 'modular_citadel/sound/vox/dirt.ogg',
-"disengaged" = 'modular_citadel/sound/vox/disengaged.ogg',
-"dish" = 'modular_citadel/sound/vox/dish.ogg',
-"disposal" = 'modular_citadel/sound/vox/disposal.ogg',
-"distance" = 'modular_citadel/sound/vox/distance.ogg',
-"distortion" = 'modular_citadel/sound/vox/distortion.ogg',
-"do" = 'modular_citadel/sound/vox/do.ogg',
-"doctor" = 'modular_citadel/sound/vox/doctor.ogg',
-"doop" = 'modular_citadel/sound/vox/doop.ogg',
-"door" = 'modular_citadel/sound/vox/door.ogg',
-"down" = 'modular_citadel/sound/vox/down.ogg',
-"dual" = 'modular_citadel/sound/vox/dual.ogg',
-"duct" = 'modular_citadel/sound/vox/duct.ogg',
-"e" = 'modular_citadel/sound/vox/e.ogg',
-"east" = 'modular_citadel/sound/vox/east.ogg',
-"echo" = 'modular_citadel/sound/vox/echo.ogg',
-"ed" = 'modular_citadel/sound/vox/ed.ogg',
-"effect" = 'modular_citadel/sound/vox/effect.ogg',
-"egress" = 'modular_citadel/sound/vox/egress.ogg',
-"eight" = 'modular_citadel/sound/vox/eight.ogg',
-"eighteen" = 'modular_citadel/sound/vox/eighteen.ogg',
-"eighty" = 'modular_citadel/sound/vox/eighty.ogg',
-"electric" = 'modular_citadel/sound/vox/electric.ogg',
-"electromagnetic" = 'modular_citadel/sound/vox/electromagnetic.ogg',
-"elevator" = 'modular_citadel/sound/vox/elevator.ogg',
-"eleven" = 'modular_citadel/sound/vox/eleven.ogg',
-"eliminate" = 'modular_citadel/sound/vox/eliminate.ogg',
-"emergency" = 'modular_citadel/sound/vox/emergency.ogg',
-"enemy" = 'modular_citadel/sound/vox/enemy.ogg',
-"energy" = 'modular_citadel/sound/vox/energy.ogg',
-"engage" = 'modular_citadel/sound/vox/engage.ogg',
-"engaged" = 'modular_citadel/sound/vox/engaged.ogg',
-"engine" = 'modular_citadel/sound/vox/engine.ogg',
-"enter" = 'modular_citadel/sound/vox/enter.ogg',
-"entry" = 'modular_citadel/sound/vox/entry.ogg',
-"environment" = 'modular_citadel/sound/vox/environment.ogg',
-"error" = 'modular_citadel/sound/vox/error.ogg',
-"escape" = 'modular_citadel/sound/vox/escape.ogg',
-"evacuate" = 'modular_citadel/sound/vox/evacuate.ogg',
-"exchange" = 'modular_citadel/sound/vox/exchange.ogg',
-"exit" = 'modular_citadel/sound/vox/exit.ogg',
-"expect" = 'modular_citadel/sound/vox/expect.ogg',
-"experiment" = 'modular_citadel/sound/vox/experiment.ogg',
-"experimental" = 'modular_citadel/sound/vox/experimental.ogg',
-"explode" = 'modular_citadel/sound/vox/explode.ogg',
-"explosion" = 'modular_citadel/sound/vox/explosion.ogg',
-"exposure" = 'modular_citadel/sound/vox/exposure.ogg',
-"exterminate" = 'modular_citadel/sound/vox/exterminate.ogg',
-"extinguish" = 'modular_citadel/sound/vox/extinguish.ogg',
-"extinguisher" = 'modular_citadel/sound/vox/extinguisher.ogg',
-"extreme" = 'modular_citadel/sound/vox/extreme.ogg',
-"f" = 'modular_citadel/sound/vox/f.ogg',
-"face" = 'modular_citadel/sound/vox/face.ogg',
-"facility" = 'modular_citadel/sound/vox/facility.ogg',
-"fahrenheit" = 'modular_citadel/sound/vox/fahrenheit.ogg',
-"failed" = 'modular_citadel/sound/vox/failed.ogg',
-"failure" = 'modular_citadel/sound/vox/failure.ogg',
-"farthest" = 'modular_citadel/sound/vox/farthest.ogg',
-"fast" = 'modular_citadel/sound/vox/fast.ogg',
-"feet" = 'modular_citadel/sound/vox/feet.ogg',
-"field" = 'modular_citadel/sound/vox/field.ogg',
-"fifteen" = 'modular_citadel/sound/vox/fifteen.ogg',
-"fifth" = 'modular_citadel/sound/vox/fifth.ogg',
-"fifty" = 'modular_citadel/sound/vox/fifty.ogg',
-"final" = 'modular_citadel/sound/vox/final.ogg',
-"fine" = 'modular_citadel/sound/vox/fine.ogg',
-"fire" = 'modular_citadel/sound/vox/fire.ogg',
-"first" = 'modular_citadel/sound/vox/first.ogg',
-"five" = 'modular_citadel/sound/vox/five.ogg',
-"flag" = 'modular_citadel/sound/vox/flag.ogg',
-"flooding" = 'modular_citadel/sound/vox/flooding.ogg',
-"floor" = 'modular_citadel/sound/vox/floor.ogg',
-"fool" = 'modular_citadel/sound/vox/fool.ogg',
-"for" = 'modular_citadel/sound/vox/for.ogg',
-"forbidden" = 'modular_citadel/sound/vox/forbidden.ogg',
-"force" = 'modular_citadel/sound/vox/force.ogg',
-"forms" = 'modular_citadel/sound/vox/forms.ogg',
-"found" = 'modular_citadel/sound/vox/found.ogg',
-"four" = 'modular_citadel/sound/vox/four.ogg',
-"fourteen" = 'modular_citadel/sound/vox/fourteen.ogg',
-"fourth" = 'modular_citadel/sound/vox/fourth.ogg',
-"fourty" = 'modular_citadel/sound/vox/fourty.ogg',
-"foxtrot" = 'modular_citadel/sound/vox/foxtrot.ogg',
-"freeman" = 'modular_citadel/sound/vox/freeman.ogg',
-"freezer" = 'modular_citadel/sound/vox/freezer.ogg',
-"from" = 'modular_citadel/sound/vox/from.ogg',
-"front" = 'modular_citadel/sound/vox/front.ogg',
-"fuel" = 'modular_citadel/sound/vox/fuel.ogg',
-"g" = 'modular_citadel/sound/vox/g.ogg',
-"gay" = 'modular_citadel/sound/vox/gay.ogg',
-"get" = 'modular_citadel/sound/vox/get.ogg',
-"go" = 'modular_citadel/sound/vox/go.ogg',
-"going" = 'modular_citadel/sound/vox/going.ogg',
-"good" = 'modular_citadel/sound/vox/good.ogg',
-"goodbye" = 'modular_citadel/sound/vox/goodbye.ogg',
-"gordon" = 'modular_citadel/sound/vox/gordon.ogg',
-"got" = 'modular_citadel/sound/vox/got.ogg',
-"government" = 'modular_citadel/sound/vox/government.ogg',
-"granted" = 'modular_citadel/sound/vox/granted.ogg',
-"great" = 'modular_citadel/sound/vox/great.ogg',
-"green" = 'modular_citadel/sound/vox/green.ogg',
-"grenade" = 'modular_citadel/sound/vox/grenade.ogg',
-"guard" = 'modular_citadel/sound/vox/guard.ogg',
-"gulf" = 'modular_citadel/sound/vox/gulf.ogg',
-"gun" = 'modular_citadel/sound/vox/gun.ogg',
-"guthrie" = 'modular_citadel/sound/vox/guthrie.ogg',
-"handling" = 'modular_citadel/sound/vox/handling.ogg',
-"hangar" = 'modular_citadel/sound/vox/hangar.ogg',
-"has" = 'modular_citadel/sound/vox/has.ogg',
-"have" = 'modular_citadel/sound/vox/have.ogg',
-"hazard" = 'modular_citadel/sound/vox/hazard.ogg',
-"head" = 'modular_citadel/sound/vox/head.ogg',
-"health" = 'modular_citadel/sound/vox/health.ogg',
-"heat" = 'modular_citadel/sound/vox/heat.ogg',
-"helicopter" = 'modular_citadel/sound/vox/helicopter.ogg',
-"helium" = 'modular_citadel/sound/vox/helium.ogg',
-"hello" = 'modular_citadel/sound/vox/hello.ogg',
-"help" = 'modular_citadel/sound/vox/help.ogg',
-"here" = 'modular_citadel/sound/vox/here.ogg',
-"hide" = 'modular_citadel/sound/vox/hide.ogg',
-"high" = 'modular_citadel/sound/vox/high.ogg',
-"highest" = 'modular_citadel/sound/vox/highest.ogg',
-"hit" = 'modular_citadel/sound/vox/hit.ogg',
-"holds" = 'modular_citadel/sound/vox/holds.ogg',
-"hole" = 'modular_citadel/sound/vox/hole.ogg',
-"hostile" = 'modular_citadel/sound/vox/hostile.ogg',
-"hot" = 'modular_citadel/sound/vox/hot.ogg',
-"hotel" = 'modular_citadel/sound/vox/hotel.ogg',
-"hour" = 'modular_citadel/sound/vox/hour.ogg',
-"hours" = 'modular_citadel/sound/vox/hours.ogg',
-"hundred" = 'modular_citadel/sound/vox/hundred.ogg',
-"hydro" = 'modular_citadel/sound/vox/hydro.ogg',
-"i" = 'modular_citadel/sound/vox/i.ogg',
-"idiot" = 'modular_citadel/sound/vox/idiot.ogg',
-"illegal" = 'modular_citadel/sound/vox/illegal.ogg',
-"immediate" = 'modular_citadel/sound/vox/immediate.ogg',
-"immediately" = 'modular_citadel/sound/vox/immediately.ogg',
-"in" = 'modular_citadel/sound/vox/in.ogg',
-"inches" = 'modular_citadel/sound/vox/inches.ogg',
-"india" = 'modular_citadel/sound/vox/india.ogg',
-"ing" = 'modular_citadel/sound/vox/ing.ogg',
-"inoperative" = 'modular_citadel/sound/vox/inoperative.ogg',
-"inside" = 'modular_citadel/sound/vox/inside.ogg',
-"inspection" = 'modular_citadel/sound/vox/inspection.ogg',
-"inspector" = 'modular_citadel/sound/vox/inspector.ogg',
-"interchange" = 'modular_citadel/sound/vox/interchange.ogg',
-"intruder" = 'modular_citadel/sound/vox/intruder.ogg',
-"invallid" = 'modular_citadel/sound/vox/invallid.ogg',
-"invasion" = 'modular_citadel/sound/vox/invasion.ogg',
-"is" = 'modular_citadel/sound/vox/is.ogg',
-"it" = 'modular_citadel/sound/vox/it.ogg',
-"johnson" = 'modular_citadel/sound/vox/johnson.ogg',
-"juliet" = 'modular_citadel/sound/vox/juliet.ogg',
-"key" = 'modular_citadel/sound/vox/key.ogg',
-"kill" = 'modular_citadel/sound/vox/kill.ogg',
-"kilo" = 'modular_citadel/sound/vox/kilo.ogg',
-"kit" = 'modular_citadel/sound/vox/kit.ogg',
-"lab" = 'modular_citadel/sound/vox/lab.ogg',
-"lambda" = 'modular_citadel/sound/vox/lambda.ogg',
-"laser" = 'modular_citadel/sound/vox/laser.ogg',
-"last" = 'modular_citadel/sound/vox/last.ogg',
-"launch" = 'modular_citadel/sound/vox/launch.ogg',
-"leak" = 'modular_citadel/sound/vox/leak.ogg',
-"leave" = 'modular_citadel/sound/vox/leave.ogg',
-"left" = 'modular_citadel/sound/vox/left.ogg',
-"legal" = 'modular_citadel/sound/vox/legal.ogg',
-"level" = 'modular_citadel/sound/vox/level.ogg',
-"lever" = 'modular_citadel/sound/vox/lever.ogg',
-"lie" = 'modular_citadel/sound/vox/lie.ogg',
-"lieutenant" = 'modular_citadel/sound/vox/lieutenant.ogg',
-"life" = 'modular_citadel/sound/vox/life.ogg',
-"light" = 'modular_citadel/sound/vox/light.ogg',
-"lima" = 'modular_citadel/sound/vox/lima.ogg',
-"liquid" = 'modular_citadel/sound/vox/liquid.ogg',
-"loading" = 'modular_citadel/sound/vox/loading.ogg',
-"locate" = 'modular_citadel/sound/vox/locate.ogg',
-"located" = 'modular_citadel/sound/vox/located.ogg',
-"location" = 'modular_citadel/sound/vox/location.ogg',
-"lock" = 'modular_citadel/sound/vox/lock.ogg',
-"locked" = 'modular_citadel/sound/vox/locked.ogg',
-"locker" = 'modular_citadel/sound/vox/locker.ogg',
-"lockout" = 'modular_citadel/sound/vox/lockout.ogg',
-"lower" = 'modular_citadel/sound/vox/lower.ogg',
-"lowest" = 'modular_citadel/sound/vox/lowest.ogg',
-"magnetic" = 'modular_citadel/sound/vox/magnetic.ogg',
-"main" = 'modular_citadel/sound/vox/main.ogg',
-"maintenance" = 'modular_citadel/sound/vox/maintenance.ogg',
-"malfunction" = 'modular_citadel/sound/vox/malfunction.ogg',
-"man" = 'modular_citadel/sound/vox/man.ogg',
-"mass" = 'modular_citadel/sound/vox/mass.ogg',
-"materials" = 'modular_citadel/sound/vox/materials.ogg',
-"maximum" = 'modular_citadel/sound/vox/maximum.ogg',
-"may" = 'modular_citadel/sound/vox/may.ogg',
-"med" = 'modular_citadel/sound/vox/med.ogg',
-"medical" = 'modular_citadel/sound/vox/medical.ogg',
-"men" = 'modular_citadel/sound/vox/men.ogg',
-"mercy" = 'modular_citadel/sound/vox/mercy.ogg',
-"mesa" = 'modular_citadel/sound/vox/mesa.ogg',
-"message" = 'modular_citadel/sound/vox/message.ogg',
-"meter" = 'modular_citadel/sound/vox/meter.ogg',
-"micro" = 'modular_citadel/sound/vox/micro.ogg',
-"middle" = 'modular_citadel/sound/vox/middle.ogg',
-"mike" = 'modular_citadel/sound/vox/mike.ogg',
-"miles" = 'modular_citadel/sound/vox/miles.ogg',
-"military" = 'modular_citadel/sound/vox/military.ogg',
-"milli" = 'modular_citadel/sound/vox/milli.ogg',
-"million" = 'modular_citadel/sound/vox/million.ogg',
-"minefield" = 'modular_citadel/sound/vox/minefield.ogg',
-"minimum" = 'modular_citadel/sound/vox/minimum.ogg',
-"minutes" = 'modular_citadel/sound/vox/minutes.ogg',
-"mister" = 'modular_citadel/sound/vox/mister.ogg',
-"mode" = 'modular_citadel/sound/vox/mode.ogg',
-"motor" = 'modular_citadel/sound/vox/motor.ogg',
-"motorpool" = 'modular_citadel/sound/vox/motorpool.ogg',
-"move" = 'modular_citadel/sound/vox/move.ogg',
-"must" = 'modular_citadel/sound/vox/must.ogg',
-"nearest" = 'modular_citadel/sound/vox/nearest.ogg',
-"nice" = 'modular_citadel/sound/vox/nice.ogg',
-"nine" = 'modular_citadel/sound/vox/nine.ogg',
-"nineteen" = 'modular_citadel/sound/vox/nineteen.ogg',
-"ninety" = 'modular_citadel/sound/vox/ninety.ogg',
-"no" = 'modular_citadel/sound/vox/no.ogg',
-"nominal" = 'modular_citadel/sound/vox/nominal.ogg',
-"north" = 'modular_citadel/sound/vox/north.ogg',
-"not" = 'modular_citadel/sound/vox/not.ogg',
-"november" = 'modular_citadel/sound/vox/november.ogg',
-"now" = 'modular_citadel/sound/vox/now.ogg',
-"number" = 'modular_citadel/sound/vox/number.ogg',
-"objective" = 'modular_citadel/sound/vox/objective.ogg',
-"observation" = 'modular_citadel/sound/vox/observation.ogg',
-"of" = 'modular_citadel/sound/vox/of.ogg',
-"officer" = 'modular_citadel/sound/vox/officer.ogg',
-"ok" = 'modular_citadel/sound/vox/ok.ogg',
-"on" = 'modular_citadel/sound/vox/on.ogg',
-"one" = 'modular_citadel/sound/vox/one.ogg',
-"open" = 'modular_citadel/sound/vox/open.ogg',
-"operating" = 'modular_citadel/sound/vox/operating.ogg',
-"operations" = 'modular_citadel/sound/vox/operations.ogg',
-"operative" = 'modular_citadel/sound/vox/operative.ogg',
-"option" = 'modular_citadel/sound/vox/option.ogg',
-"order" = 'modular_citadel/sound/vox/order.ogg',
-"organic" = 'modular_citadel/sound/vox/organic.ogg',
-"oscar" = 'modular_citadel/sound/vox/oscar.ogg',
-"out" = 'modular_citadel/sound/vox/out.ogg',
-"outside" = 'modular_citadel/sound/vox/outside.ogg',
-"over" = 'modular_citadel/sound/vox/over.ogg',
-"overload" = 'modular_citadel/sound/vox/overload.ogg',
-"override" = 'modular_citadel/sound/vox/override.ogg',
-"pacify" = 'modular_citadel/sound/vox/pacify.ogg',
-"pain" = 'modular_citadel/sound/vox/pain.ogg',
-"pal" = 'modular_citadel/sound/vox/pal.ogg',
-"panel" = 'modular_citadel/sound/vox/panel.ogg',
-"percent" = 'modular_citadel/sound/vox/percent.ogg',
-"perimeter" = 'modular_citadel/sound/vox/perimeter.ogg',
-"permitted" = 'modular_citadel/sound/vox/permitted.ogg',
-"personnel" = 'modular_citadel/sound/vox/personnel.ogg',
-"pipe" = 'modular_citadel/sound/vox/pipe.ogg',
-"plant" = 'modular_citadel/sound/vox/plant.ogg',
-"platform" = 'modular_citadel/sound/vox/platform.ogg',
-"please" = 'modular_citadel/sound/vox/please.ogg',
-"point" = 'modular_citadel/sound/vox/point.ogg',
-"portal" = 'modular_citadel/sound/vox/portal.ogg',
-"power" = 'modular_citadel/sound/vox/power.ogg',
-"presence" = 'modular_citadel/sound/vox/presence.ogg',
-"press" = 'modular_citadel/sound/vox/press.ogg',
-"primary" = 'modular_citadel/sound/vox/primary.ogg',
-"proceed" = 'modular_citadel/sound/vox/proceed.ogg',
-"processing" = 'modular_citadel/sound/vox/processing.ogg',
-"progress" = 'modular_citadel/sound/vox/progress.ogg',
-"proper" = 'modular_citadel/sound/vox/proper.ogg',
-"propulsion" = 'modular_citadel/sound/vox/propulsion.ogg',
-"prosecute" = 'modular_citadel/sound/vox/prosecute.ogg',
-"protective" = 'modular_citadel/sound/vox/protective.ogg',
-"push" = 'modular_citadel/sound/vox/push.ogg',
-"quantum" = 'modular_citadel/sound/vox/quantum.ogg',
-"quebec" = 'modular_citadel/sound/vox/quebec.ogg',
-"question" = 'modular_citadel/sound/vox/question.ogg',
-"questioning" = 'modular_citadel/sound/vox/questioning.ogg',
-"quick" = 'modular_citadel/sound/vox/quick.ogg',
-"quit" = 'modular_citadel/sound/vox/quit.ogg',
-"radiation" = 'modular_citadel/sound/vox/radiation.ogg',
-"radioactive" = 'modular_citadel/sound/vox/radioactive.ogg',
-"rads" = 'modular_citadel/sound/vox/rads.ogg',
-"rapid" = 'modular_citadel/sound/vox/rapid.ogg',
-"reach" = 'modular_citadel/sound/vox/reach.ogg',
-"reached" = 'modular_citadel/sound/vox/reached.ogg',
-"reactor" = 'modular_citadel/sound/vox/reactor.ogg',
-"red" = 'modular_citadel/sound/vox/red.ogg',
-"relay" = 'modular_citadel/sound/vox/relay.ogg',
-"released" = 'modular_citadel/sound/vox/released.ogg',
-"remaining" = 'modular_citadel/sound/vox/remaining.ogg',
-"renegade" = 'modular_citadel/sound/vox/renegade.ogg',
-"repair" = 'modular_citadel/sound/vox/repair.ogg',
-"report" = 'modular_citadel/sound/vox/report.ogg',
-"reports" = 'modular_citadel/sound/vox/reports.ogg',
-"required" = 'modular_citadel/sound/vox/required.ogg',
-"research" = 'modular_citadel/sound/vox/research.ogg',
-"reset" = 'modular_citadel/sound/vox/reset.ogg',
-"resevoir" = 'modular_citadel/sound/vox/resevoir.ogg',
-"resistance" = 'modular_citadel/sound/vox/resistance.ogg',
-"returned" = 'modular_citadel/sound/vox/returned.ogg',
-"right" = 'modular_citadel/sound/vox/right.ogg',
-"rocket" = 'modular_citadel/sound/vox/rocket.ogg',
-"roger" = 'modular_citadel/sound/vox/roger.ogg',
-"romeo" = 'modular_citadel/sound/vox/romeo.ogg',
-"room" = 'modular_citadel/sound/vox/room.ogg',
-"round" = 'modular_citadel/sound/vox/round.ogg',
-"run" = 'modular_citadel/sound/vox/run.ogg',
-"safe" = 'modular_citadel/sound/vox/safe.ogg',
-"safety" = 'modular_citadel/sound/vox/safety.ogg',
-"sargeant" = 'modular_citadel/sound/vox/sargeant.ogg',
-"satellite" = 'modular_citadel/sound/vox/satellite.ogg',
-"save" = 'modular_citadel/sound/vox/save.ogg',
-"science" = 'modular_citadel/sound/vox/science.ogg',
-"scores" = 'modular_citadel/sound/vox/scores.ogg',
-"scream" = 'modular_citadel/sound/vox/scream.ogg',
-"screen" = 'modular_citadel/sound/vox/screen.ogg',
-"search" = 'modular_citadel/sound/vox/search.ogg',
-"second" = 'modular_citadel/sound/vox/second.ogg',
-"secondary" = 'modular_citadel/sound/vox/secondary.ogg',
-"seconds" = 'modular_citadel/sound/vox/seconds.ogg',
-"sector" = 'modular_citadel/sound/vox/sector.ogg',
-"secure" = 'modular_citadel/sound/vox/secure.ogg',
-"secured" = 'modular_citadel/sound/vox/secured.ogg',
-"security" = 'modular_citadel/sound/vox/security.ogg',
-"select" = 'modular_citadel/sound/vox/select.ogg',
-"selected" = 'modular_citadel/sound/vox/selected.ogg',
-"service" = 'modular_citadel/sound/vox/service.ogg',
-"seven" = 'modular_citadel/sound/vox/seven.ogg',
-"seventeen" = 'modular_citadel/sound/vox/seventeen.ogg',
-"seventy" = 'modular_citadel/sound/vox/seventy.ogg',
-"severe" = 'modular_citadel/sound/vox/severe.ogg',
-"sewage" = 'modular_citadel/sound/vox/sewage.ogg',
-"sewer" = 'modular_citadel/sound/vox/sewer.ogg',
-"shield" = 'modular_citadel/sound/vox/shield.ogg',
-"shipment" = 'modular_citadel/sound/vox/shipment.ogg',
-"shock" = 'modular_citadel/sound/vox/shock.ogg',
-"shoot" = 'modular_citadel/sound/vox/shoot.ogg',
-"shower" = 'modular_citadel/sound/vox/shower.ogg',
-"shut" = 'modular_citadel/sound/vox/shut.ogg',
-"side" = 'modular_citadel/sound/vox/side.ogg',
-"sierra" = 'modular_citadel/sound/vox/sierra.ogg',
-"sight" = 'modular_citadel/sound/vox/sight.ogg',
-"silo" = 'modular_citadel/sound/vox/silo.ogg',
-"six" = 'modular_citadel/sound/vox/six.ogg',
-"sixteen" = 'modular_citadel/sound/vox/sixteen.ogg',
-"sixty" = 'modular_citadel/sound/vox/sixty.ogg',
-"slime" = 'modular_citadel/sound/vox/slime.ogg',
-"slow" = 'modular_citadel/sound/vox/slow.ogg',
-"soldier" = 'modular_citadel/sound/vox/soldier.ogg',
-"some" = 'modular_citadel/sound/vox/some.ogg',
-"someone" = 'modular_citadel/sound/vox/someone.ogg',
-"something" = 'modular_citadel/sound/vox/something.ogg',
-"son" = 'modular_citadel/sound/vox/son.ogg',
-"sorry" = 'modular_citadel/sound/vox/sorry.ogg',
-"south" = 'modular_citadel/sound/vox/south.ogg',
-"squad" = 'modular_citadel/sound/vox/squad.ogg',
-"square" = 'modular_citadel/sound/vox/square.ogg',
-"stairway" = 'modular_citadel/sound/vox/stairway.ogg',
-"status" = 'modular_citadel/sound/vox/status.ogg',
-"sterile" = 'modular_citadel/sound/vox/sterile.ogg',
-"sterilization" = 'modular_citadel/sound/vox/sterilization.ogg',
-"stolen" = 'modular_citadel/sound/vox/stolen.ogg',
-"storage" = 'modular_citadel/sound/vox/storage.ogg',
-"sub" = 'modular_citadel/sound/vox/sub.ogg',
-"subsurface" = 'modular_citadel/sound/vox/subsurface.ogg',
-"sudden" = 'modular_citadel/sound/vox/sudden.ogg',
-"suit" = 'modular_citadel/sound/vox/suit.ogg',
-"superconducting" = 'modular_citadel/sound/vox/superconducting.ogg',
-"supercooled" = 'modular_citadel/sound/vox/supercooled.ogg',
-"supply" = 'modular_citadel/sound/vox/supply.ogg',
-"surface" = 'modular_citadel/sound/vox/surface.ogg',
-"surrender" = 'modular_citadel/sound/vox/surrender.ogg',
-"surround" = 'modular_citadel/sound/vox/surround.ogg',
-"surrounded" = 'modular_citadel/sound/vox/surrounded.ogg',
-"switch" = 'modular_citadel/sound/vox/switch.ogg',
-"system" = 'modular_citadel/sound/vox/system.ogg',
-"systems" = 'modular_citadel/sound/vox/systems.ogg',
-"tactical" = 'modular_citadel/sound/vox/tactical.ogg',
-"take" = 'modular_citadel/sound/vox/take.ogg',
-"talk" = 'modular_citadel/sound/vox/talk.ogg',
-"tango" = 'modular_citadel/sound/vox/tango.ogg',
-"tank" = 'modular_citadel/sound/vox/tank.ogg',
-"target" = 'modular_citadel/sound/vox/target.ogg',
-"team" = 'modular_citadel/sound/vox/team.ogg',
-"temperature" = 'modular_citadel/sound/vox/temperature.ogg',
-"temporal" = 'modular_citadel/sound/vox/temporal.ogg',
-"ten" = 'modular_citadel/sound/vox/ten.ogg',
-"terminal" = 'modular_citadel/sound/vox/terminal.ogg',
-"terminated" = 'modular_citadel/sound/vox/terminated.ogg',
-"termination" = 'modular_citadel/sound/vox/termination.ogg',
-"test" = 'modular_citadel/sound/vox/test.ogg',
-"that" = 'modular_citadel/sound/vox/that.ogg',
-"the" = 'modular_citadel/sound/vox/the.ogg',
-"then" = 'modular_citadel/sound/vox/then.ogg',
-"there" = 'modular_citadel/sound/vox/there.ogg',
-"third" = 'modular_citadel/sound/vox/third.ogg',
-"thirteen" = 'modular_citadel/sound/vox/thirteen.ogg',
-"thirty" = 'modular_citadel/sound/vox/thirty.ogg',
-"this" = 'modular_citadel/sound/vox/this.ogg',
-"those" = 'modular_citadel/sound/vox/those.ogg',
-"thousand" = 'modular_citadel/sound/vox/thousand.ogg',
-"threat" = 'modular_citadel/sound/vox/threat.ogg',
-"three" = 'modular_citadel/sound/vox/three.ogg',
-"through" = 'modular_citadel/sound/vox/through.ogg',
-"time" = 'modular_citadel/sound/vox/time.ogg',
-"to" = 'modular_citadel/sound/vox/to.ogg',
-"top" = 'modular_citadel/sound/vox/top.ogg',
-"topside" = 'modular_citadel/sound/vox/topside.ogg',
-"touch" = 'modular_citadel/sound/vox/touch.ogg',
-"towards" = 'modular_citadel/sound/vox/towards.ogg',
-"track" = 'modular_citadel/sound/vox/track.ogg',
-"train" = 'modular_citadel/sound/vox/train.ogg',
-"transportation" = 'modular_citadel/sound/vox/transportation.ogg',
-"truck" = 'modular_citadel/sound/vox/truck.ogg',
-"tunnel" = 'modular_citadel/sound/vox/tunnel.ogg',
-"turn" = 'modular_citadel/sound/vox/turn.ogg',
-"turret" = 'modular_citadel/sound/vox/turret.ogg',
-"twelve" = 'modular_citadel/sound/vox/twelve.ogg',
-"twenty" = 'modular_citadel/sound/vox/twenty.ogg',
-"two" = 'modular_citadel/sound/vox/two.ogg',
-"unauthorized" = 'modular_citadel/sound/vox/unauthorized.ogg',
-"under" = 'modular_citadel/sound/vox/under.ogg',
-"uniform" = 'modular_citadel/sound/vox/uniform.ogg',
-"unlocked" = 'modular_citadel/sound/vox/unlocked.ogg',
-"until" = 'modular_citadel/sound/vox/until.ogg',
-"up" = 'modular_citadel/sound/vox/up.ogg',
-"upper" = 'modular_citadel/sound/vox/upper.ogg',
-"uranium" = 'modular_citadel/sound/vox/uranium.ogg',
-"us" = 'modular_citadel/sound/vox/us.ogg',
-"usa" = 'modular_citadel/sound/vox/usa.ogg',
-"use" = 'modular_citadel/sound/vox/use.ogg',
-"used" = 'modular_citadel/sound/vox/used.ogg',
-"user" = 'modular_citadel/sound/vox/user.ogg',
-"vacate" = 'modular_citadel/sound/vox/vacate.ogg',
-"valid" = 'modular_citadel/sound/vox/valid.ogg',
-"vapor" = 'modular_citadel/sound/vox/vapor.ogg',
-"vent" = 'modular_citadel/sound/vox/vent.ogg',
-"ventillation" = 'modular_citadel/sound/vox/ventillation.ogg',
-"victor" = 'modular_citadel/sound/vox/victor.ogg',
-"violated" = 'modular_citadel/sound/vox/violated.ogg',
-"violation" = 'modular_citadel/sound/vox/violation.ogg',
-"voltage" = 'modular_citadel/sound/vox/voltage.ogg',
-"vox_login" = 'modular_citadel/sound/vox/vox_login.ogg',
-"walk" = 'modular_citadel/sound/vox/walk.ogg',
-"wall" = 'modular_citadel/sound/vox/wall.ogg',
-"want" = 'modular_citadel/sound/vox/want.ogg',
-"wanted" = 'modular_citadel/sound/vox/wanted.ogg',
-"warm" = 'modular_citadel/sound/vox/warm.ogg',
-"warn" = 'modular_citadel/sound/vox/warn.ogg',
-"warning" = 'modular_citadel/sound/vox/warning.ogg',
-"waste" = 'modular_citadel/sound/vox/waste.ogg',
-"water" = 'modular_citadel/sound/vox/water.ogg',
-"we" = 'modular_citadel/sound/vox/we.ogg',
-"weapon" = 'modular_citadel/sound/vox/weapon.ogg',
-"west" = 'modular_citadel/sound/vox/west.ogg',
-"whiskey" = 'modular_citadel/sound/vox/whiskey.ogg',
-"white" = 'modular_citadel/sound/vox/white.ogg',
-"wilco" = 'modular_citadel/sound/vox/wilco.ogg',
-"will" = 'modular_citadel/sound/vox/will.ogg',
-"with" = 'modular_citadel/sound/vox/with.ogg',
-"without" = 'modular_citadel/sound/vox/without.ogg',
-"woop" = 'modular_citadel/sound/vox/woop.ogg',
-"xeno" = 'modular_citadel/sound/vox/xeno.ogg',
-"yankee" = 'modular_citadel/sound/vox/yankee.ogg',
-"yards" = 'modular_citadel/sound/vox/yards.ogg',
-"year" = 'modular_citadel/sound/vox/year.ogg',
-"yellow" = 'modular_citadel/sound/vox/yellow.ogg',
-"yes" = 'modular_citadel/sound/vox/yes.ogg',
-"you" = 'modular_citadel/sound/vox/you.ogg',
-"your" = 'modular_citadel/sound/vox/your.ogg',
-"yourself" = 'modular_citadel/sound/vox/yourself.ogg',
-"zero" = 'modular_citadel/sound/vox/zero.ogg',
-"zone" = 'modular_citadel/sound/vox/zone.ogg',
-"zulu" = 'modular_citadel/sound/vox/zulu.ogg',))
-#endif
\ No newline at end of file
diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm
index 5e10e71433..99ba9ad3e2 100644
--- a/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm
+++ b/modular_citadel/code/modules/mob/living/silicon/robot/dogborg_equipment.dm
@@ -13,13 +13,24 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
w_class = 3
hitsound = 'sound/weapons/bite.ogg'
sharpness = IS_SHARP
+ var/stamtostunconversion = 0.1 //Total stamloss gets multiplied by this value for the help intent hard stun. Resting adds an additional 2x multiplier on top. Keep this low or so help me god.
+ var/stuncooldown = 4 SECONDS //How long it takes before you're able to attempt to stun a target again
+ var/nextstuntime
+
+/obj/item/dogborg/jaws/examine(mob/user)
+ . = ..()
+ if(!CONFIG_GET(flag/weaken_secborg))
+ to_chat(user, "Use help intent to attempt to non-lethally incapacitate the target by latching on with your maw. This is more effective against exhausted and resting targets. ")
/obj/item/dogborg/jaws/big
name = "combat jaws"
desc = "The jaws of the law. Very sharp."
icon_state = "jaws"
- force = 12
+ force = 15 //Chomp chomp. Crew harm.
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
+ stamtostunconversion = 0.2 // 100*0.2*2=40. Stun's just long enough to slap on cuffs with click delay if the target is near hard stamcrit.
+ stuncooldown = 6 SECONDS
+
/obj/item/dogborg/jaws/small
name = "puppy jaws"
@@ -30,12 +41,36 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
var/status = 0
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
- ..()
- user.do_attack_animation(A, ATTACK_EFFECT_BITE)
- log_combat(user, A, "bit")
+ if(!istype(user))
+ return
+ if(!CONFIG_GET(flag/weaken_secborg) && user.a_intent != INTENT_HARM && istype(A, /mob/living))
+ if(A == user.pulling)
+ to_chat(user, "You already have [A] in your jaws. ")
+ return
+ if(nextstuntime >= world.time)
+ to_chat(user, "Your jaw servos are still recharging. ")
+ return
+ nextstuntime = world.time + stuncooldown
+ var/mob/living/M = A
+ var/cachedstam = M.getStaminaLoss()
+ var/totalstuntime = cachedstam * stamtostunconversion * (M.lying ? 2 : 1)
+ if(!M.resting)
+ M.Knockdown(cachedstam*2) //BORK BORK. GET DOWN.
+ M.Stun(totalstuntime)
+ user.do_attack_animation(A, ATTACK_EFFECT_BITE)
+ user.start_pulling(M, TRUE) //Yip yip. Come with.
+ user.changeNext_move(CLICK_CD_MELEE)
+ M.visible_message("[user] clamps [user.p_their()] [src] onto [M] and latches on! ", "[user] clamps [user.p_their()] [src] onto you and latches on! ")
+ if(totalstuntime >= 4 SECONDS)
+ playsound(usr, 'sound/effects/k9_jaw_strong.ogg', 75, FALSE, 2) //Wuff wuff. Big stun.
+ else
+ playsound(usr, 'sound/effects/k9_jaw_weak.ogg', 50, TRUE, -1) //Arf arf. Pls buff.
+ else
+ . = ..()
+ user.do_attack_animation(A, ATTACK_EFFECT_BITE)
/obj/item/dogborg/jaws/small/attack_self(mob/user)
- var/mob/living/silicon/robot.R = user
+ var/mob/living/silicon/robot/R = user
if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0)
name = "combat jaws"
@@ -43,14 +78,18 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
desc = "The jaws of the law."
force = 12
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
+ stamtostunconversion = 0.15
+ stuncooldown = 5 SECONDS
status = 1
to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"]. ")
else
name = "puppy jaws"
icon_state = "smalljaws"
desc = "The jaws of a small dog."
- force = 5
+ force = initial(force)
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
+ stamtostunconversion = initial(stamtostunconversion)
+ stuncooldown = initial(stuncooldown)
status = 0
if(R.emagged)
to_chat(user, "Your jaws are now [status ? "Combat" : "Pup'd"]. ")
@@ -143,7 +182,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
/obj/item/storage/bag/borgdelivery/ComponentInitialize()
. = ..()
- GET_COMPONENT(STR, /datum/component/storage)
+ var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.max_combined_w_class = 5
STR.max_items = 1
@@ -167,7 +206,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
item_flags |= NOBLUDGEON //No more attack messages
/obj/item/soap/tongue/attack_self(mob/user)
- var/mob/living/silicon/robot.R = user
+ var/mob/living/silicon/robot/R = user
if(R.cell && R.cell.charge > 100)
if(R.emagged && status == 0)
status = !status
@@ -187,7 +226,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
update_icon()
/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
- var/mob/living/silicon/robot.R = user
+ var/mob/living/silicon/robot/R = user
if(!proximity || !check_allowed_items(target))
return
if(R.client && (target in R.client.screen))
@@ -307,8 +346,10 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
/mob/living/silicon/robot
var/leaping = 0
var/pounce_cooldown = 0
- var/pounce_cooldown_time = 50 //Nearly doubled, u happy?
- var/pounce_spoolup = 3
+ var/pounce_cooldown_time = 30 //Time in deciseconds between pounces
+ var/pounce_spoolup = 5 //Time in deciseconds for the pounce to happen after clicking
+ var/pounce_stamloss_cap = 120 //How much staminaloss pounces alone are capable of bringing a spaceman to
+ var/pounce_stamloss = 80 //Base staminaloss value of the pounce
var/leap_at
var/disabler
var/laser
@@ -320,13 +361,12 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
/obj/item/dogborg/pounce/afterattack(atom/A, mob/user)
var/mob/living/silicon/robot/R = user
- if(R && !R.pounce_cooldown)
- R.pounce_cooldown = !R.pounce_cooldown
+ if(R && (world.time >= R.pounce_cooldown))
+ R.pounce_cooldown = world.time + R.pounce_cooldown_time
to_chat(R, "Your targeting systems lock on to [A]... ")
+ playsound(R, 'sound/effects/servostep.ogg', 100, TRUE)
addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup)
- spawn(R.pounce_cooldown_time)
- R.pounce_cooldown = !R.pounce_cooldown
- else if(R && R.pounce_cooldown)
+ else if(R && (world.time < R.pounce_cooldown))
to_chat(R, "Your leg actuators are still recharging! ")
/mob/living/silicon/robot/proc/leap_at(atom/A)
@@ -338,7 +378,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
//It's also extremely buggy visually, so it's balance+bugfix
return
- if(cell.charge <= 500)
+ if(cell.charge <= 750)
to_chat(src,"Insufficent reserves for jump actuators! ")
return
@@ -348,7 +388,8 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
pixel_y = 10
update_icons()
throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1)
- cell.use(500) //Doubled the energy consumption
+ cell.use(750) //Less than a stunbaton since stunbatons hit everytime.
+ playsound(src, 'sound/effects/stealthoff.ogg', 25, TRUE, -1)
weather_immunities -= "lava"
/mob/living/silicon/robot/throw_impact(atom/A)
@@ -366,13 +407,13 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
blocked = 1
if(!blocked)
L.visible_message("[src] pounces on [L]! ", "[src] pounces on you! ")
- L.Knockdown(iscarbon(L) ? 450 : 45) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
+ L.Knockdown(iscarbon(L) ? 60 : 45, override_stamdmg = CLAMP(pounce_stamloss, 0, pounce_stamloss_cap-L.getStaminaLoss())) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
playsound(src, 'sound/weapons/Egloves.ogg', 50, 1)
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
step_towards(src,L)
log_combat(src, L, "borg pounced")
else
- Knockdown(45, 1, 1)
+ Knockdown(15, 1, 1)
pounce_cooldown = !pounce_cooldown
spawn(pounce_cooldown_time) //3s by default
@@ -380,7 +421,7 @@ SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
else if(A.density && !A.CanPass(src))
visible_message("[src] smashes into [A]! ", "You smash into [A]! ")
playsound(src, 'sound/items/trayhit1.ogg', 50, 1)
- Knockdown(45, 1, 1)
+ Knockdown(15, 1, 1)
if(leaping)
leaping = 0
diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm
index b16ac1d586..feec79ee8b 100644
--- a/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/modular_citadel/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -13,7 +13,7 @@
/mob/living/silicon/robot/proc/get_cit_modules()
var/list/modulelist = list()
modulelist["MediHound"] = /obj/item/robot_module/medihound
- if(!CONFIG_GET(flag/disable_secborg))
+ if(BORG_SEC_AVAILABLE)
modulelist["Security K-9"] = /obj/item/robot_module/k9
modulelist["Scrub Puppy"] = /obj/item/robot_module/scrubpup
modulelist["Borgi"] = /obj/item/robot_module/borgi
@@ -53,6 +53,7 @@
has_snowflake_deadsprite = TRUE
dogborg = TRUE
cyborg_pixel_offset = -16
+ borghealth = 80
/obj/item/robot_module/k9/do_transform_animation()
..()
diff --git a/modular_citadel/code/modules/mob/living/silicon/robot/robot_movement.dm b/modular_citadel/code/modules/mob/living/silicon/robot/robot_movement.dm
index c7a2447be6..28327cde0e 100644
--- a/modular_citadel/code/modules/mob/living/silicon/robot/robot_movement.dm
+++ b/modular_citadel/code/modules/mob/living/silicon/robot/robot_movement.dm
@@ -11,6 +11,7 @@
. = ..()
if(!resting && !sprinting)
. += 1
+ . += speed
/mob/living/silicon/robot/proc/togglesprint(shutdown = FALSE) //Basically a copypaste of the proc from /mob/living/carbon/human
if(!shutdown && (!cell || cell.charge < 25))
@@ -18,11 +19,11 @@
sprinting = shutdown ? FALSE : !sprinting
if(!resting && canmove)
if(sprinting)
- playsound_local(src, 'modular_citadel/sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
+ playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
else
if(shutdown)
playsound_local(src, 'sound/effects/light_flicker.ogg', 50, FALSE, pressure_affected = FALSE)
- playsound_local(src, 'modular_citadel/sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
+ playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
if(hud_used && hud_used.static_inventory)
for(var/obj/screen/sprintbutton/selector in hud_used.static_inventory)
selector.insert_witty_toggle_joke_here(src)
diff --git a/modular_citadel/code/modules/mob/living/simple_animal/kiwi.dm b/modular_citadel/code/modules/mob/living/simple_animal/kiwi.dm
deleted file mode 100644
index 27c1749011..0000000000
--- a/modular_citadel/code/modules/mob/living/simple_animal/kiwi.dm
+++ /dev/null
@@ -1,134 +0,0 @@
-/mob/living/simple_animal/kiwi
- name = "space kiwi"
- desc = "Exposure to low gravity made them grow larger."
- gender = FEMALE
- icon = 'modular_citadel/icons/mob/kiwi.dmi'
- icon_state = "kiwi"
- icon_living = "kiwi"
- icon_dead = "dead"
- speak = list("Chirp!","Cheep cheep chirp!!","Cheep.")
- speak_emote = list("chirps","trills")
- emote_hear = list("chirps.")
- emote_see = list("pecks at the ground.","jumps in place.")
- density = FALSE
- speak_chance = 2
- turns_per_move = 3
- butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
- var/egg_type = /obj/item/reagent_containers/food/snacks/egg/kiwiEgg
- var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "kicks"
- attacktext = "kicks"
- health = 25
- maxHealth = 25
- ventcrawler = VENTCRAWLER_ALWAYS
- var/eggsleft = 0
- var/eggsFertile = TRUE
- pass_flags = PASSTABLE | PASSMOB
- mob_size = MOB_SIZE_SMALL
- var/list/feedMessages = list("It chirps happily.","It chirps happily.")
- var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins chirping raucously.")
- gold_core_spawnable = FRIENDLY_SPAWN
- var/static/kiwi_count = 0
-
-/mob/living/simple_animal/kiwi/Destroy()
- --kiwi_count
- return ..()
-
-
-/mob/living/simple_animal/kiwi/Initialize()
- . = ..()
- ++kiwi_count
-
-
-/mob/living/simple_animal/kiwi/Life()
- . =..()
- if(!.)
- return
- if((!stat && prob(3) && eggsleft > 0) && egg_type)
- visible_message("[src] [pick(layMessage)]")
- eggsleft--
- var/obj/item/E = new egg_type(get_turf(src))
- E.pixel_x = rand(-6,6)
- E.pixel_y = rand(-6,6)
- if(eggsFertile)
- if(kiwi_count < MAX_CHICKENS && prob(25))
- START_PROCESSING(SSobj, E)
-
-/obj/item/reagent_containers/food/snacks/egg/kiwiEgg/process()
- if(isturf(loc))
- amount_grown += rand(1,2)
- if(amount_grown >= 100)
- visible_message("[src] hatches with a quiet cracking sound.")
- new /mob/living/simple_animal/babyKiwi(get_turf(src))
- STOP_PROCESSING(SSobj, src)
- qdel(src)
- else
- STOP_PROCESSING(SSobj, src)
-
-
-/mob/living/simple_animal/kiwi/attackby(obj/item/O, mob/user, params)
- if(istype(O, food_type)) //feedin' dem kiwis
- if(!stat && eggsleft < 8)
- var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]"
- user.visible_message(feedmsg)
- qdel(O)
- eggsleft += rand(1, 4)
- else
- to_chat(user, "[name] doesn't seem hungry! ")
- else
- ..()
-
-
-/mob/living/simple_animal/babyKiwi
- name = "baby space kiwi"
- desc = "So huggable."
- icon = 'modular_citadel/icons/mob/kiwi.dmi'
- icon_state = "babyKiwi"
- icon_living = "babyKiwi"
- icon_dead = "deadBaby"
- icon_gib = "chick_gib"
- gender = FEMALE
- speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
- speak_emote = list("chirps")
- emote_hear = list("chirps.")
- emote_see = list("pecks at the ground.","Happily bounces in place.")
- density = FALSE
- speak_chance = 2
- turns_per_move = 2
- butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "kicks"
- attacktext = "kicks"
- health = 10
- maxHealth = 10
- ventcrawler = VENTCRAWLER_ALWAYS
- var/amount_grown = 0
- pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
- mob_size = MOB_SIZE_TINY
- gold_core_spawnable = FRIENDLY_SPAWN
-
-/mob/living/simple_animal/babyKiwi/Initialize()
- . = ..()
- pixel_x = rand(-6, 6)
- pixel_y = rand(0, 10)
-
-/mob/living/simple_animal/babyKiwi/Life()
- . =..()
- if(!.)
- return
- if(!stat && !ckey)
- amount_grown += rand(1,2)
- if(amount_grown >= 100)
- new /mob/living/simple_animal/kiwi(src.loc)
- qdel(src)
-
-
-/obj/item/reagent_containers/food/snacks/egg/kiwiEgg
- name = "kiwi egg"
- icon = 'modular_citadel/icons/mob/kiwi.dmi'
- desc = "A slightly bigger egg!"
- icon_state = "egg"
-
diff --git a/modular_citadel/code/modules/mob/mob.dm b/modular_citadel/code/modules/mob/mob.dm
index bf6987ab81..aa0e6b5828 100644
--- a/modular_citadel/code/modules/mob/mob.dm
+++ b/modular_citadel/code/modules/mob/mob.dm
@@ -3,9 +3,11 @@
/mob/say_mod(input, message_mode)
var/customsayverb = findtext(input, "*")
- if(customsayverb)
+ if(customsayverb && message_mode != MODE_WHISPER_CRIT)
+ message_mode = MODE_CUSTOM_SAY
return lowertext(copytext(input, 1, customsayverb))
- . = ..()
+ else
+ return ..()
/atom/movable/proc/attach_spans(input, list/spans)
var/customsayverb = findtext(input, "*")
diff --git a/modular_citadel/code/modules/projectiles/bullets/bullets/smg.dm b/modular_citadel/code/modules/projectiles/bullets/bullets/smg.dm
index f069a73fe8..75151417d7 100644
--- a/modular_citadel/code/modules/projectiles/bullets/bullets/smg.dm
+++ b/modular_citadel/code/modules/projectiles/bullets/bullets/smg.dm
@@ -1,4 +1,4 @@
/obj/item/projectile/bullet/c46x30mm_tx
name = "toxin tipped 4.6x30mm bullet"
- damage = 15
+ damage = 10
damage_type = TOX
\ No newline at end of file
diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm
index 70d3bee5af..8ee00bef06 100644
--- a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm
+++ b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon.dm
@@ -57,10 +57,9 @@
icon_state = "magjectile-nl"
damage = 2
knockdown = 0
- stamina = 25
- armour_penetration = -10
+ stamina = 20
light_range = 2
- speed = 0.7
+ speed = 0.6
range = 25
light_color = LIGHT_COLOR_BLUE
@@ -109,9 +108,10 @@
fire_sound = 'sound/weapons/magpistol.ogg'
mag_type = /obj/item/ammo_box/magazine/mmag/small
can_suppress = 0
- casing_ejector = 0
+ casing_ejector = FALSE
fire_delay = 2
- recoil = 0.2
+ recoil = 0.1
+ inaccuracy_modifier = 0.25
/obj/item/gun/ballistic/automatic/pistol/mag/update_icon()
..()
@@ -123,7 +123,6 @@
icon_state = "[initial(icon_state)][chambered ? "" : "-e"]"
///research memes///
-/*
/obj/item/gun/ballistic/automatic/pistol/mag/nopin
pin = null
spawnwithmagazine = FALSE
@@ -155,7 +154,7 @@
materials = list(MAT_METAL = 3000, MAT_SILVER = 250, MAT_TITANIUM = 250)
build_path = /obj/item/ammo_box/magazine/mmag/small
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
-*/
+
//////toy memes/////
/obj/item/projectile/bullet/reusable/foam_dart/mag
@@ -201,9 +200,9 @@
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "magjectile-large"
damage = 20
- armour_penetration = 25
+ armour_penetration = 20
light_range = 3
- speed = 0.7
+ speed = 0.6
range = 35
light_color = LIGHT_COLOR_RED
@@ -212,10 +211,10 @@
icon_state = "magjectile-large-nl"
damage = 2
knockdown = 0
- stamina = 25
- armour_penetration = -10
+ stamina = 20
+ armour_penetration = 10
light_range = 3
- speed = 0.65
+ speed = 0.6
range = 35
light_color = LIGHT_COLOR_BLUE
@@ -227,6 +226,8 @@
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "mag-casing-live"
projectile_type = /obj/item/projectile/bullet/magrifle
+ click_cooldown_override = 2.5
+ delay = 3
/obj/item/ammo_casing/caseless/anlmagm
desc = "A large, specialized ferromagnetic slug designed with a less-than-lethal payload."
@@ -234,10 +235,12 @@
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "mag-casing-live"
projectile_type = /obj/item/projectile/bullet/nlmagrifle
+ click_cooldown_override = 2.5
+ delay = 3
///magazines///
-/obj/item/ammo_box/magazine/mmag/
+/obj/item/ammo_box/magazine/mmag
name = "magrifle magazine (non-lethal disabler)"
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "mediummagmag"
@@ -261,17 +264,20 @@
icon = 'modular_citadel/icons/obj/guns/cit_guns.dmi'
icon_state = "magrifle"
item_state = "arg"
- slot_flags = 0
+ slot_flags = NONE
mag_type = /obj/item/ammo_box/magazine/mmag
fire_sound = 'sound/weapons/magrifle.ogg'
can_suppress = 0
- burst_size = 3
- fire_delay = 2
- spread = 5
- recoil = 0.15
- casing_ejector = 0
+ burst_size = 1
+ actions_types = null
+ fire_delay = 3
+ spread = 0
+ recoil = 0.1
+ casing_ejector = FALSE
+ inaccuracy_modifier = 0.5
+ weapon_weight = WEAPON_MEDIUM
+ dualwield_spread_mult = 1.4
-/*
//research///
/obj/item/gun/ballistic/automatic/magrifle/nopin
@@ -305,7 +311,7 @@
materials = list(MAT_METAL = 6000, MAT_SILVER = 500, MAT_TITANIUM = 500)
build_path = /obj/item/ammo_box/magazine/mmag
departmental_flags = DEPARTMENTAL_FLAG_SECURITY
-*/
+
///foamagrifle///
/obj/item/ammo_box/magazine/toy/foamag
@@ -327,7 +333,6 @@
spread = 60
w_class = WEIGHT_CLASS_BULKY
weapon_weight = WEAPON_HEAVY
-/*
// TECHWEBS IMPLEMENTATION
//
@@ -339,7 +344,6 @@
design_ids = list("magrifle", "magpisol", "mag_magrifle", "mag_magrifle_nl", "mag_magpistol", "mag_magpistol_nl")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
-*/
//////Hyper-Burst Rifle//////
diff --git a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm
index 8786eb6dc9..7e6a8b3389 100644
--- a/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm
+++ b/modular_citadel/code/modules/projectiles/guns/ballistic/magweapon_energy.dm
@@ -143,6 +143,7 @@
// TECHWEBS IMPLEMENTATION
*/
+/*
/datum/techweb_node/magnetic_weapons
id = "magnetic_weapons"
display_name = "Magnetic Weapons"
@@ -151,6 +152,7 @@
design_ids = list("magrifle_e", "magpistol_e", "mag_magrifle_e", "mag_magrifle_e_nl", "mag_magpistol_e", "mag_magpistol_e_nl")
research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500)
export_price = 5000
+*/
///magrifle///
diff --git a/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm b/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
index 0f7db73d6e..5fc75fa414 100644
--- a/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
+++ b/modular_citadel/code/modules/projectiles/guns/energy/energy_gun.dm
@@ -1,13 +1,6 @@
/obj/item/gun/energy/e_gun
name = "blaster carbine"
desc = "A high powered particle blaster carbine with varitable setting for stunning or lethal applications."
- icon = 'modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi'
- lefthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi'
- righthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi'
- ammo_x_offset = 2
- flight_x_offset = 17
- flight_y_offset = 11
-
/*/////////////////////////////////////////////////////////////////////////////////////////////
The Recolourable Energy Gun
diff --git a/modular_citadel/code/modules/projectiles/guns/energy/laser.dm b/modular_citadel/code/modules/projectiles/guns/energy/laser.dm
index c82a3e9ed9..76d7403d16 100644
--- a/modular_citadel/code/modules/projectiles/guns/energy/laser.dm
+++ b/modular_citadel/code/modules/projectiles/guns/energy/laser.dm
@@ -1,19 +1,11 @@
/obj/item/gun/energy/laser
name = "blaster rifle"
desc = "a high energy particle blaster, efficient and deadly."
- icon = 'modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi'
- ammo_x_offset = 1
- shaded_charge = 1
- lefthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi'
- righthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi'
/obj/item/gun/energy/laser/practice
+ icon = 'modular_citadel/icons/obj/guns/energy.dmi'
icon_state = "laser-p"
-
-/obj/item/gun/energy/laser/bluetag
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
-
-/obj/item/gun/energy/laser/redtag
- lefthand_file = 'icons/mob/inhands/weapons/guns_lefthand.dmi'
- righthand_file = 'icons/mob/inhands/weapons/guns_righthand.dmi'
+ lefthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_lefthand.dmi'
+ righthand_file = 'modular_citadel/icons/mob/inhands/OVERRIDE_guns_righthand.dmi'
+ ammo_x_offset = 1
+ shaded_charge = 1
diff --git a/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm b/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
index fa0e64032c..aef47a648e 100644
--- a/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
+++ b/modular_citadel/code/modules/projectiles/guns/pumpenergy.dm
@@ -75,9 +75,9 @@
/obj/item/gun/energy/pumpaction/proc/pump(mob/M) //pumping proc. Checks if the gun is empty and plays a different sound if it is.
var/obj/item/ammo_casing/energy/shot = ammo_type[select]
if(cell.charge < shot.e_cost)
- playsound(M, 'modular_citadel/sound/weapons/laserPumpEmpty.ogg', 100, 1) //Ends with three beeps made from highly processed knife honing noises
+ playsound(M, 'sound/weapons/laserPumpEmpty.ogg', 100, 1) //Ends with three beeps made from highly processed knife honing noises
else
- playsound(M, 'modular_citadel/sound/weapons/laserPump.ogg', 100, 1) //Ends with high pitched charging noise
+ playsound(M, 'sound/weapons/laserPump.ogg', 100, 1) //Ends with high pitched charging noise
recharge_newshot() //try to charge a new shot
update_icon()
return 1
@@ -152,14 +152,14 @@
e_cost = 150
pellets = 4
variance = 30
- fire_sound = 'modular_citadel/sound/weapons/ParticleBlaster.ogg'
+ fire_sound = 'sound/weapons/ParticleBlaster.ogg'
select_name = "disable"
/obj/item/ammo_casing/energy/disabler/slug
projectile_type = /obj/item/projectile/beam/disabler/slug
select_name = "overdrive"
e_cost = 200
- fire_sound = 'modular_citadel/sound/weapons/LaserSlugv3.ogg'
+ fire_sound = 'sound/weapons/LaserSlugv3.ogg'
/obj/item/ammo_casing/energy/laser/pump
projectile_type = /obj/item/projectile/beam/weak
@@ -167,12 +167,12 @@
select_name = "kill"
pellets = 3
variance = 15
- fire_sound = 'modular_citadel/sound/weapons/ParticleBlaster.ogg'
+ fire_sound = 'sound/weapons/ParticleBlaster.ogg'
/obj/item/ammo_casing/energy/electrode/pump
projectile_type = /obj/item/projectile/energy/electrode/pump
select_name = "stun"
- fire_sound = 'modular_citadel/sound/weapons/LaserSlugv3.ogg'
+ fire_sound = 'sound/weapons/LaserSlugv3.ogg'
e_cost = 300
pellets = 3
variance = 20
diff --git a/modular_citadel/code/modules/projectiles/guns/toys.dm b/modular_citadel/code/modules/projectiles/guns/toys.dm
index 18d174d677..731f990cfb 100644
--- a/modular_citadel/code/modules/projectiles/guns/toys.dm
+++ b/modular_citadel/code/modules/projectiles/guns/toys.dm
@@ -39,7 +39,7 @@
projectile_type = /obj/item/projectile/beam/lasertag/wavemotion
select_name = "overdrive"
e_cost = 300
- fire_sound = 'modular_citadel/sound/weapons/LaserSlugv3.ogg'
+ fire_sound = 'sound/weapons/LaserSlugv3.ogg'
/obj/item/ammo_casing/energy/laser/dispersal
projectile_type = /obj/item/projectile/beam/lasertag/dispersal
@@ -47,7 +47,7 @@
pellets = 5
variance = 25
e_cost = 200
- fire_sound = 'modular_citadel/sound/weapons/ParticleBlaster.ogg'
+ fire_sound = 'sound/weapons/ParticleBlaster.ogg'
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TOY REVOLVER
diff --git a/modular_citadel/code/modules/projectiles/projectile/energy.dm b/modular_citadel/code/modules/projectiles/projectile/energy.dm
deleted file mode 100644
index a32f23f0fc..0000000000
--- a/modular_citadel/code/modules/projectiles/projectile/energy.dm
+++ /dev/null
@@ -1,2 +0,0 @@
-/obj/item/projectile/energy/electrode
- stamina = 36
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm
index 1508a5d519..4e80f42d87 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm
@@ -136,7 +136,6 @@ Creating a chem with a low purity will make you permanently fall in love with so
color = "#660015" // rgb: , 0, 255
taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses"
overdose_threshold = 100 //If this is too easy to get 100u of this, then double it please.
- DoNotSplit = TRUE
metabolization_rate = 0.1//It has to be slow, so there's time for the effect.
data = list("creatorID" = null, "creatorGender" = null, "creatorName" = null)
var/creatorID //ckey
@@ -144,20 +143,19 @@ Creating a chem with a low purity will make you permanently fall in love with so
var/creatorName
var/mob/living/creator
pH = 10
- OnMobMergeCheck = TRUE //Procs on_mob_add when merging into a human
+ chemical_flags = REAGENT_ONMOBMERGE | REAGENT_DONOTSPLIT //Procs on_mob_add when merging into a human
can_synth = FALSE
/datum/reagent/fermi/enthrall/test
name = "MKUltraTest"
id = "enthrallTest"
- description = "A forbidden deep red mixture that overwhelms a foreign body with waves of joy, intoxicating them into servitude. When taken by the creator, it will enhance the draw of their voice to those affected by it."
+ description = "A forbidden deep red mixture that makes you like Fermis a little too much. Unobtainable and due to be removed from the wiki."
data = list("creatorID" = "honkatonkbramblesnatch", "creatorGender" = "Mistress", "creatorName" = "Fermis Yakumo")
creatorID = "honkatonkbramblesnatch"//ckey
creatorGender = "Mistress"
creatorName = "Fermis Yakumo"
purity = 1
- DoNotSplit = TRUE
/datum/reagent/fermi/enthrall/test/on_new()
id = "enthrall"
@@ -295,18 +293,18 @@ Creating a chem with a low purity will make you permanently fall in love with so
SSblackbox.record_feedback("tally", "fermi_chem", 1, "Thralls mindbroken")
/datum/reagent/fermi/enthrall/overdose_process(mob/living/carbon/M)
- M.adjustBrainLoss(0.2)//should be ~30 in total
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.2)//should be ~30 in total
..()
//Creates a gas cloud when the reaction blows up, causing everyone in it to fall in love with someone/something while it's in their system.
/datum/reagent/fermi/enthrallExplo//Created in a gas cloud when it explodes
- name = "MKUltra"
+ name = "Gaseous MKUltra"
id = "enthrallExplo"
- description = "A forbidden deep red mixture that overwhelms a foreign body with waves of desire, inducing a chemial love for another. Also, how the HECC did you get this?"
+ description = "A forbidden deep red gas that overwhelms a foreign body, causing the person they next lay their eyes on to become more interesting. Studies have shown that people are 66% more likely to make friends with this in the air. Produced when MKUltra explodes."
color = "#2C051A" // rgb: , 0, 255
metabolization_rate = 0.1
taste_description = "synthetic chocolate, a base tone of alcohol, and high notes of roses."
- DoNotSplit = TRUE
+ chemical_flags = REAGENT_DONOTSPLIT
can_synth = FALSE
var/mob/living/carbon/love
@@ -342,7 +340,7 @@ Creating a chem with a low purity will make you permanently fall in love with so
M.Stun(10)
M.emote("whimper")//does this exist?
to_chat(M, "[(M.client?.prefs.lewdchem?"":"")] You're overcome with a desire to see [love]. ")
- M.adjustBrainLoss(0.5)//I found out why everyone was so damaged!
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.5)//I found out why everyone was so damaged!
..()
/datum/reagent/fermi/enthrallExplo/on_mob_delete(mob/living/carbon/M)
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm
index 8af3176746..613d8819fa 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm
@@ -54,9 +54,9 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
var/pollStarted = FALSE
var/location_created
var/startHunger
- ImpureChem = "SDGFtox"
- InverseChemVal = 0.5
- InverseChem = "SDZF"
+ impure_chem = "SDGFtox"
+ inverse_chem_val = 0.5
+ inverse_chem = "SDZF"
can_synth = TRUE
@@ -68,11 +68,10 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
startHunger = M.nutrition
if(pollStarted == FALSE)
pollStarted = TRUE
- candies = pollGhostCandidates("Do you want to play as a clone of [M], and do you agree to respect their character and act in a similar manner to them? Do not engage in ERP as them unless you have LOOC permission from them, and ensure it is permission from the original, not a clone.")
+ candies = pollGhostCandidates("Do you want and agree to play as a clone of [M], respect their character and not engage in ERP without permission from the original?", ignore_category = POLL_IGNORE_CLONE)
log_game("FERMICHEM: [M] ckey: [M.key] has taken SDGF, and ghosts have been polled.")
if(20 to INFINITY)
if(LAZYLEN(candies) && playerClone == FALSE) //If there's candidates, clone the person and put them in there!
- log_game("FERMICHEM: [M] ckey: [M.key] is creating a clone, controlled by [candies]")
to_chat(M, "The cells reach a critical micelle concentration, nucleating rapidly within your body! ")
var/typepath = M.type
var/mob/living/carbon/human/fermi_Gclone = new typepath(M.loc)
@@ -86,15 +85,16 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
candies = shuffle(candies)//Shake those ghosts up!
for(var/mob/dead/observer/C2 in candies)
if(C2.key && C2)
- SM.key = C2.key
+ C2.transfer_ckey(SM, FALSE)
message_admins("Ghost candidate found! [C2] key [C2.key] is becoming a clone of [M] key: [M.key] (They agreed to respect the character they're becoming, and agreed to not ERP without express permission from the original.)")
log_game("FERMICHEM: [M] ckey: [M.key] is creating a clone, controlled by [C2]")
break
else
- candies =- C2
+ candies -= C2
if(!SM.mind) //Something went wrong, use alt mechanics
return ..()
SM.mind.enslave_mind_to_creator(M)
+ SM.mind.store_memory(M.mind.memory)
//If they're a zombie, they can try to negate it with this.
//I seriously wonder if anyone will ever use this function.
@@ -123,7 +123,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
//Damage the clone
SM.blood_volume = (BLOOD_VOLUME_NORMAL*SM.blood_ratio)/2
SM.adjustCloneLoss(60, 0)
- SM.setBrainLoss(40)
+ SM.setOrganLoss(ORGAN_SLOT_BRAIN, 40)
SM.nutrition = startHunger/2
//Transfer remaining reagent to clone. I think around 30u will make a healthy clone, otherwise they'll have clone damage, blood loss, brain damage and hunger.
@@ -249,7 +249,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
SM.adjustToxLoss(-(bodydamage/10), 0)
SM.blood_volume = (BLOOD_VOLUME_NORMAL*SM.blood_ratio)/1.5
SM.adjustCloneLoss((bodydamage/10), 0)
- SM.setBrainLoss((bodydamage/10))
+ SM.setOrganLoss(ORGAN_SLOT_BRAIN, (bodydamage/10))
SM.nutrition = 400
if(bodydamage>200)
SM.gain_trauma_type(BRAIN_TRAUMA_MILD)
@@ -280,8 +280,9 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
//Unobtainable, used in clone spawn.
/datum/reagent/fermi/SDGFheal
- name = "synthetic-derived growth factor"
+ name = "synthetic-derived healing factor"
id = "SDGFheal"
+ description = "Leftover SDGF is transferred into the resulting clone, which quickly heals up the stresses from suddenly splitting. Restores blood, nutrition, and repaires brain and clone damage quickly. Only obtainable from using excess SDGF, and only enters the cloned body."
metabolization_rate = 1
can_synth = FALSE
@@ -289,34 +290,35 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING
if(M.blood_volume < (BLOOD_VOLUME_NORMAL*M.blood_ratio))
M.blood_volume += 10
M.adjustCloneLoss(-2, 0)
- M.setBrainLoss(-1)
+ M.setOrganLoss(ORGAN_SLOT_BRAIN, -1)
M.nutrition += 10
..()
//Unobtainable, used if SDGF is impure but not too impure
-/datum/reagent/fermi/SDGFtox
- name = "synthetic-derived growth factor"
+/datum/reagent/impure/SDGFtox
+ name = "Synthetic-derived apoptosis factor"
id = "SDGFtox"
- description = "A chem that makes a certain chemcat angry at you if you're reading this, how did you get this???"//i.e. tell me please, figure it's a good way to get pinged for bugfixes.
+ description = "Impure synthetic-derived growth factor causes certain cells to undergo cell death, causing clone damage, and damaging blood cells."//i.e. tell me please, figure it's a good way to get pinged for bugfixes.
metabolization_rate = 1
can_synth = FALSE
-/datum/reagent/fermi/SDGFtox/on_mob_life(mob/living/carbon/M)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good)
+/datum/reagent/impure/SDGFtox/on_mob_life(mob/living/carbon/M)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good)
M.blood_volume -= 10
M.adjustCloneLoss(2, 0)
..()
//Fail state of SDGF
-/datum/reagent/fermi/SDZF
- name = "synthetic-derived growth factor"
+/datum/reagent/impure/SDZF
+ name = "synthetic-derived zombie factor"
id = "SDZF"
- description = "A horribly peverse mass of Embryonic stem cells made real by the hands of a failed chemist. This message should never appear, how did you manage to get a hold of this?"
+ description = "A horribly peverse mass of Embryonic stem cells made real by the hands of a failed chemist. Emulates normal synthetic-derived growth factor, but produces a hostile zombie at the end of it."
color = "#a502e0" // rgb: 96, 0, 255
metabolization_rate = 0.5 * REAGENTS_METABOLISM
var/startHunger
can_synth = TRUE
+ chemical_flags = REAGENT_SNEAKYNAME
-/datum/reagent/fermi/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead.
+/datum/reagent/impure/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead.
switch(current_cycle)//Pretends to be normal
if(20)
to_chat(M, "You feel the synethic cells rest uncomfortably within your body as they start to pulse and grow rapidly. ")
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm
index d05cfb552e..88586b423e 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm
@@ -28,7 +28,7 @@ I'd like to point out from my calculations it'll take about 60-80 minutes to die
var/datum/mind/originalmind
var/antiGenetics = 255
var/sleepytime = 0
- InverseChemVal = 0.25
+ inverse_chem_val = 0.25
can_synth = FALSE
/datum/action/chem/astral
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm
index d603f3ba10..ee90f985c6 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm
@@ -26,21 +26,19 @@
taste_description = "a milky ice cream like flavour."
overdose_threshold = 17
metabolization_rate = 0.25
- ImpureChem = "BEsmaller" //If you make an inpure chem, it stalls growth
- InverseChemVal = 0.35
- InverseChem = "BEsmaller" //At really impure vols, it just becomes 100% inverse
+ impure_chem = "BEsmaller" //If you make an inpure chem, it stalls growth
+ inverse_chem_val = 0.35
+ inverse_chem = "BEsmaller" //At really impure vols, it just becomes 100% inverse
can_synth = FALSE
+ var/message_spam = FALSE
-/datum/reagent/fermi/breast_enlarger/on_mob_add(mob/living/carbon/M)
+/datum/reagent/fermi/breast_enlarger/on_mob_metabolize(mob/living/M)
. = ..()
if(!ishuman(M)) //The monkey clause
if(volume >= 15) //To prevent monkey breast farms
var/turf/T = get_turf(M)
var/obj/item/organ/genital/breasts/B = new /obj/item/organ/genital/breasts(T)
- var/list/seen = viewers(8, T)
- for(var/mob/S in seen)
- to_chat(S, "A pair of breasts suddenly fly out of the [M]! ")
- //var/turf/T2 = pick(turf in view(5, M))
+ M.visible_message("A pair of breasts suddenly fly out of the [M]! ")
var/T2 = get_random_station_turf()
M.adjustBruteLoss(25)
M.Knockdown(50)
@@ -48,118 +46,105 @@
B.throw_at(T2, 8, 1)
M.reagents.remove_reagent(id, volume)
return
- log_game("FERMICHEM: [M] ckey: [M.key] has ingested Sucubus milk")
var/mob/living/carbon/human/H = M
- H.genital_override = TRUE
- var/obj/item/organ/genital/breasts/B = H.getorganslot("breasts")
- if(!B)
- H.emergent_genital_call()
- return
- if(!B.size == "huge")
- var/sizeConv = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5)
- B.prev_size = B.size
- B.cached_size = sizeConv[B.size]
+ if(!H.getorganslot(ORGAN_SLOT_BREASTS) && H.emergent_genital_call())
+ H.genital_override = TRUE
/datum/reagent/fermi/breast_enlarger/on_mob_life(mob/living/carbon/M) //Increases breast size
if(!ishuman(M))//Just in case
return..()
var/mob/living/carbon/human/H = M
- var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
+ var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
if(!B) //If they don't have breasts, give them breasts.
//If they have Acute hepatic pharmacokinesis, then route processing though liver.
- if(HAS_TRAIT(M, TRAIT_PHARMA))
- var/obj/item/organ/liver/L = M.getorganslot("liver")
+ if(HAS_TRAIT(H, TRAIT_PHARMA) || !H.canbearoused)
+ var/obj/item/organ/liver/L = H.getorganslot(ORGAN_SLOT_LIVER)
if(L)
- L.swelling+= 0.05
- return..()
+ L.swelling += 0.05
else
- M.adjustToxLoss(1)
- return..()
+ H.adjustToxLoss(1)
+ return..()
//otherwise proceed as normal
- var/obj/item/organ/genital/breasts/nB = new
- nB.Insert(M)
- if(nB)
- if(M.dna.species.use_skintones && M.dna.features["genitals_use_skintone"])
- nB.color = skintone2hex(H.skin_tone)
- else if(M.dna.features["breasts_color"])
- nB.color = "#[M.dna.features["breasts_color"]]"
- else
- nB.color = skintone2hex(H.skin_tone)
- nB.size = "flat"
- nB.cached_size = 0
- nB.prev_size = 0
- to_chat(M, "Your chest feels warm, tingling with newfound sensitivity. ")
- M.reagents.remove_reagent(id, 5)
- B = nB
+ B = new
+ if(H.dna.species.use_skintones && H.dna.features["genitals_use_skintone"])
+ B.color = skintone2hex(H.skin_tone)
+ else if(M.dna.features["breasts_color"])
+ B.color = "#[M.dna.features["breasts_color"]]"
+ else
+ B.color = skintone2hex(H.skin_tone)
+ B.size = "flat"
+ B.cached_size = 0
+ B.prev_size = 0
+ to_chat(H, "Your chest feels warm, tingling with newfound sensitivity. ")
+ H.reagents.remove_reagent(id, 5)
+ B.Insert(H)
+
//If they have them, increase size. If size is comically big, limit movement and rip clothes.
- B.cached_size = B.cached_size + 0.05
- if (B.cached_size >= 8.5 && B.cached_size < 9)
- if(H.w_uniform || H.wear_suit)
- var/target = M.get_bodypart(BODY_ZONE_CHEST)
- to_chat(M, "Your breasts begin to strain against your clothes tightly! ")
- M.adjustOxyLoss(5, 0)
- M.apply_damage(1, BRUTE, target)
- B.update()
- ..()
+ B.modify_size(0.05)
+
+ if (ISINRANGE_EX(B.cached_size, 8.5, 9) && (H.w_uniform || H.wear_suit))
+ var/target = H.get_bodypart(BODY_ZONE_CHEST)
+ if(!message_spam)
+ to_chat(H, "Your breasts begin to strain against your clothes tightly! ")
+ message_spam = TRUE
+ H.adjustOxyLoss(5, 0)
+ H.apply_damage(1, BRUTE, target)
+ return ..()
/datum/reagent/fermi/breast_enlarger/overdose_process(mob/living/carbon/M) //Turns you into a female if male and ODing, doesn't touch nonbinary and object genders.
//Acute hepatic pharmacokinesis.
- if(HAS_TRAIT(M, TRAIT_PHARMA))
- var/obj/item/organ/liver/L = M.getorganslot("liver")
+ if(HAS_TRAIT(M, TRAIT_PHARMA) || !M.canbearoused)
+ var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
L.swelling+= 0.05
return ..()
- var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
- var/obj/item/organ/genital/testicles/T = M.getorganslot("testicles")
- var/obj/item/organ/genital/vagina/V = M.getorganslot("vagina")
- var/obj/item/organ/genital/womb/W = M.getorganslot("womb")
+ var/obj/item/organ/genital/penis/P = M.getorganslot(ORGAN_SLOT_PENIS)
+ var/obj/item/organ/genital/testicles/T = M.getorganslot(ORGAN_SLOT_TESTICLES)
+ var/obj/item/organ/genital/vagina/V = M.getorganslot(ORGAN_SLOT_VAGINA)
+ var/obj/item/organ/genital/womb/W = M.getorganslot(ORGAN_SLOT_WOMB)
if(M.gender == MALE)
M.gender = FEMALE
M.visible_message("[M] suddenly looks more feminine! ", "You suddenly feel more feminine! ")
if(P)
- P.cached_length = P.cached_length - 0.05
- P.update()
+ P.modify_size(-0.05)
if(T)
- T.Remove(M)
+ qdel(T)
if(!V)
- var/obj/item/organ/genital/vagina/nV = new
- nV.Insert(M)
- V = nV
+ V = new
+ V.Insert(M)
if(!W)
- var/obj/item/organ/genital/womb/nW = new
- nW.Insert(M)
- W = nW
- ..()
+ W = new
+ W.Insert(M)
+ return ..()
/datum/reagent/fermi/BEsmaller
name = "Modesty milk"
id = "BEsmaller"
- description = "A volatile collodial mixture derived from milk that encourages mammary reduction via a potent estrogen mix."
+ description = "A volatile collodial mixture derived from milk that encourages mammary reduction via a potent estrogen mix. Produced by reacting impure Succubus milk."
color = "#E60584" // rgb: 96, 0, 255
taste_description = "a milky ice cream like flavour."
metabolization_rate = 0.25
can_synth = FALSE
/datum/reagent/fermi/BEsmaller/on_mob_life(mob/living/carbon/M)
- var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
+ var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
if(!B)
//Acute hepatic pharmacokinesis.
- if(HAS_TRAIT(M, TRAIT_PHARMA))
- var/obj/item/organ/liver/L = M.getorganslot("liver")
+ if(HAS_TRAIT(M, TRAIT_PHARMA) || !M.canbearoused)
+ var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
L.swelling-= 0.05
return ..()
//otherwise proceed as normal
return..()
- B.cached_size = B.cached_size - 0.05
- B.update()
- ..()
+ B.modify_size(-0.05)
+ return ..()
/datum/reagent/fermi/BEsmaller_hypo
name = "Rectify milk" //Rectify
@@ -171,31 +156,28 @@
var/sizeConv = list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5)
can_synth = TRUE
-/datum/reagent/fermi/BEsmaller_hypo/on_mob_add(mob/living/carbon/M)
+/datum/reagent/fermi/BEsmaller_hypo/on_mob_metabolize(mob/living/M)
. = ..()
- if(!M.getorganslot("vagina"))
- if(M.dna.features["has_vag"])
- var/obj/item/organ/genital/vagina/nV = new
- nV.Insert(M)
- if(!M.getorganslot("womb"))
- if(M.dna.features["has_womb"])
- var/obj/item/organ/genital/womb/nW = new
- nW.Insert(M)
+ if(!ishuman(M))
+ return
+ var/mob/living/carbon/human/H = M
+ if(!H.getorganslot(ORGAN_SLOT_VAGINA) && H.dna.features["has_vag"])
+ H.give_genital(/obj/item/organ/genital/vagina)
+ if(!H.getorganslot(ORGAN_SLOT_WOMB) && H.dna.features["has_womb"])
+ H.give_genital(/obj/item/organ/genital/womb)
/datum/reagent/fermi/BEsmaller_hypo/on_mob_life(mob/living/carbon/M)
- var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
+ var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
if(!B)
return..()
- if(!M.dna.features["has_breasts"])//Fast fix for those who don't want it.
- B.cached_size = B.cached_size - 0.1
- B.update()
- else if(B.cached_size > (sizeConv[M.dna.features["breasts_size"]]+0.1))
- B.cached_size = B.cached_size - 0.05
- B.update()
- else if(B.cached_size < (sizeConv[M.dna.features["breasts_size"]])+0.1)
- B.cached_size = B.cached_size + 0.05
- B.update()
- ..()
+ var/optimal_size = B.breast_values[M.dna.features["breasts_size"]]
+ if(!optimal_size)//Fast fix for those who don't want it.
+ B.modify_size(-0.1)
+ else if(B.cached_size > optimal_size)
+ B.modify_size(-0.05, optimal_size)
+ else if(B.cached_size < optimal_size)
+ B.modify_size(0.05, 0, optimal_size)
+ return ..()
////////////////////////////////////////////////////////////////////////////////////////////////////
// PENIS ENLARGE
@@ -211,20 +193,19 @@
taste_description = "chinese dragon powder"
overdose_threshold = 17 //ODing makes you male and removes female genitals
metabolization_rate = 0.5
- ImpureChem = "PEsmaller" //If you make an inpure chem, it stalls growth
- InverseChemVal = 0.35
- InverseChem = "PEsmaller" //At really impure vols, it just becomes 100% inverse and shrinks instead.
+ impure_chem = "PEsmaller" //If you make an inpure chem, it stalls growth
+ inverse_chem_val = 0.35
+ inverse_chem = "PEsmaller" //At really impure vols, it just becomes 100% inverse and shrinks instead.
can_synth = FALSE
+ var/message_spam = FALSE
-/datum/reagent/fermi/penis_enlarger/on_mob_add(mob/living/carbon/M)
+/datum/reagent/fermi/penis_enlarger/on_mob_metabolize(mob/living/M)
. = ..()
if(!ishuman(M)) //Just monkeying around.
if(volume >= 15) //to prevent monkey penis farms
var/turf/T = get_turf(M)
var/obj/item/organ/genital/penis/P = new /obj/item/organ/genital/penis(T)
- var/list/seen = viewers(8, T)
- for(var/mob/S in seen)
- to_chat(S, "A penis suddenly flies out of the [M]! ")
+ M.visible_message("A penis suddenly flies out of the [M]! ")
var/T2 = get_random_station_turf()
M.adjustBruteLoss(25)
M.Knockdown(50)
@@ -233,104 +214,94 @@
M.reagents.remove_reagent(id, volume)
return
var/mob/living/carbon/human/H = M
- H.genital_override = TRUE
- var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
- if(!P)
- H.emergent_genital_call()
- return
- P.prev_length = P.length
- P.cached_length = P.length
+ if(!H.getorganslot(ORGAN_SLOT_PENIS) && H.emergent_genital_call())
+ H.genital_override = TRUE
/datum/reagent/fermi/penis_enlarger/on_mob_life(mob/living/carbon/M) //Increases penis size, 5u = +1 inch.
if(!ishuman(M))
- return
+ return ..()
var/mob/living/carbon/human/H = M
- var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
+ var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!P)//They do have a preponderance for escapism, or so I've heard.
//If they have Acute hepatic pharmacokinesis, then route processing though liver.
- if(HAS_TRAIT(M, TRAIT_PHARMA))
- var/obj/item/organ/liver/L = M.getorganslot("liver")
+ if(HAS_TRAIT(H, TRAIT_PHARMA) || !H.canbearoused)
+ var/obj/item/organ/liver/L = H.getorganslot(ORGAN_SLOT_LIVER)
if(L)
- L.swelling+= 0.05
- return..()
+ L.swelling += 0.05
else
- M.adjustToxLoss(1)
- return..()
+ H.adjustToxLoss(1)
+ return ..()
//otherwise proceed as normal
- var/obj/item/organ/genital/penis/nP = new
- nP.Insert(M)
- if(nP)
- nP.length = 1
- to_chat(M, "Your groin feels warm, as you feel a newly forming bulge down below. ")
- nP.cached_length = 1
- nP.prev_length = 1
- M.reagents.remove_reagent(id, 5)
- P = nP
+ P = new
+ P.length = 1
+ to_chat(H, "Your groin feels warm, as you feel a newly forming bulge down below. ")
+ P.prev_length = 1
+ H.reagents.remove_reagent(id, 5)
+ P.Insert(H)
- P.cached_length = P.cached_length + 0.1
- if (P.cached_length >= 20.5 && P.cached_length < 21)
- if(H.w_uniform || H.wear_suit)
- var/target = M.get_bodypart(BODY_ZONE_CHEST)
- to_chat(M, "Your cock begin to strain against your clothes tightly! ")
- M.apply_damage(2.5, BRUTE, target)
+ P.modify_size(0.1)
+ if (ISINRANGE_EX(P.length, 20.5, 21) && (H.w_uniform || H.wear_suit))
+ var/target = H.get_bodypart(BODY_ZONE_CHEST)
+ if(!message_spam)
+ to_chat(H, "Your cock begin to strain against your clothes tightly! ")
+ message_spam = TRUE
+ H.apply_damage(2.5, BRUTE, target)
- P.update()
- ..()
+ return ..()
-/datum/reagent/fermi/penis_enlarger/overdose_process(mob/living/carbon/M) //Turns you into a male if female and ODing, doesn't touch nonbinary and object genders.
+/datum/reagent/fermi/penis_enlarger/overdose_process(mob/living/carbon/human/M) //Turns you into a male if female and ODing, doesn't touch nonbinary and object genders.
+ if(!istype(M))
+ return ..()
//Acute hepatic pharmacokinesis.
- if(HAS_TRAIT(M, TRAIT_PHARMA))
- var/obj/item/organ/liver/L = M.getorganslot("liver")
+ if(HAS_TRAIT(M, TRAIT_PHARMA) || !M.canbearoused)
+ var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
L.swelling+= 0.05
return..()
- var/obj/item/organ/genital/breasts/B = M.getorganslot("breasts")
- var/obj/item/organ/genital/testicles/T = M.getorganslot("testicles")
- var/obj/item/organ/genital/vagina/V = M.getorganslot("vagina")
- var/obj/item/organ/genital/womb/W = M.getorganslot("womb")
+ var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS)
+ var/obj/item/organ/genital/testicles/T = M.getorganslot(ORGAN_SLOT_TESTICLES)
+ var/obj/item/organ/genital/vagina/V = M.getorganslot(ORGAN_SLOT_VAGINA)
+ var/obj/item/organ/genital/womb/W = M.getorganslot(ORGAN_SLOT_WOMB)
if(M.gender == FEMALE)
M.gender = MALE
M.visible_message("[M] suddenly looks more masculine! ", "You suddenly feel more masculine! ")
if(B)
- B.cached_size = B.cached_size - 0.05
- B.update()
- if(V)
- V.Remove(M)
+ B.modify_size(-0.05)
+ if(M.getorganslot(ORGAN_SLOT_VAGINA))
+ qdel(V)
if(W)
- W.Remove(M)
+ qdel(W)
if(!T)
- var/obj/item/organ/genital/testicles/nT = new
- nT.Insert(M)
- T = nT
- ..()
+ T = new
+ T.Insert(M)
+ return ..()
/datum/reagent/fermi/PEsmaller // Due to cozmo's request...!
name = "Chastity draft"
id = "PEsmaller"
- description = "A volatile collodial mixture derived from various masculine solutions that encourages a smaller gentleman's package via a potent testosterone mix, formula derived from a collaboration from Fermichem and Doctor Ronald Hyatt, who is well known for his phallus palace."
+ description = "A volatile collodial mixture derived from various masculine solutions that encourages a smaller gentleman's package via a potent testosterone mix. Produced by reacting impure Incubus draft."
color = "#888888" // This is greyish..?
taste_description = "chinese dragon powder"
metabolization_rate = 0.5
can_synth = FALSE
/datum/reagent/fermi/PEsmaller/on_mob_life(mob/living/carbon/M)
+ if(!ishuman(M))
+ return ..()
var/mob/living/carbon/human/H = M
- var/obj/item/organ/genital/penis/P = H.getorganslot("penis")
+ var/obj/item/organ/genital/penis/P = H.getorganslot(ORGAN_SLOT_PENIS)
if(!P)
//Acute hepatic pharmacokinesis.
if(HAS_TRAIT(M, TRAIT_PHARMA))
- var/obj/item/organ/liver/L = M.getorganslot("liver")
+ var/obj/item/organ/liver/L = M.getorganslot(ORGAN_SLOT_LIVER)
L.swelling-= 0.05
- return..()
-
- //otherwise proceed as normal
return..()
- P.cached_length = P.cached_length - 0.1
- P.update()
+
+ P.modify_size(-0.1)
..()
/datum/reagent/fermi/PEsmaller_hypo
@@ -342,24 +313,25 @@
metabolization_rate = 0.5
can_synth = TRUE
-/datum/reagent/fermi/PEsmaller_hypo/on_mob_add(mob/living/carbon/M)
+/datum/reagent/fermi/PEsmaller_hypo/on_mob_metabolize(mob/living/M)
. = ..()
- if(!M.getorganslot("testicles"))
- if(M.dna.features["has_balls"])
- var/obj/item/organ/genital/testicles/nT = new
- nT.Insert(M)
+ if(!ishuman(M))
+ return
+ var/mob/living/carbon/human/H = M
+ if(!H.getorganslot(ORGAN_SLOT_PENIS) && H.dna.features["has_cock"])
+ H.give_genital(/obj/item/organ/genital/penis)
+ if(!H.getorganslot(ORGAN_SLOT_TESTICLES) && H.dna.features["has_balls"])
+ H.give_genital(/obj/item/organ/genital/testicles)
/datum/reagent/fermi/PEsmaller_hypo/on_mob_life(mob/living/carbon/M)
- var/obj/item/organ/genital/penis/P = M.getorganslot("penis")
+ var/obj/item/organ/genital/penis/P = M.getorganslot(ORGAN_SLOT_PENIS)
if(!P)
return ..()
- if(!M.dna.features["has_cock"])//Fast fix for those who don't want it.
- P.cached_length = P.cached_length - 0.2
- P.update()
- else if(P.cached_length > (M.dna.features["cock_length"]+0.1))
- P.cached_length = P.cached_length - 0.1
- P.update()
- else if(P.cached_length < (M.dna.features["cock_length"]+0.1))
- P.cached_length = P.cached_length + 0.1
- P.update()
- ..()
+ var/optimal_size = M.dna.features["cock_length"]
+ if(!optimal_size)//Fast fix for those who don't want it.
+ P.modify_size(-0.2)
+ else if(P.length > optimal_size)
+ P.modify_size(-0.1, optimal_size)
+ else if(P.length < optimal_size)
+ P.modify_size(0.1, 0, optimal_size)
+ return ..()
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm
index 031b105468..edb4bedfed 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/fermi_reagents.dm
@@ -6,7 +6,10 @@
id = "fermi"
taste_description = "affection and love!"
can_synth = FALSE
- SplitChem = TRUE
+ //SplitChem = TRUE
+ impure_chem = "fermiTox"// What chemical is metabolised with an inpure reaction
+ inverse_chem_val = 0.25 // If the impurity is below 0.5, replace ALL of the chem with inverse_chemupon metabolising
+ inverse_chem = "fermiTox"
//This should process fermichems to find out how pure they are and what effect to do.
/datum/reagent/fermi/on_mob_add(mob/living/carbon/M, amount)
@@ -36,7 +39,7 @@
taste_description = "like jerky, whiskey and an off aftertaste of a crypt."
metabolization_rate = 0.2
overdose_threshold = 25
- DoNotSplit = TRUE
+ chemical_flags = REAGENT_DONOTSPLIT
pH = 4
can_synth = TRUE
@@ -81,9 +84,9 @@
color = "#f9b9bc" // rgb: , 0, 255
taste_description = "dewicious degenyewacy"
metabolization_rate = 0.5 * REAGENTS_METABOLISM
- InverseChemVal = 0
+ inverse_chem_val = 0
var/obj/item/organ/tongue/nT
- DoNotSplit = TRUE
+ chemical_flags = REAGENT_DONOTSPLIT
pH = 5
var/obj/item/organ/tongue/T
can_synth = TRUE
@@ -165,21 +168,21 @@
//Writen by Trilby!! Embellsished a little by me.
/datum/reagent/fermi/nanite_b_gone
- name = "Naninte bane"
+ name = "Nanite bane"
id = "nanite_b_gone"
description = "A stablised EMP that is highly volatile, shocking small nano machines that will kill them off at a rapid rate in a patient's system."
color = "#708f8f"
overdose_threshold = 15
- ImpureChem = "nanite_b_goneTox" //If you make an inpure chem, it stalls growth
- InverseChemVal = 0.25
- InverseChem = "nanite_b_goneTox" //At really impure vols, it just becomes 100% inverse
+ impure_chem = "nanite_b_goneTox" //If you make an inpure chem, it stalls growth
+ inverse_chem_val = 0.25
+ inverse_chem = "nanite_b_goneTox" //At really impure vols, it just becomes 100% inverse
taste_description = "what can only be described as licking a battery."
pH = 9
can_synth = FALSE
/datum/reagent/fermi/nanite_b_gone/on_mob_life(mob/living/carbon/C)
//var/component/nanites/N = M.GetComponent(/datum/component/nanites)
- GET_COMPONENT_FROM(N, /datum/component/nanites, C)
+ var/datum/component/nanites/N = C.GetComponent(/datum/component/nanites)
if(isnull(N))
return ..()
N.nanite_volume = -purity//0.5 seems to be the default to me, so it'll neuter them.
@@ -187,7 +190,7 @@
/datum/reagent/fermi/nanite_b_gone/overdose_process(mob/living/carbon/C)
//var/component/nanites/N = M.GetComponent(/datum/component/nanites)
- GET_COMPONENT_FROM(N, /datum/component/nanites, C)
+ var/datum/component/nanites/N = C.GetComponent(/datum/component/nanites)
if(prob(5))
to_chat(C, "The residual voltage from the nanites causes you to seize up! ")
C.electrocute_act(10, (get_turf(C)), 1, FALSE, FALSE, FALSE, TRUE)
@@ -195,7 +198,7 @@
//empulse((get_turf(C)), 3, 2)//So the nanites randomize
var/atom/T = C
T.emp_act(EMP_HEAVY)
- to_chat(C, "The nanites short circuit within your system! ")
+ to_chat(C, "You feel a strange tingling sensation come from your core. ")
if(isnull(N))
return ..()
N.nanite_volume = -2
@@ -205,10 +208,11 @@
O.emp_act(EMP_HEAVY)
/datum/reagent/fermi/nanite_b_goneTox
- name = "Naninte bain"
+ name = "Electromagnetic crystals"
id = "nanite_b_goneTox"
- description = "Poorly made, and shocks you!"
- metabolization_rate = 1
+ description = "Causes items upon the patient to sometimes short out, as well as causing a shock in the patient, if the residual charge between the crystals builds up to sufficient quantities"
+ metabolization_rate = 0.5
+ chemical_flags = REAGENT_INVISIBLE
//Increases shock events.
/datum/reagent/fermi/nanite_b_goneTox/on_mob_life(mob/living/carbon/C)//Damages the taker if their purity is low. Extended use of impure chemicals will make the original die. (thus can't be spammed unless you've very good)
@@ -246,8 +250,7 @@
if((method==VAPOR) && (!C.wear_mask))
if(prob(20))
to_chat(C, "You can feel your lungs burning! ")
- var/obj/item/organ/lungs/L = C.getorganslot(ORGAN_SLOT_LUNGS)
- L.adjustLungLoss(acidstr*2, C)
+ C.adjustOrganLoss(ORGAN_SLOT_LUNGS, acidstr*2)
C.apply_damage(acidstr/5, BURN, target)
C.acid_act(acidstr, volume)
..()
@@ -274,7 +277,7 @@
name = "Fermis Test Reagent"
id = "fermiTest"
description = "You should be really careful with this...! Also, how did you get this?"
- addProc = TRUE
+ chemical_flags = REAGENT_FORCEONNEW
can_synth = FALSE
/datum/reagent/fermi/fermiTest/on_new(datum/reagents/holder)
@@ -305,22 +308,6 @@
playsound(get_turf(M), 'modular_citadel/sound/voice/merowr.ogg', 50, 1)
holder.clear_reagents()
-/datum/reagent/fermi/fermiTox
- name = "FermiTox"
- id = "fermiTox"
- description = "You should be really careful with this...! Also, how did you get this? You shouldn't have this!"
- data = "merge"
- color = "FFFFFF"
- can_synth = FALSE
-
-//I'm concerned this is too weak, but I also don't want deathmixes.
-/datum/reagent/fermi/fermiTox/on_mob_life(mob/living/carbon/C, method)
- if(C.dna && istype(C.dna.species, /datum/species/jelly))
- C.adjustToxLoss(-2)
- else
- C.adjustToxLoss(2)
- ..()
-
/datum/reagent/fermi/acidic_buffer
name = "Acidic buffer"
id = "acidic_buffer"
@@ -335,7 +322,7 @@
return ..()
data = datapH
if(LAZYLEN(holder.reagent_list) == 1)
- return
+ return ..()
holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume))
var/list/seen = viewers(5, get_turf(holder))
for(var/mob/M in seen)
@@ -357,7 +344,7 @@
return ..()
data = datapH
if(LAZYLEN(holder.reagent_list) == 1)
- return
+ return ..()
holder.pH = ((holder.pH * holder.total_volume)+(pH * (volume)))/(holder.total_volume + (volume))
var/list/seen = viewers(5, get_turf(holder))
for(var/mob/M in seen)
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm
index b717948a20..4949cc6ecf 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm
@@ -6,9 +6,9 @@
color = "#68e83a"
pH = 8.6
overdose_threshold = 35
- ImpureChem = "yamerol_tox"
- InverseChemVal = 0.4
- InverseChem = "yamerol_tox"
+ impure_chem = "yamerol_tox"
+ inverse_chem_val = 0.4
+ inverse_chem = "yamerol_tox"
can_synth = TRUE
/datum/reagent/fermi/yamerol/on_mob_life(mob/living/carbon/C)
@@ -16,9 +16,9 @@
var/obj/item/organ/lungs/L = C.getorganslot(ORGAN_SLOT_LUNGS)
if(T)
- T.adjustTongueLoss(C, -2)//Fix the inputs me!
+ T.applyOrganDamage(-2)
if(L)
- L.adjustLungLoss(-5, C)
+ C.adjustOrganLoss(ORGAN_SLOT_LUNGS, -5)
C.adjustOxyLoss(-2)
else
C.adjustOxyLoss(-10)
@@ -65,31 +65,87 @@
holder.remove_reagent(src.id, "10")
if(!C.getorganslot(ORGAN_SLOT_LUNGS))
- var/obj/item/organ/lungs/L = new()
+ var/obj/item/organ/lungs/yamerol/L = new()
L.Insert(C)
- to_chat(C, "You feel your lungs reform in your chest. ")
+ to_chat(C, "You feel the yamerol merge in your chest. ")
holder.remove_reagent(src.id, "10")
C.adjustOxyLoss(-3)
..()
-/datum/reagent/fermi/yamerol_tox
- name = "Yamerol"
+/datum/reagent/impure/yamerol_tox
+ name = "Yamer oh no"
id = "yamerol_tox"
- description = "For when you've trouble speaking or breathing, just yell YAMEROL! A chem that helps soothe any congestion problems and at high concentrations restores damaged lungs and tongues!"
+ description = "A dangerous, cloying toxin that stucks to a patient’s respiratory system, damaging their tongue, lungs and causing suffocation."
taste_description = "a weird, syrupy flavour, yamero"
color = "#68e83a"
pH = 8.6
-/datum/reagent/fermi/yamerol_tox/on_mob_life(mob/living/carbon/C)
+/datum/reagent/impure/yamerol_tox/on_mob_life(mob/living/carbon/C)
var/obj/item/organ/tongue/T = C.getorganslot(ORGAN_SLOT_TONGUE)
var/obj/item/organ/lungs/L = C.getorganslot(ORGAN_SLOT_LUNGS)
if(T)
- T.adjustTongueLoss(C, 1)
+ T.applyOrganDamage(1)
if(L)
- L.adjustLungLoss(4, C)
+ C.adjustOrganLoss(ORGAN_SLOT_LUNGS, 4)
C.adjustOxyLoss(3)
else
C.adjustOxyLoss(10)
..()
+
+
+/datum/reagent/synthtissue
+ name = "Synthtissue"
+ id = "synthtissue"
+ description = "Synthetic tissue used for grafting onto damaged organs during surgery, or for treating limb damage. Has a very tight growth window between 305-320, any higher and the temperature will cause the cells to die. Additionally, growth time is considerably long, so chemists are encouraged to leave beakers with said reaction ongoing, while they tend to their other duties."
+ pH = 7.6
+ metabolization_rate = 0.05 //Give them time to graft
+ data = list("grown_volume" = 0, "injected_vol" = 0)
+
+/datum/reagent/synthtissue/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1)
+ if(iscarbon(M))
+ var/target = M.zone_selected
+ if (M.stat == DEAD)
+ show_message = 0
+ if(method in list(PATCH, TOUCH))
+ M.apply_damage(reac_volume*-1.5, BRUTE, target)
+ M.apply_damage(reac_volume*-1.5, BURN, target)
+ if(show_message)
+ to_chat(M, "You feel your [target] heal! It stings like hell! ")
+ SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "painful_medicine", /datum/mood_event/painful_medicine)
+ if(method==INJECT)
+ data["injected_vol"] = reac_volume
+ ..()
+
+/datum/reagent/synthtissue/on_mob_life(mob/living/carbon/C)
+ if(!iscarbon(C))
+ return ..()
+ if(data["injected_vol"] > 14)
+ if(data["grown_volume"] > 175) //I don't think this is even possible, but damn to I want to see if someone can (bare in mind it takes 2s to grow 0.05u)
+ if(volume >= 14)
+ if(C.regenerate_organs(only_one = TRUE))
+ C.reagents.remove_reagent(id, 15)
+ to_chat(C, "You feel something reform inside of you! ")
+
+ data["injected_vol"] -= metabolization_rate
+ ..()
+
+/datum/reagent/synthtissue/on_merge(passed_data)
+ if(!passed_data)
+ return ..()
+ if(passed_data["grown_volume"] > data["grown_volume"])
+ data["grown_volume"] = passed_data["grown_volume"]
+ if(iscarbon(holder.my_atom))
+ data["injected_vol"] = data["injected_vol"] + passed_data["injected_vol"]
+ passed_data["injected_vol"] = 0
+ ..()
+
+/datum/reagent/synthtissue/on_new(passed_data)
+ if(!passed_data)
+ return ..()
+ if(passed_data["grown_volume"] > data["grown_volume"])
+ data["grown_volume"] = passed_data["grown_volume"]
+ ..()
+
+//NEEDS ON_MOB_DEAD()
diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm
index 00063c22d4..c8ebde11d9 100644
--- a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm
@@ -1,11 +1,3 @@
-/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume)
- if(istype(O, /obj/effect/decal/cleanable) || istype(O, /obj/item/projectile/bullet/reusable/foam_dart) || istype(O, /obj/item/ammo_casing/caseless/foam_dart))
- qdel(O)
- else
- if(O)
- O.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
- SEND_SIGNAL(O, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD)
-
/datum/reagent/syndicateadrenals
name = "Syndicate Adrenaline"
id = "syndicateadrenals"
diff --git a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
index 367093ea6f..7fcae0eb13 100644
--- a/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
+++ b/modular_citadel/code/modules/reagents/chemistry/recipes/fermi.dm
@@ -2,15 +2,33 @@
mix_sound = 'sound/effects/bubbles.ogg'
//Called for every reaction step
-/datum/chemical_reaction/proc/FermiCreate(holder)
+/datum/chemical_reaction/proc/FermiCreate(datum/reagents/holder, added_volume, added_purity)
return
//Called when reaction STOP_PROCESSING
-/datum/chemical_reaction/proc/FermiFinish(datum/reagents/holder)
+/datum/chemical_reaction/proc/FermiFinish(datum/reagents/holder, var/atom/my_atom, reactVol)
+ if(clear_conversion == REACTION_CLEAR_IMPURE | REACTION_CLEAR_INVERSE)
+ for(var/id in results)
+ var/datum/reagent/R = my_atom.reagents.has_reagent("[id]")
+ if(R.purity == 1)
+ continue
+
+ var/cached_volume = R.volume
+ if(clear_conversion == REACTION_CLEAR_INVERSE && R.inverse_chem)
+ if(R.inverse_chem_val > R.purity)
+ my_atom.reagents.remove_reagent(R.id, cached_volume, FALSE)
+ my_atom.reagents.add_reagent(R.inverse_chem, cached_volume, FALSE, other_purity = 1)
+
+ else if (clear_conversion == REACTION_CLEAR_IMPURE && R.impure_chem)
+ var/impureVol = cached_volume * (1 - R.purity)
+ my_atom.reagents.remove_reagent(R.id, (impureVol), FALSE)
+ my_atom.reagents.add_reagent(R.impure_chem, impureVol, FALSE, other_purity = 1)
+ R.cached_purity = R.purity
+ R.purity = 1
return
//Called when temperature is above a certain threshold, or if purity is too low.
-/datum/chemical_reaction/proc/FermiExplode(datum/reagents, var/atom/my_atom, volume, temp, pH, Exploding = FALSE)
+/datum/chemical_reaction/proc/FermiExplode(datum/reagents/R0, var/atom/my_atom, volume, temp, pH, Exploding = FALSE)
if (Exploding == TRUE)
return
@@ -58,7 +76,7 @@
var/datum/effect_system/smoke_spread/chem/s = new()
R.my_atom = my_atom //Give the gas a fingerprint
- for (var/datum/reagent/reagent in my_atom.reagents.reagent_list) //make gas for reagents, has to be done this way, otherwise it never stops Exploding
+ for (var/datum/reagent/reagent in R0.reagent_list) //make gas for reagents, has to be done this way, otherwise it never stops Exploding
R.add_reagent(reagent.id, reagent.volume/3) //Seems fine? I think I fixed the infinite explosion bug.
if (reagent.purity < 0.6)
@@ -86,8 +104,8 @@
/datum/chemical_reaction/fermi/eigenstate
name = "Eigenstasium"
id = "eigenstate"
- results = list("eigenstate" = 0.1)
- required_reagents = list("bluespace" = 0.1, "stable_plasma" = 0.1, "sugar" = 0.1)
+ results = list("eigenstate" = 1)
+ required_reagents = list("bluespace" = 1, "stable_plasma" = 1, "sugar" = 1)
mix_message = "the reaction zaps suddenly!"
//FermiChem vars:
OptimalTempMin = 350 // Lower area of bell curve for determining heat based rate reactions
@@ -120,8 +138,8 @@
/datum/chemical_reaction/fermi/SDGF
name = "Synthetic-derived growth factor"
id = "SDGF"
- results = list("SDGF" = 0.3)
- required_reagents = list("stable_plasma" = 0.15, "clonexadone" = 0.15, "uranium" = 0.15, "synthflesh" = 0.15)
+ results = list("SDGF" = 3)
+ required_reagents = list("stable_plasma" = 1.5, "clonexadone" = 1.5, "uranium" = 1.5, "synthflesh" = 1.5)
mix_message = "the reaction gives off a blorble!"
required_temp = 1
//FermiChem vars:
@@ -161,8 +179,8 @@
/datum/chemical_reaction/fermi/breast_enlarger
name = "Sucubus milk"
id = "breast_enlarger"
- results = list("breast_enlarger" = 0.8)
- required_reagents = list("salglu_solution" = 0.1, "milk" = 0.1, "synthflesh" = 0.2, "silicon" = 0.3, "aphro" = 0.3)
+ results = list("breast_enlarger" = 8)
+ required_reagents = list("salglu_solution" = 1, "milk" = 1, "synthflesh" = 2, "silicon" = 3, "aphro" = 3)
mix_message = "the reaction gives off a mist of milk."
//FermiChem vars:
OptimalTempMin = 200
@@ -201,8 +219,8 @@
/datum/chemical_reaction/fermi/penis_enlarger
name = "Incubus draft"
id = "penis_enlarger"
- results = list("penis_enlarger" = 0.8)
- required_reagents = list("blood" = 0.5, "synthflesh" = 0.2, "carbon" = 0.2, "aphro" = 0.2, "salglu_solution" = 0.1,)
+ results = list("penis_enlarger" = 8)
+ required_reagents = list("blood" = 5, "synthflesh" = 2, "carbon" = 2, "aphro" = 2, "salglu_solution" = 1)
mix_message = "the reaction gives off a spicy mist."
//FermiChem vars:
OptimalTempMin = 200
@@ -240,8 +258,8 @@
/datum/chemical_reaction/fermi/astral
name = "Astrogen"
id = "astral"
- results = list("astral" = 0.5)
- required_reagents = list("eigenstate" = 0.1, "plasma" = 0.3, "synaptizine" = 0.1, "aluminium" = 0.5)
+ results = list("astral" = 5)
+ required_reagents = list("eigenstate" = 1, "plasma" = 3, "synaptizine" = 1, "aluminium" = 5)
//FermiChem vars:
OptimalTempMin = 700
OptimalTempMax = 800
@@ -263,10 +281,10 @@
/datum/chemical_reaction/fermi/enthrall/ //check this
name = "MKUltra"
id = "enthrall"
- results = list("enthrall" = 0.5)
+ results = list("enthrall" = 5)
//required_reagents = list("iron" = 1, "iodine" = 1) Test vars
- //required_reagents = list("cocoa" = 0.1, "astral" = 0.1, "mindbreaker" = 0.1, "psicodine" = 0.1, "happiness" = 0.1)
- required_reagents = list("cocoa" = 0.1, "bluespace" = 0.1, "mindbreaker" = 0.1, "psicodine" = 0.1, "happiness" = 0.1) //TEMPORARY UNTIL HEADMINS GIVE THE OKAY FOR MK USE.
+ //required_reagents = list("cocoa" = 1, "astral" = 1, "mindbreaker" = 1, "psicodine" = 1, "happiness" = 1)
+ required_reagents = list("cocoa" = 1, "bluespace" = 1, "mindbreaker" = 1, "psicodine" = 1, "happiness" = 1) //TEMPORARY UNTIL HEADMINS GIVE THE OKAY FOR MK USE.
required_catalysts = list("blood" = 1)
mix_message = "the reaction gives off a burgundy plume of smoke!"
//FermiChem vars:
@@ -309,10 +327,10 @@
//So slimes can play too.
/datum/chemical_reaction/fermi/enthrall/slime
- required_catalysts = list("slimejelly" = 1)
+ required_catalysts = list("jellyblood" = 1)
/datum/chemical_reaction/fermi/enthrall/slime/FermiFinish(datum/reagents/holder, var/atom/my_atom)
- var/datum/reagent/toxin/slimejelly/B = locate(/datum/reagent/toxin/slimejelly) in my_atom.reagents.reagent_list//The one line change.
+ var/datum/reagent/blood/jellyblood/B = locate(/datum/reagent/blood/jellyblood) in my_atom.reagents.reagent_list//The one line change.
var/datum/reagent/fermi/enthrall/E = locate(/datum/reagent/fermi/enthrall) in my_atom.reagents.reagent_list
if(!B.data)
var/list/seen = viewers(5, get_turf(my_atom))
@@ -342,8 +360,8 @@
/datum/chemical_reaction/fermi/hatmium // done
name = "Hat growth serum"
id = "hatmium"
- results = list("hatmium" = 0.5)
- required_reagents = list("ethanol" = 0.1, "nutriment" = 0.3, "cooking_oil" = 0.2, "iron" = 0.1, "gold" = 0.3)
+ results = list("hatmium" = 5)
+ required_reagents = list("ethanol" = 1, "nutriment" = 3, "cooking_oil" = 2, "iron" = 1, "gold" = 3)
//mix_message = ""
//FermiChem vars:
OptimalTempMin = 500
@@ -377,8 +395,8 @@
/datum/chemical_reaction/fermi/furranium
name = "Furranium"
id = "furranium"
- results = list("furranium" = 0.5)
- required_reagents = list("aphro" = 0.1, "moonsugar" = 0.1, "silver" = 0.2, "salglu_solution" = 0.1)
+ results = list("furranium" = 5)
+ required_reagents = list("aphro" = 1, "moonsugar" = 1, "silver" = 2, "salglu_solution" = 1)
mix_message = "You think you can hear a howl come from the beaker."
//FermiChem vars:
OptimalTempMin = 350
@@ -397,7 +415,7 @@
PurityMin = 0.3
/datum/chemical_reaction/fermi/furranium/organic
- required_reagents = list("aphro" = 0.1, "catnip" = 0.1, "silver" = 0.2, "salglu_solution" = 0.1)
+ required_reagents = list("aphro" = 1, "catnip" = 1, "silver" = 2, "salglu_solution" = 1)
//FOR INSTANT REACTIONS - DO NOT MULTIPLY LIMIT BY 10.
//There's a weird rounding error or something ugh.
@@ -428,14 +446,14 @@
/datum/chemical_reaction/fermi/acidic_buffer//done test
name = "Acetic acid buffer"
id = "acidic_buffer"
- results = list("acidic_buffer" = 2) //acetic acid
- required_reagents = list("salglu_solution" = 0.2, "ethanol" = 0.6, "oxygen" = 0.6, "water" = 0.6)
+ results = list("acidic_buffer" = 10) //acetic acid
+ required_reagents = list("salglu_solution" = 1, "ethanol" = 3, "oxygen" = 3, "water" = 3)
//FermiChem vars:
OptimalTempMin = 250
OptimalTempMax = 500
ExplodeTemp = 9999 //check to see overflow doesn't happen!
- OptimalpHMin = 2
- OptimalpHMax = 6
+ OptimalpHMin = 0
+ OptimalpHMax = 14
ReactpHLim = 0
//CatalystFact = 0 //To do 1
CurveSharpT = 4
@@ -455,15 +473,15 @@
/datum/chemical_reaction/fermi/basic_buffer//done test
name = "Ethyl Ethanoate buffer"
id = "basic_buffer"
- results = list("basic_buffer" = 1.5)
- required_reagents = list("acidic_buffer" = 0.5, "ethanol" = 0.5, "water" = 0.5)
+ results = list("basic_buffer" = 5)
+ required_reagents = list("lye" = 1, "ethanol" = 2, "water" = 2)
required_catalysts = list("sacid" = 1) //vagely acetic
- //FermiChem vars:x
+ //FermiChem vars:
OptimalTempMin = 250
OptimalTempMax = 500
ExplodeTemp = 9999 //check to see overflow doesn't happen!
- OptimalpHMin = 5
- OptimalpHMax = 12
+ OptimalpHMin = 0
+ OptimalpHMax = 14
ReactpHLim = 0
//CatalystFact = 0 //To do 1
CurveSharpT = 4
@@ -487,8 +505,8 @@
/datum/chemical_reaction/fermi/secretcatchem //DONE
name = "secretcatchem"
id = "secretcatchem"
- results = list("secretcatchem" = 0.5)
- required_reagents = list("stable_plasma" = 0.1, "sugar" = 0.1, "cream" = 0.1, "clonexadone" = 0.1)//Yes this will make a plushie if you don't lucky guess. It'll eat all your reagents too.
+ results = list("secretcatchem" = 5)
+ required_reagents = list("stable_plasma" = 1, "sugar" = 1, "cream" = 1, "clonexadone" = 1)//Yes this will make a plushie if you don't lucky guess. It'll eat all your reagents too.
required_catalysts = list("SDGF" = 1)
required_temp = 600
mix_message = "the reaction gives off a meow!"
@@ -521,7 +539,7 @@
RateUpLim += (rand(1, 1000)/100)
PurityMin += (rand(-1, 1)/10)
var/additions = list("aluminium", "silver", "gold", "plasma", "silicon", "uranium", "milk")
- required_reagents[pick(additions)] = rand(0.1, 0.5)//weird
+ required_reagents[pick(additions)] = rand(1, 5)//weird
/datum/chemical_reaction/fermi/secretcatchem/FermiFinish(datum/reagents/holder, var/atom/my_atom)
SSblackbox.record_feedback("tally", "catgirlium")//log
@@ -540,8 +558,8 @@
/datum/chemical_reaction/fermi/yamerol//done test
name = "Yamerol"
id = "yamerol"
- results = list("yamerol" = 1.5)
- required_reagents = list("perfluorodecalin" = 0.5, "salbutamol" = 0.5, "water" = 0.5)
+ results = list("yamerol" = 3)
+ required_reagents = list("perfluorodecalin" = 1, "salbutamol" = 1, "water" = 1)
//FermiChem vars:
OptimalTempMin = 300
OptimalTempMax = 500
diff --git a/modular_citadel/code/modules/reagents/objects/items.dm b/modular_citadel/code/modules/reagents/objects/items.dm
index 02f2db7c1e..6221bdde18 100644
--- a/modular_citadel/code/modules/reagents/objects/items.dm
+++ b/modular_citadel/code/modules/reagents/objects/items.dm
@@ -1,12 +1,12 @@
/obj/item/fermichem/pHbooklet
- name = "pH indicator booklet"
- desc = "A booklet containing paper soaked in universal indicator."
- icon_state = "pHbooklet"
- icon = 'modular_citadel/icons/obj/FermiChem.dmi'
- item_flags = NOBLUDGEON
- var/numberOfPages = 50
- resistance_flags = FLAMMABLE
- w_class = WEIGHT_CLASS_TINY
+ name = "pH indicator booklet"
+ desc = "A booklet containing paper soaked in universal indicator."
+ icon_state = "pHbooklet"
+ icon = 'icons/obj/chemical.dmi'
+ item_flags = NOBLUDGEON
+ var/numberOfPages = 50
+ resistance_flags = FLAMMABLE
+ w_class = WEIGHT_CLASS_TINY
//A little janky with pockets
/obj/item/fermichem/pHbooklet/attack_hand(mob/user)
@@ -29,7 +29,7 @@
to_chat(user, "[src] is empty! ")
add_fingerprint(user)
return
- . = ..()
+ . = ..()
if(. & COMPONENT_NO_INTERACT)
return
var/I = user.get_active_held_item()
@@ -37,86 +37,86 @@
user.put_in_active_hand(src)
/obj/item/fermichem/pHbooklet/MouseDrop()
- var/mob/living/user = usr
- if(numberOfPages >= 1)
- var/obj/item/fermichem/pHpaper/P = new /obj/item/fermichem/pHpaper
- P.add_fingerprint(user)
- P.forceMove(user)
- user.put_in_active_hand(P)
- to_chat(user, "You take [P] out of \the [src]. ")
- numberOfPages--
- playsound(user.loc, 'sound/items/poster_ripped.ogg', 50, 1)
- add_fingerprint(user)
- if(numberOfPages == 0)
- icon_state = "pHbookletEmpty"
- return
- else
- to_chat(user, "[src] is empty! ")
- add_fingerprint(user)
- return
- ..()
+ var/mob/living/user = usr
+ if(numberOfPages >= 1)
+ var/obj/item/fermichem/pHpaper/P = new /obj/item/fermichem/pHpaper
+ P.add_fingerprint(user)
+ P.forceMove(user)
+ user.put_in_active_hand(P)
+ to_chat(user, "You take [P] out of \the [src]. ")
+ numberOfPages--
+ playsound(user.loc, 'sound/items/poster_ripped.ogg', 50, 1)
+ add_fingerprint(user)
+ if(numberOfPages == 0)
+ icon_state = "pHbookletEmpty"
+ return
+ else
+ to_chat(user, "[src] is empty! ")
+ add_fingerprint(user)
+ return
+ ..()
/obj/item/fermichem/pHpaper
- name = "pH indicator strip"
- desc = "A piece of paper that will change colour depending on the pH of a solution."
- icon_state = "pHpaper"
- icon = 'modular_citadel/icons/obj/FermiChem.dmi'
- item_flags = NOBLUDGEON
- color = "#f5c352"
- var/used = FALSE
- resistance_flags = FLAMMABLE
- w_class = WEIGHT_CLASS_TINY
+ name = "pH indicator strip"
+ desc = "A piece of paper that will change colour depending on the pH of a solution."
+ icon_state = "pHpaper"
+ icon = 'icons/obj/chemical.dmi'
+ item_flags = NOBLUDGEON
+ color = "#f5c352"
+ var/used = FALSE
+ resistance_flags = FLAMMABLE
+ w_class = WEIGHT_CLASS_TINY
/obj/item/fermichem/pHpaper/afterattack(obj/item/reagent_containers/cont, mob/user, proximity)
- if(!istype(cont))
- return
- if(used == TRUE)
- to_chat(user, "[user] has already been used! ")
- return
- if(!LAZYLEN(cont.reagents.reagent_list))
- return
- switch(round(cont.reagents.pH, 1))
- if(14 to INFINITY)
- color = "#462c83"
- if(13 to 14)
- color = "#63459b"
- if(12 to 13)
- color = "#5a51a2"
- if(11 to 12)
- color = "#3853a4"
- if(10 to 11)
- color = "#3f93cf"
- if(9 to 10)
- color = "#0bb9b7"
- if(8 to 9)
- color = "#23b36e"
- if(7 to 8)
- color = "#3aa651"
- if(6 to 7)
- color = "#4cb849"
- if(5 to 6)
- color = "#b5d335"
- if(4 to 5)
- color = "#f7ec1e"
- if(3 to 4)
- color = "#fbc314"
- if(2 to 3)
- color = "#f26724"
- if(1 to 2)
- color = "#ef1d26"
- if(-INFINITY to 1)
- color = "#c6040c"
- desc += " The paper looks to be around a pH of [round(cont.reagents.pH, 1)]"
- used = TRUE
+ if(!istype(cont))
+ return
+ if(used == TRUE)
+ to_chat(user, "[user] has already been used! ")
+ return
+ if(!LAZYLEN(cont.reagents.reagent_list))
+ return
+ switch(round(cont.reagents.pH, 1))
+ if(14 to INFINITY)
+ color = "#462c83"
+ if(13 to 14)
+ color = "#63459b"
+ if(12 to 13)
+ color = "#5a51a2"
+ if(11 to 12)
+ color = "#3853a4"
+ if(10 to 11)
+ color = "#3f93cf"
+ if(9 to 10)
+ color = "#0bb9b7"
+ if(8 to 9)
+ color = "#23b36e"
+ if(7 to 8)
+ color = "#3aa651"
+ if(6 to 7)
+ color = "#4cb849"
+ if(5 to 6)
+ color = "#b5d335"
+ if(4 to 5)
+ color = "#f7ec1e"
+ if(3 to 4)
+ color = "#fbc314"
+ if(2 to 3)
+ color = "#f26724"
+ if(1 to 2)
+ color = "#ef1d26"
+ if(-INFINITY to 1)
+ color = "#c6040c"
+ desc += " The paper looks to be around a pH of [round(cont.reagents.pH, 1)]"
+ used = TRUE
/obj/item/fermichem/pHmeter
- name = "Chemistry Analyser"
- desc = "A a electrode attached to a small circuit box that will tell you the pH of a solution. The screen currently displays nothing."
- icon_state = "pHmeter"
- icon = 'modular_citadel/icons/obj/FermiChem.dmi'
- resistance_flags = FLAMMABLE
- w_class = WEIGHT_CLASS_TINY
- var/scanmode = 1
+ name = "Chemistry Analyser"
+ desc = "A a electrode attached to a small circuit box that will tell you the pH of a solution. The screen currently displays nothing."
+ icon_state = "pHmeter"
+ icon = 'icons/obj/chemical.dmi'
+ resistance_flags = FLAMMABLE
+ w_class = WEIGHT_CLASS_TINY
+ var/scanmode = 1
/obj/item/fermichem/pHmeter/attack_self(mob/user)
if(!scanmode)
@@ -127,21 +127,21 @@
scanmode = 0
/obj/item/fermichem/pHmeter/afterattack(atom/A, mob/user, proximity)
- . = ..()
- if(!istype(A, /obj/item/reagent_containers))
- return
- var/obj/item/reagent_containers/cont = A
- if(LAZYLEN(cont.reagents.reagent_list) == null)
- return
- var/out_message
- to_chat(user, "The chemistry meter beeps and displays: ")
- out_message += "Total volume: [round(cont.volume, 0.01)] Total pH: [round(cont.reagents.pH, 0.1)]\n"
- if(cont.reagents.fermiIsReacting)
- out_message += "A reaction appears to be occuring currently.\n"
- out_message += "Chemicals found in the beaker: \n"
- for(var/datum/reagent/R in cont.reagents.reagent_list)
- out_message += "[R.volume]u of [R.name] , Purity: [R.purity], [(scanmode?"[(R.overdose_threshold?"Overdose: [R.overdose_threshold]u, ":"")][(R.addiction_threshold?"Addiction: [R.addiction_threshold]u, ":"")]Base pH: [R.pH].":".")]\n"
- if(scanmode)
- out_message += "Analysis: [R.description]\n"
- to_chat(user, "[out_message] ")
- desc = "An electrode attached to a small circuit box that will analyse a beaker. It can be toggled to give a reduced or extended report. The screen currently displays [round(cont.reagents.pH, 0.1)]."
+ . = ..()
+ if(!istype(A, /obj/item/reagent_containers))
+ return
+ var/obj/item/reagent_containers/cont = A
+ if(LAZYLEN(cont.reagents.reagent_list) == null)
+ return
+ var/out_message
+ to_chat(user, "The chemistry meter beeps and displays: ")
+ out_message += "Total volume: [round(cont.volume, 0.01)] Total pH: [round(cont.reagents.pH, 0.1)]\n"
+ if(cont.reagents.fermiIsReacting)
+ out_message += "A reaction appears to be occuring currently.\n"
+ out_message += "Chemicals found in the beaker: \n"
+ for(var/datum/reagent/R in cont.reagents.reagent_list)
+ out_message += "[R.volume]u of [R.name] , Purity: [R.purity], [(scanmode?"[(R.overdose_threshold?"Overdose: [R.overdose_threshold]u, ":"")][(R.addiction_threshold?"Addiction: [R.addiction_threshold]u, ":"")]Base pH: [R.pH].":".")]\n"
+ if(scanmode)
+ out_message += "Analysis: [R.description]\n"
+ to_chat(user, "[out_message] ")
+ desc = "An electrode attached to a small circuit box that will analyse a beaker. It can be toggled to give a reduced or extended report. The screen currently displays [round(cont.reagents.pH, 0.1)]."
diff --git a/modular_citadel/code/modules/reagents/reagent container/cit_kegs.dm b/modular_citadel/code/modules/reagents/reagent container/cit_kegs.dm
deleted file mode 100644
index d40dba8a3f..0000000000
--- a/modular_citadel/code/modules/reagents/reagent container/cit_kegs.dm
+++ /dev/null
@@ -1,41 +0,0 @@
-/obj/structure/reagent_dispensers/keg
- name = "keg"
- desc = "A keg."
- icon = 'modular_citadel/icons/obj/objects.dmi'
- icon_state = "keg"
- reagent_id = "water"
-
-/obj/structure/reagent_dispensers/keg/mead
- name = "keg of mead"
- desc = "A keg of mead."
- icon_state = "orangekeg"
- reagent_id = "mead"
-
-/obj/structure/reagent_dispensers/keg/aphro
- name = "keg of aphrodisiac"
- desc = "A keg of aphrodisiac."
- icon_state = "pinkkeg"
- reagent_id = "aphro"
-
-/obj/structure/reagent_dispensers/keg/aphro/strong
- name = "keg of strong aphrodisiac"
- desc = "A keg of strong and addictive aphrodisiac."
- reagent_id = "aphro+"
-
-/obj/structure/reagent_dispensers/keg/milk
- name = "keg of milk"
- desc = "It's not quite what you were hoping for."
- icon_state = "whitekeg"
- reagent_id = "milk"
-
-/obj/structure/reagent_dispensers/keg/semen
- name = "keg of semen"
- desc = "Dear lord, where did this even come from?"
- icon_state = "whitekeg"
- reagent_id = "semen"
-
-/obj/structure/reagent_dispensers/keg/gargle
- name = "keg of pan galactic gargleblaster"
- desc = "A keg of... wow that's a long name."
- icon_state = "bluekeg"
- reagent_id = "gargleblaster"
\ No newline at end of file
diff --git a/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm b/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm
deleted file mode 100755
index 9e7da03f9b..0000000000
--- a/modular_citadel/code/modules/reagents/reagent container/hypospraymkii.dm
+++ /dev/null
@@ -1,296 +0,0 @@
-#define HYPO_SPRAY 0
-#define HYPO_INJECT 1
-
-#define WAIT_SPRAY 25
-#define WAIT_INJECT 25
-#define SELF_SPRAY 15
-#define SELF_INJECT 15
-
-#define DELUXE_WAIT_SPRAY 20
-#define DELUXE_WAIT_INJECT 20
-#define DELUXE_SELF_SPRAY 10
-#define DELUXE_SELF_INJECT 10
-
-#define COMBAT_WAIT_SPRAY 0
-#define COMBAT_WAIT_INJECT 0
-#define COMBAT_SELF_SPRAY 0
-#define COMBAT_SELF_INJECT 0
-
-//A vial-loaded hypospray. Cartridge-based!
-/obj/item/hypospray/mkii
- name = "hypospray mk.II"
- icon = 'modular_citadel/icons/obj/hypospraymkii.dmi'
- icon_state = "hypo2"
- desc = "A new development from DeForest Medical, this hypospray takes 30-unit vials as the drug supply for easy swapping."
- w_class = WEIGHT_CLASS_TINY
- var/list/allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/tiny, /obj/item/reagent_containers/glass/bottle/vial/small)
- var/mode = HYPO_INJECT
- var/obj/item/reagent_containers/glass/bottle/vial/vial
- var/start_vial = /obj/item/reagent_containers/glass/bottle/vial/small
- var/spawnwithvial = TRUE
- var/inject_wait = WAIT_INJECT
- var/spray_wait = WAIT_SPRAY
- var/spray_self = SELF_SPRAY
- var/inject_self = SELF_INJECT
- var/quickload = FALSE
- var/penetrates = FALSE
-
-/obj/item/hypospray/mkii/brute
- start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/bicaridine
-
-/obj/item/hypospray/mkii/toxin
- start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/antitoxin
-
-/obj/item/hypospray/mkii/oxygen
- start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/dexalin
-
-/obj/item/hypospray/mkii/burn
- start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/kelotane
-
-/obj/item/hypospray/mkii/tricord
- start_vial = /obj/item/reagent_containers/glass/bottle/vial/small/preloaded/tricord
-
-/obj/item/hypospray/mkii/enlarge
- spawnwithvial = FALSE
-
-/obj/item/hypospray/mkii/CMO
- name = "hypospray mk.II deluxe"
- allowed_containers = list(/obj/item/reagent_containers/glass/bottle/vial/tiny, /obj/item/reagent_containers/glass/bottle/vial/small, /obj/item/reagent_containers/glass/bottle/vial/large)
- icon_state = "cmo2"
- desc = "The Deluxe Hypospray can take larger-size vials. It also acts faster and delivers more reagents per spray."
- resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
- start_vial = /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/CMO
- inject_wait = DELUXE_WAIT_INJECT
- spray_wait = DELUXE_WAIT_SPRAY
- spray_self = DELUXE_SELF_SPRAY
- inject_self = DELUXE_SELF_INJECT
-
-/obj/item/hypospray/mkii/CMO/combat
- name = "combat hypospray mk.II"
- desc = "A combat-ready deluxe hypospray that acts almost instantly. It can be tactically reloaded by using a vial on it."
- icon_state = "combat2"
- start_vial = /obj/item/reagent_containers/glass/bottle/vial/large/preloaded/combat
- inject_wait = COMBAT_WAIT_INJECT
- spray_wait = COMBAT_WAIT_SPRAY
- spray_self = COMBAT_SELF_SPRAY
- inject_self = COMBAT_SELF_INJECT
- quickload = TRUE
- penetrates = TRUE
-
-/obj/item/hypospray/mkii/Initialize()
- . = ..()
- if(!spawnwithvial)
- update_icon()
- return
- if(start_vial)
- vial = new start_vial
- update_icon()
-
-/obj/item/hypospray/mkii/update_icon()
- ..()
- icon_state = "[initial(icon_state)][vial ? "" : "-e"]"
- if(ismob(loc))
- var/mob/M = loc
- M.update_inv_hands()
- return
-
-/obj/item/hypospray/mkii/examine(mob/user)
- . = ..()
- to_chat(user, "[vial] has [vial.reagents.total_volume]u remaining.")
- to_chat(user, "[src] is set to [mode ? "Inject" : "Spray"] contents on application.")
-
-/obj/item/hypospray/mkii/proc/unload_hypo(obj/item/I, mob/user)
- if((istype(I, /obj/item/reagent_containers/glass/bottle/vial)))
- var/obj/item/reagent_containers/glass/bottle/vial/V = I
- V.forceMove(user.loc)
- user.put_in_hands(V)
- to_chat(user, "You remove [vial] from [src]. ")
- vial = null
- update_icon()
- playsound(loc, 'sound/weapons/empty.ogg', 50, 1)
- else
- to_chat(user, "This hypo isn't loaded! ")
- return
-
-/obj/item/hypospray/mkii/attackby(obj/item/I, mob/living/user)
- if((istype(I, /obj/item/reagent_containers/glass/bottle/vial) && vial != null))
- if(!quickload)
- to_chat(user, "[src] can not hold more than one vial! ")
- return FALSE
- unload_hypo(vial, user)
- if((istype(I, /obj/item/reagent_containers/glass/bottle/vial)))
- var/obj/item/reagent_containers/glass/bottle/vial/V = I
- if(!is_type_in_list(V, allowed_containers))
- to_chat(user, "[src] doesn't accept this type of vial. ")
- return FALSE
- if(!user.transferItemToLoc(V,src))
- return FALSE
- vial = V
- user.visible_message("[user] has loaded a vial into [src]. ","You have loaded [vial] into [src]. ")
- update_icon()
- playsound(loc, 'sound/weapons/autoguninsert.ogg', 35, 1)
- return TRUE
- else
- to_chat(user, "This doesn't fit in [src]. ")
- return FALSE
- return FALSE
-
-/obj/item/hypospray/mkii/AltClick(mob/user)
- if(vial)
- vial.attack_self(user)
-
-// Gunna allow this for now, still really don't approve - Pooj
-/obj/item/hypospray/mkii/emag_act(mob/user)
- . = ..()
- if(obj_flags & EMAGGED)
- to_chat(user, "[src] happens to be already overcharged.")
- return
- inject_wait = COMBAT_WAIT_INJECT
- spray_wait = COMBAT_WAIT_SPRAY
- spray_self = COMBAT_SELF_INJECT
- inject_self = COMBAT_SELF_SPRAY
- penetrates = TRUE
- to_chat(user, "You overcharge [src]'s control circuit.")
- obj_flags |= EMAGGED
- return TRUE
-
-/obj/item/hypospray/mkii/attack_hand(mob/user)
- . = ..() //Don't bother changing this or removing it from containers will break.
-
-/obj/item/hypospray/mkii/attack(obj/item/I, mob/user, params)
- return
-
-/obj/item/hypospray/mkii/afterattack(atom/target, mob/user, proximity)
- if(!vial)
- return
-
- if(!proximity)
- return
-
- if(!ismob(target))
- return
-
- var/mob/living/L
- if(isliving(target))
- L = target
- if(!penetrates && !L.can_inject(user, 1)) //This check appears another four times, since otherwise the penetrating sprays will break in do_mob.
- return
-
- if(!L && !target.is_injectable()) //only checks on non-living mobs, due to how can_inject() handles
- to_chat(user, "You cannot directly fill [target]! ")
- return
-
- if(target.reagents.total_volume >= target.reagents.maximum_volume)
- to_chat(user, "[target] is full. ")
- return
-
- if(ishuman(L))
- var/obj/item/bodypart/affecting = L.get_bodypart(check_zone(user.zone_selected))
- if(!affecting)
- to_chat(user, "The limb is missing! ")
- return
- if(affecting.status != BODYPART_ORGANIC)
- to_chat(user, "Medicine won't work on a robotic limb! ")
- return
-
- var/contained = vial.reagents.log_list()
- log_combat(user, L, "attemped to inject", src, addition="which had [contained]")
-//Always log attemped injections for admins
- if(vial != null)
- switch(mode)
- if(HYPO_INJECT)
- if(L) //living mob
- if(L != user)
- L.visible_message("[user] is trying to inject [L] with [src]! ", \
- "[user] is trying to inject [L] with [src]! ")
- if(!do_mob(user, L, inject_wait))
- return
- if(!penetrates && !L.can_inject(user, 1))
- return
- if(!vial.reagents.total_volume)
- return
- if(L.reagents.total_volume >= L.reagents.maximum_volume)
- return
- L.visible_message("[user] uses the [src] on [L]! ", \
- "[user] uses the [src] on [L]! ")
- else
- if(!do_mob(user, L, inject_self))
- return
- if(!penetrates && !L.can_inject(user, 1))
- return
- if(!vial.reagents.total_volume)
- return
- if(L.reagents.total_volume >= L.reagents.maximum_volume)
- return
- log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode]) ")
- L.log_message("applied [src] to themselves ([contained]). ", INDIVIDUAL_ATTACK_LOG)
-
- var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1)
- vial.reagents.reaction(L, INJECT, fraction)
- vial.reagents.trans_to(target, vial.amount_per_transfer_from_this)
- if(vial.amount_per_transfer_from_this >= 15)
- playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1)
- if(vial.amount_per_transfer_from_this < 15)
- playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1)
- to_chat(user, "You inject [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units. ")
-
- if(HYPO_SPRAY)
- if(L) //living mob
- if(L != user)
- L.visible_message("[user] is trying to spray [L] with [src]! ", \
- "[user] is trying to spray [L] with [src]! ")
- if(!do_mob(user, L, spray_wait))
- return
- if(!penetrates && !L.can_inject(user, 1))
- return
- if(!vial.reagents.total_volume)
- return
- if(L.reagents.total_volume >= L.reagents.maximum_volume)
- return
- L.visible_message("[user] uses the [src] on [L]! ", \
- "[user] uses the [src] on [L]! ")
- else
- if(!do_mob(user, L, spray_self))
- return
- if(!penetrates && !L.can_inject(user, 1))
- return
- if(!vial.reagents.total_volume)
- return
- if(L.reagents.total_volume >= L.reagents.maximum_volume)
- return
- log_attack("[user.name] ([user.ckey]) applied [src] to [L.name] ([L.ckey]), which had [contained] (INTENT: [uppertext(user.a_intent)]) (MODE: [src.mode]) ")
- L.log_message("applied [src] to themselves ([contained]). ", INDIVIDUAL_ATTACK_LOG)
- var/fraction = min(vial.amount_per_transfer_from_this/vial.reagents.total_volume, 1)
- vial.reagents.reaction(L, PATCH, fraction)
- vial.reagents.trans_to(target, vial.amount_per_transfer_from_this)
- if(vial.amount_per_transfer_from_this >= 15)
- playsound(loc,'sound/items/hypospray_long.ogg',50, 1, -1)
- if(vial.amount_per_transfer_from_this < 15)
- playsound(loc, pick('sound/items/hypospray.ogg','sound/items/hypospray2.ogg'), 50, 1, -1)
- to_chat(user, "You spray [vial.amount_per_transfer_from_this] units of the solution. The hypospray's cartridge now contains [vial.reagents.total_volume] units. ")
- else
- to_chat(user, "[src] doesn't work here! ")
- return
-
-/obj/item/hypospray/mkii/attack_self(mob/living/user)
- if(user)
- if(user.incapacitated())
- return
- else if(!vial)
- to_chat(user, "This Hypo needs to be loaded first!")
- return
- else
- unload_hypo(vial,user)
-
-/obj/item/hypospray/mkii/verb/modes()
- set name = "Toggle Application Mode"
- set category = "Object"
- set src in usr
- var/mob/M = usr
- switch(mode)
- if(HYPO_SPRAY)
- mode = HYPO_INJECT
- to_chat(M, "[src] is now set to inject contents on application.")
- if(HYPO_INJECT)
- mode = HYPO_SPRAY
- to_chat(M, "[src] is now set to spray contents on application.")
diff --git a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm
index c4c1cff1e7..df3922dc09 100644
--- a/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm
+++ b/modular_citadel/code/modules/reagents/reagents/cit_reagents.dm
@@ -2,7 +2,7 @@
/datum/reagent/consumable/semen
name = "Semen"
id = "semen"
- description = "Sperm from some animal. Useless for anything but insemination, really."
+ description = "Sperm from some animal. I bet you'll drink this out of a bucket someday."
taste_description = "something salty"
taste_mult = 2 //Not very overpowering flavor
data = list("donor"=null,"viruses"=null,"donor_DNA"=null,"blood_type"=null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null)
@@ -39,7 +39,9 @@
add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/semen/replace_decal(obj/effect/decal/cleanable/semen/S)
- S.add_blood_DNA(return_blood_DNA())
+ if(S.blood_DNA)
+ blood_DNA |= S.blood_DNA.Copy()
+ ..()
/datum/reagent/consumable/femcum
name = "Female Ejaculate"
@@ -71,7 +73,8 @@
add_blood_DNA(list("Non-human DNA" = "A+"))
/obj/effect/decal/cleanable/femcum/replace_decal(obj/effect/decal/cleanable/femcum/F)
- F.add_blood_DNA(return_blood_DNA())
+ if(F.blood_DNA)
+ blood_DNA |= F.blood_DNA.Copy()
..()
/datum/reagent/consumable/femcum/reaction_turf(turf/T, reac_volume)
@@ -138,16 +141,16 @@
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage2(mob/living/M)
if(prob(30))
- M.adjustBrainLoss(2)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 2)
..()
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage3(mob/living/M)
if(prob(30))
- M.adjustBrainLoss(3)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 3)
..()
/datum/reagent/drug/aphrodisiacplus/addiction_act_stage4(mob/living/M)
if(prob(30))
- M.adjustBrainLoss(4)
+ M.adjustOrganLoss(ORGAN_SLOT_BRAIN, 4)
..()
/datum/reagent/drug/aphrodisiacplus/overdose_process(mob/living/M)
diff --git a/modular_citadel/code/modules/research/designs/machine_designs.dm b/modular_citadel/code/modules/research/designs/machine_designs.dm
deleted file mode 100644
index 6a1331dddc..0000000000
--- a/modular_citadel/code/modules/research/designs/machine_designs.dm
+++ /dev/null
@@ -1,6 +0,0 @@
-/datum/design/board/autoylathe
- name = "Machine Design (Autoylathe)"
- desc = "The circuit board for an autoylathe."
- id = "autoylathe"
- build_path = /obj/item/circuitboard/machine/autoylathe
- category = list("Misc. Machinery")
diff --git a/modular_citadel/code/modules/research/designs/weapon_designs.dm b/modular_citadel/code/modules/research/designs/weapon_designs.dm
deleted file mode 100644
index b27cedbcc2..0000000000
--- a/modular_citadel/code/modules/research/designs/weapon_designs.dm
+++ /dev/null
@@ -1,7 +0,0 @@
-/datum/design/mag_oldsmg/rubber_mag
- name = "WT-550 Semi-Auto SMG rubberbullets Magazine (4.6x30mm rubber)"
- desc = "A 20 round rubber shots magazine for the out of date security WT-550 Semi-Auto SMG"
- id = "mag_oldsmg_rubber"
- materials = list(MAT_METAL = 6000)
- build_path = /obj/item/ammo_box/magazine/wt550m9/wtrubber
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY
diff --git a/modular_citadel/code/modules/research/designs/weapon_designs/weapon_designs.dm b/modular_citadel/code/modules/research/designs/weapon_designs/weapon_designs.dm
deleted file mode 100644
index 6246b9e24e..0000000000
--- a/modular_citadel/code/modules/research/designs/weapon_designs/weapon_designs.dm
+++ /dev/null
@@ -1,7 +0,0 @@
-/datum/design/mag_oldsmg/tx_mag
- name = "WT-550 Semi-Auto SMG Uranium Magazine (4.6x30mm TX)"
- desc = "A 20 round uranium tipped magazine for the out of date security WT-550 Semi-Auto SMG."
- id = "mag_oldsmg_tx"
- materials = list(MAT_METAL = 6000, MAT_SILVER = 600, MAT_URANIUM = 2000)
- build_path = /obj/item/ammo_box/magazine/wt550m9/wttx
- departmental_flags = DEPARTMENTAL_FLAG_SECURITY
diff --git a/modular_citadel/code/modules/research/designs/xenobio_designs.dm b/modular_citadel/code/modules/research/designs/xenobio_designs.dm
deleted file mode 100644
index 45ed8e83a0..0000000000
--- a/modular_citadel/code/modules/research/designs/xenobio_designs.dm
+++ /dev/null
@@ -1,25 +0,0 @@
-/datum/design/xenobio_upgrade
- name = "owo"
- desc = "someone's bussin"
- build_type = PROTOLATHE
- materials = list(MAT_METAL = 300, MAT_GLASS = 100)
- category = list("Electronics")
- departmental_flags = DEPARTMENTAL_FLAG_SCIENCE
-
-/datum/design/xenobio_upgrade/xenobiomonkeys
- name = "Xenobiology console monkey upgrade disk"
- desc = "This disk will add the ability to remotely recycle monkeys via the Xenobiology console."
- id = "xenobio_monkeys"
- build_path = /obj/item/disk/xenobio_console_upgrade/monkey
-
-/datum/design/xenobio_upgrade/xenobioslimebasic
- name = "Xenobiology console basic slime upgrade disk"
- desc = "This disk will add the ability to remotely manipulate slimes via the Xenobiology console."
- id = "xenobio_slimebasic"
- build_path = /obj/item/disk/xenobio_console_upgrade/slimebasic
-
-/datum/design/xenobio_upgrade/xenobioslimeadv
- name = "Xenobiology console advanced slime upgrade disk"
- desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
- id = "xenobio_slimeadv"
- build_path = /obj/item/disk/xenobio_console_upgrade/slimeadv
diff --git a/modular_citadel/code/modules/research/techweb/_techweb.dm b/modular_citadel/code/modules/research/techweb/_techweb.dm
deleted file mode 100644
index 1c96229594..0000000000
--- a/modular_citadel/code/modules/research/techweb/_techweb.dm
+++ /dev/null
@@ -1,3 +0,0 @@
-/datum/techweb/specialized/autounlocking/autoylathe
- design_autounlock_buildtypes = AUTOYLATHE
- allowed_buildtypes = AUTOYLATHE
diff --git a/modular_citadel/code/modules/research/xenobiology/xenobio_camera.dm b/modular_citadel/code/modules/research/xenobiology/xenobio_camera.dm
deleted file mode 100644
index b700626a1d..0000000000
--- a/modular_citadel/code/modules/research/xenobiology/xenobio_camera.dm
+++ /dev/null
@@ -1,48 +0,0 @@
-/obj/machinery/computer/camera_advanced/xenobio
- max_slimes = 1
- var/upgradetier = 0
-
-/obj/machinery/computer/camera_advanced/xenobio/attackby(obj/item/O, mob/user, params)
- if(istype(O, /obj/item/disk/xenobio_console_upgrade))
- var/obj/item/disk/xenobio_console_upgrade/diskthing = O
- var/successfulupgrade = FALSE
- for(var/I in diskthing.upgradetypes)
- if(upgradetier & I)
- continue
- else
- upgradetier |= I
- successfulupgrade = TRUE
- if(I == XENOBIO_UPGRADE_SLIMEADV)
- max_slimes = 10
- if(successfulupgrade)
- to_chat(user, "You have successfully upgraded [src] with [O]. ")
- else
- to_chat(user, "[src] already has the contents of [O] installed! ")
- return
- . = ..()
-
-/obj/item/disk/xenobio_console_upgrade
- name = "Xenobiology console upgrade disk"
- desc = "Allan please add detail."
- icon_state = "datadisk5"
- var/list/upgradetypes = list()
-
-/obj/item/disk/xenobio_console_upgrade/admin
- name = "Xenobio all access thing"
- desc = "'the consoles are literally useless!!!!!!!!!!!!!!!'"
- upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV, XENOBIO_UPGRADE_MONKEYS)
-
-/obj/item/disk/xenobio_console_upgrade/monkey
- name = "Xenobiology console monkey upgrade disk"
- desc = "This disk will add the ability to remotely recycle monkeys via the Xenobiology console."
- upgradetypes = list(XENOBIO_UPGRADE_MONKEYS)
-
-/obj/item/disk/xenobio_console_upgrade/slimebasic
- name = "Xenobiology console basic slime upgrade disk"
- desc = "This disk will add the ability to remotely manipulate slimes via the Xenobiology console."
- upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC)
-
-/obj/item/disk/xenobio_console_upgrade/slimeadv
- name = "Xenobiology console advanced slime upgrade disk"
- desc = "This disk will add the ability to remotely feed slimes potions via the Xenobiology console, and lift the restrictions on the number of slimes that can be stored inside the Xenobiology console. This includes the contents of the basic slime upgrade disk."
- upgradetypes = list(XENOBIO_UPGRADE_SLIMEBASIC, XENOBIO_UPGRADE_SLIMEADV)
diff --git a/modular_citadel/code/modules/vehicles/secway.dm b/modular_citadel/code/modules/vehicles/secway.dm
deleted file mode 100644
index 85c1de15e2..0000000000
--- a/modular_citadel/code/modules/vehicles/secway.dm
+++ /dev/null
@@ -1,54 +0,0 @@
-/obj/vehicle/ridden/secway
- var/chargemax = 150
- var/chargerate = 0.35
- var/charge = 150
- var/chargespeed = 1
- var/normalspeed = 2
- var/last_tick = 0
- var/list/progressbars_by_rider = list()
-
-/obj/vehicle/ridden/secway/Initialize()
- . = ..()
- START_PROCESSING(SSfastprocess, src)
-
-/obj/vehicle/ridden/secway/process()
- var/diff = world.time - last_tick
- var/regen = chargerate * diff
- charge = CLAMP(charge + regen, 0, chargemax)
- last_tick = world.time
-
-/obj/vehicle/ridden/secway/relaymove(mob/user, direction)
- var/new_speed = normalspeed
- if(ishuman(user))
- var/mob/living/carbon/human/H = user
- if(H.sprinting && charge)
- charge--
- new_speed = chargespeed
- GET_COMPONENT(D, /datum/component/riding)
- D.vehicle_move_delay = new_speed
- for(var/i in progressbars_by_rider)
- var/datum/progressbar/B = progressbars_by_rider[i]
- B.update(charge)
- return ..()
-
-/obj/vehicle/ridden/secway/buckle_mob(mob/living/M, force, check_loc)
- . = ..(M, force, check_loc)
- if(.)
- if(progressbars_by_rider[M])
- qdel(progressbars_by_rider[M])
- var/datum/progressbar/D = new(M, chargemax, src)
- D.update(charge)
- progressbars_by_rider[M] = D
-
-/obj/vehicle/ridden/secway/unbuckle_mob(mob/living/M, force)
- . = ..(M, force)
- if(.)
- qdel(progressbars_by_rider[M])
- progressbars_by_rider -= M
-
-/obj/vehicle/ridden/secway/Destroy()
- for(var/i in progressbars_by_rider)
- qdel(progressbars_by_rider[i])
- progressbars_by_rider.Cut()
- STOP_PROCESSING(SSfastprocess, src)
- return ..()
\ No newline at end of file
diff --git a/modular_citadel/icons/aicards.dmi b/modular_citadel/icons/aicards.dmi
deleted file mode 100644
index 363a828fb7..0000000000
Binary files a/modular_citadel/icons/aicards.dmi and /dev/null differ
diff --git a/modular_citadel/icons/eutactic/item/hypereutactic.dmi b/modular_citadel/icons/eutactic/item/hypereutactic.dmi
deleted file mode 100644
index 90a665f676..0000000000
Binary files a/modular_citadel/icons/eutactic/item/hypereutactic.dmi and /dev/null differ
diff --git a/modular_citadel/icons/eutactic/item/noneutactic.dmi b/modular_citadel/icons/eutactic/item/noneutactic.dmi
deleted file mode 100644
index 9d8b9fd1dd..0000000000
Binary files a/modular_citadel/icons/eutactic/item/noneutactic.dmi and /dev/null differ
diff --git a/modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi b/modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi
deleted file mode 100644
index ca94055113..0000000000
Binary files a/modular_citadel/icons/eutactic/mob/hypereutactic_left.dmi and /dev/null differ
diff --git a/modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi b/modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi
deleted file mode 100644
index a9b90da740..0000000000
Binary files a/modular_citadel/icons/eutactic/mob/hypereutactic_right.dmi and /dev/null differ
diff --git a/modular_citadel/icons/eutactic/mob/noneutactic_left.dmi b/modular_citadel/icons/eutactic/mob/noneutactic_left.dmi
deleted file mode 100644
index a426597146..0000000000
Binary files a/modular_citadel/icons/eutactic/mob/noneutactic_left.dmi and /dev/null differ
diff --git a/modular_citadel/icons/eutactic/mob/noneutactic_right.dmi b/modular_citadel/icons/eutactic/mob/noneutactic_right.dmi
deleted file mode 100644
index aab77c5fd4..0000000000
Binary files a/modular_citadel/icons/eutactic/mob/noneutactic_right.dmi and /dev/null differ
diff --git a/modular_citadel/icons/firstaid.dmi b/modular_citadel/icons/firstaid.dmi
index 8c603c8762..d061adf9f2 100644
Binary files a/modular_citadel/icons/firstaid.dmi and b/modular_citadel/icons/firstaid.dmi differ
diff --git a/modular_citadel/icons/lavaknight/item/head.dmi b/modular_citadel/icons/lavaknight/item/head.dmi
deleted file mode 100644
index 950d4894e9..0000000000
Binary files a/modular_citadel/icons/lavaknight/item/head.dmi and /dev/null differ
diff --git a/modular_citadel/icons/lavaknight/item/suit.dmi b/modular_citadel/icons/lavaknight/item/suit.dmi
deleted file mode 100644
index 49cd14b666..0000000000
Binary files a/modular_citadel/icons/lavaknight/item/suit.dmi and /dev/null differ
diff --git a/modular_citadel/icons/lavaknight/mob/head.dmi b/modular_citadel/icons/lavaknight/mob/head.dmi
deleted file mode 100644
index 5084c9c66f..0000000000
Binary files a/modular_citadel/icons/lavaknight/mob/head.dmi and /dev/null differ
diff --git a/modular_citadel/icons/lavaknight/mob/suit.dmi b/modular_citadel/icons/lavaknight/mob/suit.dmi
deleted file mode 100644
index ed51ceaaa4..0000000000
Binary files a/modular_citadel/icons/lavaknight/mob/suit.dmi and /dev/null differ
diff --git a/modular_citadel/icons/mob/64x32_effects.dmi b/modular_citadel/icons/mob/64x32_effects.dmi
index 7db65a8fc3..a11b3584a3 100644
Binary files a/modular_citadel/icons/mob/64x32_effects.dmi and b/modular_citadel/icons/mob/64x32_effects.dmi differ
diff --git a/modular_citadel/icons/mob/BananaSpider.dmi b/modular_citadel/icons/mob/BananaSpider.dmi
deleted file mode 100644
index da65ef43fa..0000000000
Binary files a/modular_citadel/icons/mob/BananaSpider.dmi and /dev/null differ
diff --git a/modular_citadel/icons/mob/clothing/fed hats n modern.dmi b/modular_citadel/icons/mob/clothing/fed hats n modern.dmi
deleted file mode 100644
index ab8682b785..0000000000
Binary files a/modular_citadel/icons/mob/clothing/fed hats n modern.dmi and /dev/null differ
diff --git a/modular_citadel/icons/mob/clothing/fedcoats.dmi b/modular_citadel/icons/mob/clothing/fedcoats.dmi
deleted file mode 100644
index 6554b3a45d..0000000000
Binary files a/modular_citadel/icons/mob/clothing/fedcoats.dmi and /dev/null differ
diff --git a/modular_citadel/icons/mob/digishoes.dmi b/modular_citadel/icons/mob/digishoes.dmi
index b4e27d0b5d..a8e6c49423 100644
Binary files a/modular_citadel/icons/mob/digishoes.dmi and b/modular_citadel/icons/mob/digishoes.dmi differ
diff --git a/modular_citadel/icons/mob/kiwi.dmi b/modular_citadel/icons/mob/kiwi.dmi
deleted file mode 100644
index 18777f65cf..0000000000
Binary files a/modular_citadel/icons/mob/kiwi.dmi and /dev/null differ
diff --git a/modular_citadel/icons/mob/mam_ears.dmi b/modular_citadel/icons/mob/mam_ears.dmi
index a23716562e..fcc124c695 100644
Binary files a/modular_citadel/icons/mob/mam_ears.dmi and b/modular_citadel/icons/mob/mam_ears.dmi differ
diff --git a/modular_citadel/icons/mob/mam_markings.dmi b/modular_citadel/icons/mob/mam_markings.dmi
index dce56de556..af916d2fd0 100644
Binary files a/modular_citadel/icons/mob/mam_markings.dmi and b/modular_citadel/icons/mob/mam_markings.dmi differ
diff --git a/modular_citadel/icons/mob/mam_snouts.dmi b/modular_citadel/icons/mob/mam_snouts.dmi
index d2cb9b7286..d0f5d56314 100644
Binary files a/modular_citadel/icons/mob/mam_snouts.dmi and b/modular_citadel/icons/mob/mam_snouts.dmi differ
diff --git a/modular_citadel/icons/mob/mam_tails.dmi b/modular_citadel/icons/mob/mam_tails.dmi
index b16de1c0de..e4bd5119b6 100644
Binary files a/modular_citadel/icons/mob/mam_tails.dmi and b/modular_citadel/icons/mob/mam_tails.dmi differ
diff --git a/modular_citadel/icons/mob/markings_notmammals.dmi b/modular_citadel/icons/mob/markings_notmammals.dmi
index d9577698d1..79c97968ed 100644
Binary files a/modular_citadel/icons/mob/markings_notmammals.dmi and b/modular_citadel/icons/mob/markings_notmammals.dmi differ
diff --git a/modular_citadel/icons/mob/mutant_bodyparts.dmi b/modular_citadel/icons/mob/mutant_bodyparts.dmi
index 8c0856429b..a66895f864 100644
Binary files a/modular_citadel/icons/mob/mutant_bodyparts.dmi and b/modular_citadel/icons/mob/mutant_bodyparts.dmi differ
diff --git a/modular_citadel/icons/mob/taur_canine.dmi b/modular_citadel/icons/mob/taur_canine.dmi
index 0242d2e673..15d6214446 100644
Binary files a/modular_citadel/icons/mob/taur_canine.dmi and b/modular_citadel/icons/mob/taur_canine.dmi differ
diff --git a/modular_citadel/icons/mob/taur_hooved.dmi b/modular_citadel/icons/mob/taur_hooved.dmi
index e9860f2014..63e604b430 100644
Binary files a/modular_citadel/icons/mob/taur_hooved.dmi and b/modular_citadel/icons/mob/taur_hooved.dmi differ
diff --git a/modular_citadel/icons/mob/taur_naga.dmi b/modular_citadel/icons/mob/taur_naga.dmi
index 1ca4509db7..7214ec7073 100644
Binary files a/modular_citadel/icons/mob/taur_naga.dmi and b/modular_citadel/icons/mob/taur_naga.dmi differ
diff --git a/modular_citadel/icons/mob/uniform_digi.dmi b/modular_citadel/icons/mob/uniform_digi.dmi
index aea900d110..3f1335153e 100644
Binary files a/modular_citadel/icons/mob/uniform_digi.dmi and b/modular_citadel/icons/mob/uniform_digi.dmi differ
diff --git a/modular_citadel/icons/obj/FermiChem.dmi b/modular_citadel/icons/obj/FermiChem.dmi
deleted file mode 100644
index de7a86d574..0000000000
Binary files a/modular_citadel/icons/obj/FermiChem.dmi and /dev/null differ
diff --git a/modular_citadel/icons/obj/aicards.dmi b/modular_citadel/icons/obj/aicards.dmi
deleted file mode 100644
index f956a6e88d..0000000000
Binary files a/modular_citadel/icons/obj/aicards.dmi and /dev/null differ
diff --git a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi
index ed3286615b..570acbf4cf 100644
Binary files a/modular_citadel/icons/obj/clothing/trek_item_icon.dmi and b/modular_citadel/icons/obj/clothing/trek_item_icon.dmi differ
diff --git a/modular_citadel/icons/obj/genitals/hud.dmi b/modular_citadel/icons/obj/genitals/hud.dmi
index bf2adcb1fc..f8c8643fe0 100644
Binary files a/modular_citadel/icons/obj/genitals/hud.dmi and b/modular_citadel/icons/obj/genitals/hud.dmi differ
diff --git a/modular_citadel/icons/obj/genitals/testicles_onmob.dmi b/modular_citadel/icons/obj/genitals/testicles_onmob.dmi
index 33659cf13c..65eb24268f 100644
Binary files a/modular_citadel/icons/obj/genitals/testicles_onmob.dmi and b/modular_citadel/icons/obj/genitals/testicles_onmob.dmi differ
diff --git a/modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi b/modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi
deleted file mode 100644
index 9a902e0dff..0000000000
Binary files a/modular_citadel/icons/obj/guns/OVERRIDE_energy.dmi and /dev/null differ
diff --git a/modular_citadel/icons/obj/guns/energy.dmi b/modular_citadel/icons/obj/guns/energy.dmi
new file mode 100644
index 0000000000..482ec04d94
Binary files /dev/null and b/modular_citadel/icons/obj/guns/energy.dmi differ
diff --git a/modular_citadel/icons/obj/hypospraymkii.dmi b/modular_citadel/icons/obj/hypospraymkii.dmi
deleted file mode 100755
index 3f32219d84..0000000000
Binary files a/modular_citadel/icons/obj/hypospraymkii.dmi and /dev/null differ
diff --git a/modular_citadel/icons/obj/id.dmi b/modular_citadel/icons/obj/id.dmi
deleted file mode 100644
index 653542e93d..0000000000
Binary files a/modular_citadel/icons/obj/id.dmi and /dev/null differ
diff --git a/modular_citadel/icons/obj/modularpills.dmi b/modular_citadel/icons/obj/modularpills.dmi
deleted file mode 100644
index 78095d82c0..0000000000
Binary files a/modular_citadel/icons/obj/modularpills.dmi and /dev/null differ
diff --git a/modular_citadel/icons/obj/vial.dmi b/modular_citadel/icons/obj/vial.dmi
deleted file mode 100755
index 8d1fefe470..0000000000
Binary files a/modular_citadel/icons/obj/vial.dmi and /dev/null differ
diff --git a/modular_citadel/interface/skin.dmf b/modular_citadel/interface/skin.dmf
index c5b5138609..025a53bdca 100644
--- a/modular_citadel/interface/skin.dmf
+++ b/modular_citadel/interface/skin.dmf
@@ -54,7 +54,7 @@ window "mainwindow"
size = 640x440
anchor1 = none
anchor2 = none
- background-color = #eeeeee
+ background-color = #242424
is-default = true
saved-params = "pos;size;is-minimized;is-maximized"
icon = 'icons\\ss13_64.png'
@@ -66,7 +66,7 @@ window "mainwindow"
size = 637x440
anchor1 = 0,0
anchor2 = 100,100
- background-color = #eeeeee
+ background-color = #272727
saved-params = "splitter"
left = "mapwindow"
right = "infowindow"
@@ -78,7 +78,7 @@ window "mainwindow"
size = 200x200
anchor1 = none
anchor2 = none
- background-color = #ffffff
+ background-color = #272727
is-visible = false
saved-params = ""
elem "tooltip"
@@ -87,7 +87,7 @@ window "mainwindow"
size = 999x999
anchor1 = none
anchor2 = none
- background-color = #ffffff
+ background-color = #272727
is-visible = false
saved-params = ""
@@ -119,7 +119,7 @@ window "infowindow"
size = 640x480
anchor1 = none
anchor2 = none
- background-color = #eeeeee
+ background-color = #242424
saved-params = "pos;size;is-minimized;is-maximized"
is-pane = true
elem "info"
@@ -128,6 +128,7 @@ window "infowindow"
size = 640x445
anchor1 = 0,0
anchor2 = 100,100
+ background-color = #272727
saved-params = "splitter"
left = "statwindow"
right = "outputwindow"
@@ -138,7 +139,8 @@ window "infowindow"
size = 104x20
anchor1 = 3,0
anchor2 = 19,0
- background-color = #90b3dd
+ text-color = #e0e0e0
+ background-color = #40628a
saved-params = "is-checked"
text = "Changelog"
command = "changelog"
@@ -148,7 +150,8 @@ window "infowindow"
size = 100x20
anchor1 = 19,0
anchor2 = 34,0
- background-color = #90b3dd
+ text-color = #e0e0e0
+ background-color = #40628a
saved-params = "is-checked"
text = "Rules"
command = "rules"
@@ -158,7 +161,8 @@ window "infowindow"
size = 100x20
anchor1 = 34,0
anchor2 = 50,0
- background-color = #90b3dd
+ text-color = #e0e0e0
+ background-color = #40628a
saved-params = "is-checked"
text = "Wiki"
command = "wiki"
@@ -168,7 +172,8 @@ window "infowindow"
size = 100x20
anchor1 = 50,0
anchor2 = 66,0
- background-color = #90b3dd
+ text-color = #e0e0e0
+ background-color = #40628a
saved-params = "is-checked"
text = "Forum"
command = "forum"
@@ -178,7 +183,8 @@ window "infowindow"
size = 100x20
anchor1 = 66,0
anchor2 = 81,0
- background-color = #90b3dd
+ text-color = #e0e0e0
+ background-color = #40628a
saved-params = "is-checked"
text = "GitHub"
command = "github"
@@ -189,7 +195,8 @@ window "infowindow"
anchor1 = 81,0
anchor2 = 97,0
font-size = 8
- background-color = #ef7f7f
+ text-color = #e0e0e0
+ background-color = #A92c2c
saved-params = "is-checked"
text = "Report Issue"
command = "report-issue"
@@ -201,7 +208,7 @@ window "outputwindow"
size = 640x480
anchor1 = none
anchor2 = none
- background-color = #eeeeee
+ background-color = #272727
saved-params = "pos;size;is-minimized;is-maximized"
titlebar = false
statusbar = false
@@ -225,7 +232,8 @@ window "outputwindow"
size = 37x20
anchor1 = 100,100
anchor2 = none
- background-color = #eeeeee
+ text-color = #e0e0e0
+ background-color = #272727
saved-params = "is-checked"
text = "Chat"
command = ".winset \"say.is-checked=true ? input.command=\"!say \\\"\" : input.command=\""
@@ -237,7 +245,7 @@ window "outputwindow"
size = 640x456
anchor1 = 0,0
anchor2 = 100,100
- background-color = #ffffff
+ background-color = #272727
is-visible = false
is-disabled = true
saved-params = ""
@@ -248,6 +256,8 @@ window "outputwindow"
size = 640x456
anchor1 = 0,0
anchor2 = 100,100
+ text-color = #e0e0e0
+ background-color = #272727
is-default = true
saved-params = ""
@@ -258,7 +268,7 @@ window "statwindow"
size = 640x480
anchor1 = none
anchor2 = none
- background-color = #eeeeee
+ background-color = #242424
saved-params = "pos;size;is-minimized;is-maximized"
is-pane = true
elem "stat"
@@ -267,9 +277,14 @@ window "statwindow"
size = 640x480
anchor1 = 0,0
anchor2 = 100,100
+ text-color = #e0e0e0
+ background-color = #272727
is-default = true
saved-params = ""
- tab-background-color = #eeeeee
+ tab-text-color = #e0e0e0
+ tab-background-color = #242424
+ prefix-color = #e0e0e0
+ suffix-color = #e0e0e0
window "preferences_window"
elem "preferences_window"
diff --git a/sound/ambience/servicebell.ogg b/sound/ambience/servicebell.ogg
new file mode 100644
index 0000000000..f55c7d5a75
Binary files /dev/null and b/sound/ambience/servicebell.ogg differ
diff --git a/sound/AI/aimalf.ogg b/sound/announcer/classic/aimalf.ogg
similarity index 100%
rename from sound/AI/aimalf.ogg
rename to sound/announcer/classic/aimalf.ogg
diff --git a/sound/AI/aliens.ogg b/sound/announcer/classic/aliens.ogg
similarity index 100%
rename from sound/AI/aliens.ogg
rename to sound/announcer/classic/aliens.ogg
diff --git a/sound/AI/animes.ogg b/sound/announcer/classic/animes.ogg
similarity index 100%
rename from sound/AI/animes.ogg
rename to sound/announcer/classic/animes.ogg
diff --git a/sound/AI/attention.ogg b/sound/announcer/classic/attention.ogg
similarity index 100%
rename from sound/AI/attention.ogg
rename to sound/announcer/classic/attention.ogg
diff --git a/sound/AI/commandreport.ogg b/sound/announcer/classic/commandreport.ogg
similarity index 100%
rename from sound/AI/commandreport.ogg
rename to sound/announcer/classic/commandreport.ogg
diff --git a/sound/AI/granomalies.ogg b/sound/announcer/classic/granomalies.ogg
similarity index 100%
rename from sound/AI/granomalies.ogg
rename to sound/announcer/classic/granomalies.ogg
diff --git a/sound/AI/intercept.ogg b/sound/announcer/classic/intercept.ogg
similarity index 100%
rename from sound/AI/intercept.ogg
rename to sound/announcer/classic/intercept.ogg
diff --git a/sound/AI/ionstorm.ogg b/sound/announcer/classic/ionstorm.ogg
similarity index 100%
rename from sound/AI/ionstorm.ogg
rename to sound/announcer/classic/ionstorm.ogg
diff --git a/sound/AI/meteors.ogg b/sound/announcer/classic/meteors.ogg
similarity index 100%
rename from sound/AI/meteors.ogg
rename to sound/announcer/classic/meteors.ogg
diff --git a/sound/AI/newAI.ogg b/sound/announcer/classic/newAI.ogg
similarity index 100%
rename from sound/AI/newAI.ogg
rename to sound/announcer/classic/newAI.ogg
diff --git a/sound/AI/outbreak5.ogg b/sound/announcer/classic/outbreak5.ogg
similarity index 100%
rename from sound/AI/outbreak5.ogg
rename to sound/announcer/classic/outbreak5.ogg
diff --git a/sound/AI/outbreak7.ogg b/sound/announcer/classic/outbreak7.ogg
similarity index 100%
rename from sound/AI/outbreak7.ogg
rename to sound/announcer/classic/outbreak7.ogg
diff --git a/sound/AI/poweroff.ogg b/sound/announcer/classic/poweroff.ogg
similarity index 100%
rename from sound/AI/poweroff.ogg
rename to sound/announcer/classic/poweroff.ogg
diff --git a/sound/AI/poweron.ogg b/sound/announcer/classic/poweron.ogg
similarity index 100%
rename from sound/AI/poweron.ogg
rename to sound/announcer/classic/poweron.ogg
diff --git a/sound/AI/radiation.ogg b/sound/announcer/classic/radiation.ogg
similarity index 100%
rename from sound/AI/radiation.ogg
rename to sound/announcer/classic/radiation.ogg
diff --git a/sound/AI/shuttlecalled.ogg b/sound/announcer/classic/shuttlecalled.ogg
similarity index 100%
rename from sound/AI/shuttlecalled.ogg
rename to sound/announcer/classic/shuttlecalled.ogg
diff --git a/sound/AI/shuttledock.ogg b/sound/announcer/classic/shuttledock.ogg
similarity index 100%
rename from sound/AI/shuttledock.ogg
rename to sound/announcer/classic/shuttledock.ogg
diff --git a/sound/AI/shuttlerecalled.ogg b/sound/announcer/classic/shuttlerecalled.ogg
similarity index 100%
rename from sound/AI/shuttlerecalled.ogg
rename to sound/announcer/classic/shuttlerecalled.ogg
diff --git a/sound/AI/spanomalies.ogg b/sound/announcer/classic/spanomalies.ogg
similarity index 100%
rename from sound/AI/spanomalies.ogg
rename to sound/announcer/classic/spanomalies.ogg
diff --git a/sound/AI/welcome.ogg b/sound/announcer/classic/welcome.ogg
similarity index 100%
rename from sound/AI/welcome.ogg
rename to sound/announcer/classic/welcome.ogg
diff --git a/sound/announcer/medibot/aliens.ogg b/sound/announcer/medibot/aliens.ogg
new file mode 100644
index 0000000000..57fa70c3ca
Binary files /dev/null and b/sound/announcer/medibot/aliens.ogg differ
diff --git a/sound/announcer/medibot/animes.ogg b/sound/announcer/medibot/animes.ogg
new file mode 100644
index 0000000000..7615a744a6
Binary files /dev/null and b/sound/announcer/medibot/animes.ogg differ
diff --git a/sound/announcer/medibot/attention.ogg b/sound/announcer/medibot/attention.ogg
new file mode 100644
index 0000000000..d4d5a27085
Binary files /dev/null and b/sound/announcer/medibot/attention.ogg differ
diff --git a/sound/announcer/medibot/commandreport.ogg b/sound/announcer/medibot/commandreport.ogg
new file mode 100644
index 0000000000..4e5c2e1d1f
Binary files /dev/null and b/sound/announcer/medibot/commandreport.ogg differ
diff --git a/sound/announcer/medibot/granomalies.ogg b/sound/announcer/medibot/granomalies.ogg
new file mode 100644
index 0000000000..2713a3cb19
Binary files /dev/null and b/sound/announcer/medibot/granomalies.ogg differ
diff --git a/sound/announcer/medibot/intercept.ogg b/sound/announcer/medibot/intercept.ogg
new file mode 100644
index 0000000000..c59d0455c1
Binary files /dev/null and b/sound/announcer/medibot/intercept.ogg differ
diff --git a/sound/announcer/medibot/ionstorm.ogg b/sound/announcer/medibot/ionstorm.ogg
new file mode 100644
index 0000000000..15aeac9f7f
Binary files /dev/null and b/sound/announcer/medibot/ionstorm.ogg differ
diff --git a/sound/announcer/medibot/meteors.ogg b/sound/announcer/medibot/meteors.ogg
new file mode 100644
index 0000000000..91208cae12
Binary files /dev/null and b/sound/announcer/medibot/meteors.ogg differ
diff --git a/sound/announcer/medibot/newAI.ogg b/sound/announcer/medibot/newAI.ogg
new file mode 100644
index 0000000000..c40b099020
Binary files /dev/null and b/sound/announcer/medibot/newAI.ogg differ
diff --git a/sound/announcer/medibot/outbreak5.ogg b/sound/announcer/medibot/outbreak5.ogg
new file mode 100644
index 0000000000..7118af4449
Binary files /dev/null and b/sound/announcer/medibot/outbreak5.ogg differ
diff --git a/sound/announcer/medibot/outbreak7.ogg b/sound/announcer/medibot/outbreak7.ogg
new file mode 100644
index 0000000000..1fc542534d
Binary files /dev/null and b/sound/announcer/medibot/outbreak7.ogg differ
diff --git a/sound/announcer/medibot/poweroff.ogg b/sound/announcer/medibot/poweroff.ogg
new file mode 100644
index 0000000000..875df35002
Binary files /dev/null and b/sound/announcer/medibot/poweroff.ogg differ
diff --git a/sound/announcer/medibot/poweron.ogg b/sound/announcer/medibot/poweron.ogg
new file mode 100644
index 0000000000..4b1605b1c7
Binary files /dev/null and b/sound/announcer/medibot/poweron.ogg differ
diff --git a/sound/announcer/medibot/radiation.ogg b/sound/announcer/medibot/radiation.ogg
new file mode 100644
index 0000000000..5c48830b5f
Binary files /dev/null and b/sound/announcer/medibot/radiation.ogg differ
diff --git a/sound/announcer/medibot/shuttlecalled.ogg b/sound/announcer/medibot/shuttlecalled.ogg
new file mode 100644
index 0000000000..a775567abe
Binary files /dev/null and b/sound/announcer/medibot/shuttlecalled.ogg differ
diff --git a/sound/announcer/medibot/shuttledocked.ogg b/sound/announcer/medibot/shuttledocked.ogg
new file mode 100644
index 0000000000..933928db06
Binary files /dev/null and b/sound/announcer/medibot/shuttledocked.ogg differ
diff --git a/sound/announcer/medibot/shuttlerecalled.ogg b/sound/announcer/medibot/shuttlerecalled.ogg
new file mode 100644
index 0000000000..53b622576d
Binary files /dev/null and b/sound/announcer/medibot/shuttlerecalled.ogg differ
diff --git a/sound/announcer/medibot/spanomalies.ogg b/sound/announcer/medibot/spanomalies.ogg
new file mode 100644
index 0000000000..d710999e1e
Binary files /dev/null and b/sound/announcer/medibot/spanomalies.ogg differ
diff --git a/sound/announcer/medibot/welcome.ogg b/sound/announcer/medibot/welcome.ogg
new file mode 100644
index 0000000000..f9a698fd08
Binary files /dev/null and b/sound/announcer/medibot/welcome.ogg differ
diff --git a/sound/creatures/goose1.ogg b/sound/creatures/goose1.ogg
new file mode 100644
index 0000000000..3d605ad622
Binary files /dev/null and b/sound/creatures/goose1.ogg differ
diff --git a/sound/creatures/goose2.ogg b/sound/creatures/goose2.ogg
new file mode 100644
index 0000000000..735faba791
Binary files /dev/null and b/sound/creatures/goose2.ogg differ
diff --git a/sound/creatures/goose3.ogg b/sound/creatures/goose3.ogg
new file mode 100644
index 0000000000..1aeec77369
Binary files /dev/null and b/sound/creatures/goose3.ogg differ
diff --git a/sound/creatures/goose4.ogg b/sound/creatures/goose4.ogg
new file mode 100644
index 0000000000..699f143bd3
Binary files /dev/null and b/sound/creatures/goose4.ogg differ
diff --git a/sound/AI/harmalarm.ogg b/sound/effects/harmalarm.ogg
similarity index 100%
rename from sound/AI/harmalarm.ogg
rename to sound/effects/harmalarm.ogg
diff --git a/sound/effects/k9_jaw_strong.ogg b/sound/effects/k9_jaw_strong.ogg
new file mode 100644
index 0000000000..9f60050b95
Binary files /dev/null and b/sound/effects/k9_jaw_strong.ogg differ
diff --git a/sound/effects/k9_jaw_weak.ogg b/sound/effects/k9_jaw_weak.ogg
new file mode 100644
index 0000000000..3ef2272f01
Binary files /dev/null and b/sound/effects/k9_jaw_weak.ogg differ
diff --git a/modular_citadel/sound/misc/adrenalinject.ogg b/sound/misc/adrenalinject.ogg
similarity index 100%
rename from modular_citadel/sound/misc/adrenalinject.ogg
rename to sound/misc/adrenalinject.ogg
diff --git a/modular_citadel/sound/misc/souldeath.ogg b/sound/misc/souldeath.ogg
similarity index 100%
rename from modular_citadel/sound/misc/souldeath.ogg
rename to sound/misc/souldeath.ogg
diff --git a/modular_citadel/sound/misc/sprintactivate.ogg b/sound/misc/sprintactivate.ogg
similarity index 100%
rename from modular_citadel/sound/misc/sprintactivate.ogg
rename to sound/misc/sprintactivate.ogg
diff --git a/modular_citadel/sound/misc/sprintdeactivate.ogg b/sound/misc/sprintdeactivate.ogg
similarity index 100%
rename from modular_citadel/sound/misc/sprintdeactivate.ogg
rename to sound/misc/sprintdeactivate.ogg
diff --git a/modular_citadel/sound/misc/ui_toggle.ogg b/sound/misc/ui_toggle.ogg
similarity index 100%
rename from modular_citadel/sound/misc/ui_toggle.ogg
rename to sound/misc/ui_toggle.ogg
diff --git a/modular_citadel/sound/misc/ui_toggleoff.ogg b/sound/misc/ui_toggleoff.ogg
similarity index 100%
rename from modular_citadel/sound/misc/ui_toggleoff.ogg
rename to sound/misc/ui_toggleoff.ogg
diff --git a/sound/spookoween/ahaha.ogg b/sound/spookoween/ahaha.ogg
new file mode 100644
index 0000000000..2e830ad6c7
Binary files /dev/null and b/sound/spookoween/ahaha.ogg differ
diff --git a/modular_citadel/sound/misc/cheekibreeki.ogg b/sound/voice/human/cheekibreeki.ogg
similarity index 100%
rename from modular_citadel/sound/misc/cheekibreeki.ogg
rename to sound/voice/human/cheekibreeki.ogg
diff --git a/modular_citadel/sound/misc/cyka1.ogg b/sound/voice/human/cyka1.ogg
similarity index 100%
rename from modular_citadel/sound/misc/cyka1.ogg
rename to sound/voice/human/cyka1.ogg
diff --git a/modular_citadel/sound/misc/manup.ogg b/sound/voice/manup.ogg
similarity index 100%
rename from modular_citadel/sound/misc/manup.ogg
rename to sound/voice/manup.ogg
diff --git a/sound/vore/LICENSE.txt b/sound/vore/LICENSE.txt
index ce95152f5d..a1e539b762 100644
--- a/sound/vore/LICENSE.txt
+++ b/sound/vore/LICENSE.txt
@@ -1 +1,3 @@
-Audio work within these folders are © Poojawa 2017, all rights reserved.
\ No newline at end of file
+Audio work within these folders are © Poojawa 2017, all rights reserved.
+
+Artist work by ChemicalCrux
\ No newline at end of file
diff --git a/sound/vore/pred/death_01.ogg b/sound/vore/pred/death_01.ogg
index 63ace65beb..231884ef54 100644
Binary files a/sound/vore/pred/death_01.ogg and b/sound/vore/pred/death_01.ogg differ
diff --git a/sound/vore/pred/death_02.ogg b/sound/vore/pred/death_02.ogg
index 4185f6fb20..5de3e4148c 100644
Binary files a/sound/vore/pred/death_02.ogg and b/sound/vore/pred/death_02.ogg differ
diff --git a/sound/vore/pred/death_03.ogg b/sound/vore/pred/death_03.ogg
index a9e5d769df..4ffa271af7 100644
Binary files a/sound/vore/pred/death_03.ogg and b/sound/vore/pred/death_03.ogg differ
diff --git a/sound/vore/pred/death_04.ogg b/sound/vore/pred/death_04.ogg
index 4deb6d5ec8..a4c0e91be6 100644
Binary files a/sound/vore/pred/death_04.ogg and b/sound/vore/pred/death_04.ogg differ
diff --git a/sound/vore/pred/death_05.ogg b/sound/vore/pred/death_05.ogg
index 9c359627c3..aeec557758 100644
Binary files a/sound/vore/pred/death_05.ogg and b/sound/vore/pred/death_05.ogg differ
diff --git a/sound/vore/pred/death_06.ogg b/sound/vore/pred/death_06.ogg
index 3d0fd0f58c..f5b077ebd4 100644
Binary files a/sound/vore/pred/death_06.ogg and b/sound/vore/pred/death_06.ogg differ
diff --git a/sound/vore/pred/death_07.ogg b/sound/vore/pred/death_07.ogg
index 98454abac9..afaaab65bb 100644
Binary files a/sound/vore/pred/death_07.ogg and b/sound/vore/pred/death_07.ogg differ
diff --git a/sound/vore/pred/death_08.ogg b/sound/vore/pred/death_08.ogg
index 068d6b8355..b1b8479ea8 100644
Binary files a/sound/vore/pred/death_08.ogg and b/sound/vore/pred/death_08.ogg differ
diff --git a/sound/vore/pred/death_09.ogg b/sound/vore/pred/death_09.ogg
index a4ad821c16..1454deafad 100644
Binary files a/sound/vore/pred/death_09.ogg and b/sound/vore/pred/death_09.ogg differ
diff --git a/sound/vore/pred/death_10.ogg b/sound/vore/pred/death_10.ogg
index b67868442f..f0e23e1d54 100644
Binary files a/sound/vore/pred/death_10.ogg and b/sound/vore/pred/death_10.ogg differ
diff --git a/sound/vore/pred/death_11.ogg b/sound/vore/pred/death_11.ogg
index db125edf80..43e80467e0 100644
Binary files a/sound/vore/pred/death_11.ogg and b/sound/vore/pred/death_11.ogg differ
diff --git a/sound/vore/pred/death_12.ogg b/sound/vore/pred/death_12.ogg
index ab4c548744..5ec6029998 100644
Binary files a/sound/vore/pred/death_12.ogg and b/sound/vore/pred/death_12.ogg differ
diff --git a/sound/vore/pred/death_13.ogg b/sound/vore/pred/death_13.ogg
index 008941942f..9073bac4f2 100644
Binary files a/sound/vore/pred/death_13.ogg and b/sound/vore/pred/death_13.ogg differ
diff --git a/sound/vore/pred/digest_01.ogg b/sound/vore/pred/digest_01.ogg
index 09e6805e90..20b6d1d43a 100644
Binary files a/sound/vore/pred/digest_01.ogg and b/sound/vore/pred/digest_01.ogg differ
diff --git a/sound/vore/pred/digest_02.ogg b/sound/vore/pred/digest_02.ogg
index d6852aeb9a..7fc41e2305 100644
Binary files a/sound/vore/pred/digest_02.ogg and b/sound/vore/pred/digest_02.ogg differ
diff --git a/sound/vore/pred/digest_03.ogg b/sound/vore/pred/digest_03.ogg
index 9e85de831e..98b032c7cb 100644
Binary files a/sound/vore/pred/digest_03.ogg and b/sound/vore/pred/digest_03.ogg differ
diff --git a/sound/vore/pred/digest_04.ogg b/sound/vore/pred/digest_04.ogg
index b35da498d3..ed494e813c 100644
Binary files a/sound/vore/pred/digest_04.ogg and b/sound/vore/pred/digest_04.ogg differ
diff --git a/sound/vore/pred/digest_05.ogg b/sound/vore/pred/digest_05.ogg
index 60ea067a91..53bb4814f7 100644
Binary files a/sound/vore/pred/digest_05.ogg and b/sound/vore/pred/digest_05.ogg differ
diff --git a/sound/vore/pred/digest_06.ogg b/sound/vore/pred/digest_06.ogg
index 4dcf50b699..787c336282 100644
Binary files a/sound/vore/pred/digest_06.ogg and b/sound/vore/pred/digest_06.ogg differ
diff --git a/sound/vore/pred/digest_07.ogg b/sound/vore/pred/digest_07.ogg
index 4d8fefd100..f63d4c633a 100644
Binary files a/sound/vore/pred/digest_07.ogg and b/sound/vore/pred/digest_07.ogg differ
diff --git a/sound/vore/pred/digest_08.ogg b/sound/vore/pred/digest_08.ogg
index da8b3fa963..dbbda3b517 100644
Binary files a/sound/vore/pred/digest_08.ogg and b/sound/vore/pred/digest_08.ogg differ
diff --git a/sound/vore/pred/digest_09.ogg b/sound/vore/pred/digest_09.ogg
index 072efb17fb..1877f1ca05 100644
Binary files a/sound/vore/pred/digest_09.ogg and b/sound/vore/pred/digest_09.ogg differ
diff --git a/sound/vore/pred/digest_10.ogg b/sound/vore/pred/digest_10.ogg
index fb69e4fd1a..3e22b8b2fb 100644
Binary files a/sound/vore/pred/digest_10.ogg and b/sound/vore/pred/digest_10.ogg differ
diff --git a/sound/vore/pred/digest_11.ogg b/sound/vore/pred/digest_11.ogg
index 611882b6d3..089d4ee7e4 100644
Binary files a/sound/vore/pred/digest_11.ogg and b/sound/vore/pred/digest_11.ogg differ
diff --git a/sound/vore/pred/digest_12.ogg b/sound/vore/pred/digest_12.ogg
index c9e004afb7..76a9134646 100644
Binary files a/sound/vore/pred/digest_12.ogg and b/sound/vore/pred/digest_12.ogg differ
diff --git a/sound/vore/pred/digest_13.ogg b/sound/vore/pred/digest_13.ogg
index 45a9d59f52..12b1c6bb18 100644
Binary files a/sound/vore/pred/digest_13.ogg and b/sound/vore/pred/digest_13.ogg differ
diff --git a/sound/vore/pred/digest_14.ogg b/sound/vore/pred/digest_14.ogg
index 9815d172ca..c68231585c 100644
Binary files a/sound/vore/pred/digest_14.ogg and b/sound/vore/pred/digest_14.ogg differ
diff --git a/sound/vore/pred/digest_15.ogg b/sound/vore/pred/digest_15.ogg
index d2e44ecc86..32aecca35b 100644
Binary files a/sound/vore/pred/digest_15.ogg and b/sound/vore/pred/digest_15.ogg differ
diff --git a/sound/vore/pred/digest_16.ogg b/sound/vore/pred/digest_16.ogg
index 84faa4bd99..d112913570 100644
Binary files a/sound/vore/pred/digest_16.ogg and b/sound/vore/pred/digest_16.ogg differ
diff --git a/sound/vore/pred/digest_17.ogg b/sound/vore/pred/digest_17.ogg
index 0dd6fd4989..d23c4c6ddc 100644
Binary files a/sound/vore/pred/digest_17.ogg and b/sound/vore/pred/digest_17.ogg differ
diff --git a/sound/vore/pred/digest_18.ogg b/sound/vore/pred/digest_18.ogg
index a9fa5b51f9..ae8ac9f74f 100644
Binary files a/sound/vore/pred/digest_18.ogg and b/sound/vore/pred/digest_18.ogg differ
diff --git a/sound/vore/pred/escape.ogg b/sound/vore/pred/escape.ogg
index a823fc1284..fc093a5acf 100644
Binary files a/sound/vore/pred/escape.ogg and b/sound/vore/pred/escape.ogg differ
diff --git a/sound/vore/pred/insertion_01.ogg b/sound/vore/pred/insertion_01.ogg
index 6a8e7e3ff0..4ca8b6e425 100644
Binary files a/sound/vore/pred/insertion_01.ogg and b/sound/vore/pred/insertion_01.ogg differ
diff --git a/sound/vore/pred/insertion_02.ogg b/sound/vore/pred/insertion_02.ogg
index c6e4f96d94..a23cfaf201 100644
Binary files a/sound/vore/pred/insertion_02.ogg and b/sound/vore/pred/insertion_02.ogg differ
diff --git a/sound/vore/pred/loop.ogg b/sound/vore/pred/loop.ogg
index afd6e6003d..5f0994251a 100644
Binary files a/sound/vore/pred/loop.ogg and b/sound/vore/pred/loop.ogg differ
diff --git a/sound/vore/pred/schlorp.ogg b/sound/vore/pred/schlorp.ogg
index c9cd5a3413..eefb9dd71e 100644
Binary files a/sound/vore/pred/schlorp.ogg and b/sound/vore/pred/schlorp.ogg differ
diff --git a/sound/vore/pred/squish _02.ogg b/sound/vore/pred/squish _02.ogg
index 2e3effb4d7..846f0a2ece 100644
Binary files a/sound/vore/pred/squish _02.ogg and b/sound/vore/pred/squish _02.ogg differ
diff --git a/sound/vore/pred/squish _03.ogg b/sound/vore/pred/squish _03.ogg
index 24b5f9ce02..568aa81a3d 100644
Binary files a/sound/vore/pred/squish _03.ogg and b/sound/vore/pred/squish _03.ogg differ
diff --git a/sound/vore/pred/squish_01.ogg b/sound/vore/pred/squish_01.ogg
index 17dc83ed98..bc014b811d 100644
Binary files a/sound/vore/pred/squish_01.ogg and b/sound/vore/pred/squish_01.ogg differ
diff --git a/sound/vore/pred/squish_02.ogg b/sound/vore/pred/squish_02.ogg
index febc4c106e..8d92bfd19e 100644
Binary files a/sound/vore/pred/squish_02.ogg and b/sound/vore/pred/squish_02.ogg differ
diff --git a/sound/vore/pred/squish_03.ogg b/sound/vore/pred/squish_03.ogg
index c1b544806b..f62bf7ff60 100644
Binary files a/sound/vore/pred/squish_03.ogg and b/sound/vore/pred/squish_03.ogg differ
diff --git a/sound/vore/pred/squish_04.ogg b/sound/vore/pred/squish_04.ogg
index e764ba051b..47037d9a3a 100644
Binary files a/sound/vore/pred/squish_04.ogg and b/sound/vore/pred/squish_04.ogg differ
diff --git a/sound/vore/pred/stomachmove.ogg b/sound/vore/pred/stomachmove.ogg
index 3a9ed98dae..4e11cc03ed 100644
Binary files a/sound/vore/pred/stomachmove.ogg and b/sound/vore/pred/stomachmove.ogg differ
diff --git a/sound/vore/pred/struggle_01.ogg b/sound/vore/pred/struggle_01.ogg
index aea5581889..96c569b0f9 100644
Binary files a/sound/vore/pred/struggle_01.ogg and b/sound/vore/pred/struggle_01.ogg differ
diff --git a/sound/vore/pred/struggle_02.ogg b/sound/vore/pred/struggle_02.ogg
index 526abd0a9e..2f0d3324f1 100644
Binary files a/sound/vore/pred/struggle_02.ogg and b/sound/vore/pred/struggle_02.ogg differ
diff --git a/sound/vore/pred/struggle_03.ogg b/sound/vore/pred/struggle_03.ogg
index f3300a8bf3..9632817010 100644
Binary files a/sound/vore/pred/struggle_03.ogg and b/sound/vore/pred/struggle_03.ogg differ
diff --git a/sound/vore/pred/struggle_04.ogg b/sound/vore/pred/struggle_04.ogg
index 9efa23eaa9..7a30de3baf 100644
Binary files a/sound/vore/pred/struggle_04.ogg and b/sound/vore/pred/struggle_04.ogg differ
diff --git a/sound/vore/pred/struggle_05.ogg b/sound/vore/pred/struggle_05.ogg
index ec4d006880..0bae93d50f 100644
Binary files a/sound/vore/pred/struggle_05.ogg and b/sound/vore/pred/struggle_05.ogg differ
diff --git a/sound/vore/pred/swallow_01.ogg b/sound/vore/pred/swallow_01.ogg
index 1767daf0e8..45a0008586 100644
Binary files a/sound/vore/pred/swallow_01.ogg and b/sound/vore/pred/swallow_01.ogg differ
diff --git a/sound/vore/pred/swallow_02.ogg b/sound/vore/pred/swallow_02.ogg
index dd906bfad8..8f9bcb2e84 100644
Binary files a/sound/vore/pred/swallow_02.ogg and b/sound/vore/pred/swallow_02.ogg differ
diff --git a/sound/vore/pred/taurswallow.ogg b/sound/vore/pred/taurswallow.ogg
index 697947fb49..c700f71803 100644
Binary files a/sound/vore/pred/taurswallow.ogg and b/sound/vore/pred/taurswallow.ogg differ
diff --git a/sound/vore/prey/death_01.ogg b/sound/vore/prey/death_01.ogg
index fb73f520d8..539a873a7e 100644
Binary files a/sound/vore/prey/death_01.ogg and b/sound/vore/prey/death_01.ogg differ
diff --git a/sound/vore/prey/death_02.ogg b/sound/vore/prey/death_02.ogg
index 96a4004691..4dd1a285ea 100644
Binary files a/sound/vore/prey/death_02.ogg and b/sound/vore/prey/death_02.ogg differ
diff --git a/sound/vore/prey/death_03.ogg b/sound/vore/prey/death_03.ogg
index faae0c0cad..30a3622c86 100644
Binary files a/sound/vore/prey/death_03.ogg and b/sound/vore/prey/death_03.ogg differ
diff --git a/sound/vore/prey/death_04.ogg b/sound/vore/prey/death_04.ogg
index 7a7230e11c..ff983c2c31 100644
Binary files a/sound/vore/prey/death_04.ogg and b/sound/vore/prey/death_04.ogg differ
diff --git a/sound/vore/prey/death_05.ogg b/sound/vore/prey/death_05.ogg
index 91e351a62c..44b8603048 100644
Binary files a/sound/vore/prey/death_05.ogg and b/sound/vore/prey/death_05.ogg differ
diff --git a/sound/vore/prey/death_06.ogg b/sound/vore/prey/death_06.ogg
index 59f5f5cde9..836a4fd18c 100644
Binary files a/sound/vore/prey/death_06.ogg and b/sound/vore/prey/death_06.ogg differ
diff --git a/sound/vore/prey/death_07.ogg b/sound/vore/prey/death_07.ogg
index 6a8ef68561..2406fea727 100644
Binary files a/sound/vore/prey/death_07.ogg and b/sound/vore/prey/death_07.ogg differ
diff --git a/sound/vore/prey/death_08.ogg b/sound/vore/prey/death_08.ogg
index 1991706d94..0d7627dfae 100644
Binary files a/sound/vore/prey/death_08.ogg and b/sound/vore/prey/death_08.ogg differ
diff --git a/sound/vore/prey/death_09.ogg b/sound/vore/prey/death_09.ogg
index c209e5f112..fa00a29d31 100644
Binary files a/sound/vore/prey/death_09.ogg and b/sound/vore/prey/death_09.ogg differ
diff --git a/sound/vore/prey/death_10.ogg b/sound/vore/prey/death_10.ogg
index ccf51389f1..738e7cf909 100644
Binary files a/sound/vore/prey/death_10.ogg and b/sound/vore/prey/death_10.ogg differ
diff --git a/sound/vore/prey/death_11.ogg b/sound/vore/prey/death_11.ogg
index b8089d0d88..bfd47945ae 100644
Binary files a/sound/vore/prey/death_11.ogg and b/sound/vore/prey/death_11.ogg differ
diff --git a/sound/vore/prey/death_12.ogg b/sound/vore/prey/death_12.ogg
index b39a17b9aa..e6e800b2da 100644
Binary files a/sound/vore/prey/death_12.ogg and b/sound/vore/prey/death_12.ogg differ
diff --git a/sound/vore/prey/death_13.ogg b/sound/vore/prey/death_13.ogg
index 375e1ec72f..c9b79887d7 100644
Binary files a/sound/vore/prey/death_13.ogg and b/sound/vore/prey/death_13.ogg differ
diff --git a/sound/vore/prey/digest_01.ogg b/sound/vore/prey/digest_01.ogg
index 0340773865..a1d13f7fb7 100644
Binary files a/sound/vore/prey/digest_01.ogg and b/sound/vore/prey/digest_01.ogg differ
diff --git a/sound/vore/prey/digest_02.ogg b/sound/vore/prey/digest_02.ogg
index 837e894f80..443d23c194 100644
Binary files a/sound/vore/prey/digest_02.ogg and b/sound/vore/prey/digest_02.ogg differ
diff --git a/sound/vore/prey/digest_03.ogg b/sound/vore/prey/digest_03.ogg
index 6f5db33b78..eb798b66ff 100644
Binary files a/sound/vore/prey/digest_03.ogg and b/sound/vore/prey/digest_03.ogg differ
diff --git a/sound/vore/prey/digest_04.ogg b/sound/vore/prey/digest_04.ogg
index b4184cd2a9..a2c2c3e1ac 100644
Binary files a/sound/vore/prey/digest_04.ogg and b/sound/vore/prey/digest_04.ogg differ
diff --git a/sound/vore/prey/digest_05.ogg b/sound/vore/prey/digest_05.ogg
index 79209df1f5..752a6d48f3 100644
Binary files a/sound/vore/prey/digest_05.ogg and b/sound/vore/prey/digest_05.ogg differ
diff --git a/sound/vore/prey/digest_06.ogg b/sound/vore/prey/digest_06.ogg
index 193167c50d..f2e80b919f 100644
Binary files a/sound/vore/prey/digest_06.ogg and b/sound/vore/prey/digest_06.ogg differ
diff --git a/sound/vore/prey/digest_07.ogg b/sound/vore/prey/digest_07.ogg
index 1092c3d5e0..6a2ff70ff8 100644
Binary files a/sound/vore/prey/digest_07.ogg and b/sound/vore/prey/digest_07.ogg differ
diff --git a/sound/vore/prey/digest_08.ogg b/sound/vore/prey/digest_08.ogg
index ef6aa1dcab..4e55f4671d 100644
Binary files a/sound/vore/prey/digest_08.ogg and b/sound/vore/prey/digest_08.ogg differ
diff --git a/sound/vore/prey/digest_09.ogg b/sound/vore/prey/digest_09.ogg
index db0a07d2b8..452e6b4a2e 100644
Binary files a/sound/vore/prey/digest_09.ogg and b/sound/vore/prey/digest_09.ogg differ
diff --git a/sound/vore/prey/digest_10.ogg b/sound/vore/prey/digest_10.ogg
index 788350acc6..4c5dc2e333 100644
Binary files a/sound/vore/prey/digest_10.ogg and b/sound/vore/prey/digest_10.ogg differ
diff --git a/sound/vore/prey/digest_11.ogg b/sound/vore/prey/digest_11.ogg
index 9f00271cd3..e94c0af656 100644
Binary files a/sound/vore/prey/digest_11.ogg and b/sound/vore/prey/digest_11.ogg differ
diff --git a/sound/vore/prey/digest_12.ogg b/sound/vore/prey/digest_12.ogg
index 4a7e360688..cb212fed1c 100644
Binary files a/sound/vore/prey/digest_12.ogg and b/sound/vore/prey/digest_12.ogg differ
diff --git a/sound/vore/prey/digest_13.ogg b/sound/vore/prey/digest_13.ogg
index 890c65ab08..9fd292184e 100644
Binary files a/sound/vore/prey/digest_13.ogg and b/sound/vore/prey/digest_13.ogg differ
diff --git a/sound/vore/prey/digest_14.ogg b/sound/vore/prey/digest_14.ogg
index de54440ea5..24279d4712 100644
Binary files a/sound/vore/prey/digest_14.ogg and b/sound/vore/prey/digest_14.ogg differ
diff --git a/sound/vore/prey/digest_15.ogg b/sound/vore/prey/digest_15.ogg
index 52ad557e84..2bf555ba41 100644
Binary files a/sound/vore/prey/digest_15.ogg and b/sound/vore/prey/digest_15.ogg differ
diff --git a/sound/vore/prey/digest_16.ogg b/sound/vore/prey/digest_16.ogg
index f2ff139651..98edd6fb61 100644
Binary files a/sound/vore/prey/digest_16.ogg and b/sound/vore/prey/digest_16.ogg differ
diff --git a/sound/vore/prey/digest_17.ogg b/sound/vore/prey/digest_17.ogg
index fa8ac42ae4..2ff5c173e1 100644
Binary files a/sound/vore/prey/digest_17.ogg and b/sound/vore/prey/digest_17.ogg differ
diff --git a/sound/vore/prey/digest_18.ogg b/sound/vore/prey/digest_18.ogg
index f6fa631ad3..6a1ae78fb8 100644
Binary files a/sound/vore/prey/digest_18.ogg and b/sound/vore/prey/digest_18.ogg differ
diff --git a/sound/vore/prey/escape.ogg b/sound/vore/prey/escape.ogg
index 9947f53013..621997a56d 100644
Binary files a/sound/vore/prey/escape.ogg and b/sound/vore/prey/escape.ogg differ
diff --git a/sound/vore/prey/insertion_01.ogg b/sound/vore/prey/insertion_01.ogg
index e8ec89cd9e..5a3b942bb3 100644
Binary files a/sound/vore/prey/insertion_01.ogg and b/sound/vore/prey/insertion_01.ogg differ
diff --git a/sound/vore/prey/insertion_02.ogg b/sound/vore/prey/insertion_02.ogg
index e21b6b23e8..2d35094522 100644
Binary files a/sound/vore/prey/insertion_02.ogg and b/sound/vore/prey/insertion_02.ogg differ
diff --git a/sound/vore/prey/loop.ogg b/sound/vore/prey/loop.ogg
index a6a040e501..1584482d92 100644
Binary files a/sound/vore/prey/loop.ogg and b/sound/vore/prey/loop.ogg differ
diff --git a/sound/vore/prey/schlorp.ogg b/sound/vore/prey/schlorp.ogg
index c9cd5a3413..d1895ee26a 100644
Binary files a/sound/vore/prey/schlorp.ogg and b/sound/vore/prey/schlorp.ogg differ
diff --git a/sound/vore/prey/squish_01.ogg b/sound/vore/prey/squish_01.ogg
index d1b3285381..2785a4a080 100644
Binary files a/sound/vore/prey/squish_01.ogg and b/sound/vore/prey/squish_01.ogg differ
diff --git a/sound/vore/prey/squish_02.ogg b/sound/vore/prey/squish_02.ogg
index f754a258f4..f5671f7165 100644
Binary files a/sound/vore/prey/squish_02.ogg and b/sound/vore/prey/squish_02.ogg differ
diff --git a/sound/vore/prey/squish_03.ogg b/sound/vore/prey/squish_03.ogg
index 9a01dcd2e9..1e8f2bb896 100644
Binary files a/sound/vore/prey/squish_03.ogg and b/sound/vore/prey/squish_03.ogg differ
diff --git a/sound/vore/prey/squish_04.ogg b/sound/vore/prey/squish_04.ogg
index d7c96b5bee..2e618890a9 100644
Binary files a/sound/vore/prey/squish_04.ogg and b/sound/vore/prey/squish_04.ogg differ
diff --git a/sound/vore/prey/stomachmove.ogg b/sound/vore/prey/stomachmove.ogg
index 1a32c7a217..e4e004b072 100644
Binary files a/sound/vore/prey/stomachmove.ogg and b/sound/vore/prey/stomachmove.ogg differ
diff --git a/sound/vore/prey/struggle_01.ogg b/sound/vore/prey/struggle_01.ogg
index ca90ed4f19..de0f3ad8bd 100644
Binary files a/sound/vore/prey/struggle_01.ogg and b/sound/vore/prey/struggle_01.ogg differ
diff --git a/sound/vore/prey/struggle_02.ogg b/sound/vore/prey/struggle_02.ogg
index 711c488db2..2695ab0adf 100644
Binary files a/sound/vore/prey/struggle_02.ogg and b/sound/vore/prey/struggle_02.ogg differ
diff --git a/sound/vore/prey/struggle_03.ogg b/sound/vore/prey/struggle_03.ogg
index d7e4e5f0bb..17dd8bec8a 100644
Binary files a/sound/vore/prey/struggle_03.ogg and b/sound/vore/prey/struggle_03.ogg differ
diff --git a/sound/vore/prey/struggle_04.ogg b/sound/vore/prey/struggle_04.ogg
index 4e6532a0fc..8631853509 100644
Binary files a/sound/vore/prey/struggle_04.ogg and b/sound/vore/prey/struggle_04.ogg differ
diff --git a/sound/vore/prey/struggle_05.ogg b/sound/vore/prey/struggle_05.ogg
index 6399d69adc..233addec0b 100644
Binary files a/sound/vore/prey/struggle_05.ogg and b/sound/vore/prey/struggle_05.ogg differ
diff --git a/sound/vore/prey/swallow_01.ogg b/sound/vore/prey/swallow_01.ogg
index 86e14ef7af..3da3fef66a 100644
Binary files a/sound/vore/prey/swallow_01.ogg and b/sound/vore/prey/swallow_01.ogg differ
diff --git a/sound/vore/prey/swallow_02.ogg b/sound/vore/prey/swallow_02.ogg
index dbfad7750a..30d9a4e44d 100644
Binary files a/sound/vore/prey/swallow_02.ogg and b/sound/vore/prey/swallow_02.ogg differ
diff --git a/sound/vore/prey/taurswallow.ogg b/sound/vore/prey/taurswallow.ogg
index 925ac9229c..f5b5706b36 100644
Binary files a/sound/vore/prey/taurswallow.ogg and b/sound/vore/prey/taurswallow.ogg differ
diff --git a/modular_citadel/sound/vox/_comma.ogg b/sound/vox/_comma.ogg
similarity index 100%
rename from modular_citadel/sound/vox/_comma.ogg
rename to sound/vox/_comma.ogg
diff --git a/modular_citadel/sound/vox/_period.ogg b/sound/vox/_period.ogg
similarity index 100%
rename from modular_citadel/sound/vox/_period.ogg
rename to sound/vox/_period.ogg
diff --git a/modular_citadel/sound/vox/a.ogg b/sound/vox/a.ogg
similarity index 100%
rename from modular_citadel/sound/vox/a.ogg
rename to sound/vox/a.ogg
diff --git a/modular_citadel/sound/vox/accelerating.ogg b/sound/vox/accelerating.ogg
similarity index 100%
rename from modular_citadel/sound/vox/accelerating.ogg
rename to sound/vox/accelerating.ogg
diff --git a/modular_citadel/sound/vox/accelerator.ogg b/sound/vox/accelerator.ogg
similarity index 100%
rename from modular_citadel/sound/vox/accelerator.ogg
rename to sound/vox/accelerator.ogg
diff --git a/modular_citadel/sound/vox/accepted.ogg b/sound/vox/accepted.ogg
similarity index 100%
rename from modular_citadel/sound/vox/accepted.ogg
rename to sound/vox/accepted.ogg
diff --git a/modular_citadel/sound/vox/access.ogg b/sound/vox/access.ogg
similarity index 100%
rename from modular_citadel/sound/vox/access.ogg
rename to sound/vox/access.ogg
diff --git a/modular_citadel/sound/vox/acknowledge.ogg b/sound/vox/acknowledge.ogg
similarity index 100%
rename from modular_citadel/sound/vox/acknowledge.ogg
rename to sound/vox/acknowledge.ogg
diff --git a/modular_citadel/sound/vox/acknowledged.ogg b/sound/vox/acknowledged.ogg
similarity index 100%
rename from modular_citadel/sound/vox/acknowledged.ogg
rename to sound/vox/acknowledged.ogg
diff --git a/modular_citadel/sound/vox/acquired.ogg b/sound/vox/acquired.ogg
similarity index 100%
rename from modular_citadel/sound/vox/acquired.ogg
rename to sound/vox/acquired.ogg
diff --git a/modular_citadel/sound/vox/acquisition.ogg b/sound/vox/acquisition.ogg
similarity index 100%
rename from modular_citadel/sound/vox/acquisition.ogg
rename to sound/vox/acquisition.ogg
diff --git a/modular_citadel/sound/vox/across.ogg b/sound/vox/across.ogg
similarity index 100%
rename from modular_citadel/sound/vox/across.ogg
rename to sound/vox/across.ogg
diff --git a/modular_citadel/sound/vox/activate.ogg b/sound/vox/activate.ogg
similarity index 100%
rename from modular_citadel/sound/vox/activate.ogg
rename to sound/vox/activate.ogg
diff --git a/modular_citadel/sound/vox/activated.ogg b/sound/vox/activated.ogg
similarity index 100%
rename from modular_citadel/sound/vox/activated.ogg
rename to sound/vox/activated.ogg
diff --git a/modular_citadel/sound/vox/activity.ogg b/sound/vox/activity.ogg
similarity index 100%
rename from modular_citadel/sound/vox/activity.ogg
rename to sound/vox/activity.ogg
diff --git a/modular_citadel/sound/vox/adios.ogg b/sound/vox/adios.ogg
similarity index 100%
rename from modular_citadel/sound/vox/adios.ogg
rename to sound/vox/adios.ogg
diff --git a/modular_citadel/sound/vox/administration.ogg b/sound/vox/administration.ogg
similarity index 100%
rename from modular_citadel/sound/vox/administration.ogg
rename to sound/vox/administration.ogg
diff --git a/modular_citadel/sound/vox/advanced.ogg b/sound/vox/advanced.ogg
similarity index 100%
rename from modular_citadel/sound/vox/advanced.ogg
rename to sound/vox/advanced.ogg
diff --git a/modular_citadel/sound/vox/after.ogg b/sound/vox/after.ogg
similarity index 100%
rename from modular_citadel/sound/vox/after.ogg
rename to sound/vox/after.ogg
diff --git a/modular_citadel/sound/vox/agent.ogg b/sound/vox/agent.ogg
similarity index 100%
rename from modular_citadel/sound/vox/agent.ogg
rename to sound/vox/agent.ogg
diff --git a/modular_citadel/sound/vox/alarm.ogg b/sound/vox/alarm.ogg
similarity index 100%
rename from modular_citadel/sound/vox/alarm.ogg
rename to sound/vox/alarm.ogg
diff --git a/modular_citadel/sound/vox/alert.ogg b/sound/vox/alert.ogg
similarity index 100%
rename from modular_citadel/sound/vox/alert.ogg
rename to sound/vox/alert.ogg
diff --git a/modular_citadel/sound/vox/alien.ogg b/sound/vox/alien.ogg
similarity index 100%
rename from modular_citadel/sound/vox/alien.ogg
rename to sound/vox/alien.ogg
diff --git a/modular_citadel/sound/vox/aligned.ogg b/sound/vox/aligned.ogg
similarity index 100%
rename from modular_citadel/sound/vox/aligned.ogg
rename to sound/vox/aligned.ogg
diff --git a/modular_citadel/sound/vox/all.ogg b/sound/vox/all.ogg
similarity index 100%
rename from modular_citadel/sound/vox/all.ogg
rename to sound/vox/all.ogg
diff --git a/modular_citadel/sound/vox/alpha.ogg b/sound/vox/alpha.ogg
similarity index 100%
rename from modular_citadel/sound/vox/alpha.ogg
rename to sound/vox/alpha.ogg
diff --git a/modular_citadel/sound/vox/am.ogg b/sound/vox/am.ogg
similarity index 100%
rename from modular_citadel/sound/vox/am.ogg
rename to sound/vox/am.ogg
diff --git a/modular_citadel/sound/vox/amigo.ogg b/sound/vox/amigo.ogg
similarity index 100%
rename from modular_citadel/sound/vox/amigo.ogg
rename to sound/vox/amigo.ogg
diff --git a/modular_citadel/sound/vox/ammunition.ogg b/sound/vox/ammunition.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ammunition.ogg
rename to sound/vox/ammunition.ogg
diff --git a/modular_citadel/sound/vox/an.ogg b/sound/vox/an.ogg
similarity index 100%
rename from modular_citadel/sound/vox/an.ogg
rename to sound/vox/an.ogg
diff --git a/modular_citadel/sound/vox/and.ogg b/sound/vox/and.ogg
similarity index 100%
rename from modular_citadel/sound/vox/and.ogg
rename to sound/vox/and.ogg
diff --git a/modular_citadel/sound/vox/announcement.ogg b/sound/vox/announcement.ogg
similarity index 100%
rename from modular_citadel/sound/vox/announcement.ogg
rename to sound/vox/announcement.ogg
diff --git a/modular_citadel/sound/vox/anomalous.ogg b/sound/vox/anomalous.ogg
similarity index 100%
rename from modular_citadel/sound/vox/anomalous.ogg
rename to sound/vox/anomalous.ogg
diff --git a/modular_citadel/sound/vox/antenna.ogg b/sound/vox/antenna.ogg
similarity index 100%
rename from modular_citadel/sound/vox/antenna.ogg
rename to sound/vox/antenna.ogg
diff --git a/modular_citadel/sound/vox/any.ogg b/sound/vox/any.ogg
similarity index 100%
rename from modular_citadel/sound/vox/any.ogg
rename to sound/vox/any.ogg
diff --git a/modular_citadel/sound/vox/apprehend.ogg b/sound/vox/apprehend.ogg
similarity index 100%
rename from modular_citadel/sound/vox/apprehend.ogg
rename to sound/vox/apprehend.ogg
diff --git a/modular_citadel/sound/vox/approach.ogg b/sound/vox/approach.ogg
similarity index 100%
rename from modular_citadel/sound/vox/approach.ogg
rename to sound/vox/approach.ogg
diff --git a/modular_citadel/sound/vox/are.ogg b/sound/vox/are.ogg
similarity index 100%
rename from modular_citadel/sound/vox/are.ogg
rename to sound/vox/are.ogg
diff --git a/modular_citadel/sound/vox/area.ogg b/sound/vox/area.ogg
similarity index 100%
rename from modular_citadel/sound/vox/area.ogg
rename to sound/vox/area.ogg
diff --git a/modular_citadel/sound/vox/arm.ogg b/sound/vox/arm.ogg
similarity index 100%
rename from modular_citadel/sound/vox/arm.ogg
rename to sound/vox/arm.ogg
diff --git a/modular_citadel/sound/vox/armed.ogg b/sound/vox/armed.ogg
similarity index 100%
rename from modular_citadel/sound/vox/armed.ogg
rename to sound/vox/armed.ogg
diff --git a/modular_citadel/sound/vox/armor.ogg b/sound/vox/armor.ogg
similarity index 100%
rename from modular_citadel/sound/vox/armor.ogg
rename to sound/vox/armor.ogg
diff --git a/modular_citadel/sound/vox/armory.ogg b/sound/vox/armory.ogg
similarity index 100%
rename from modular_citadel/sound/vox/armory.ogg
rename to sound/vox/armory.ogg
diff --git a/modular_citadel/sound/vox/arrest.ogg b/sound/vox/arrest.ogg
similarity index 100%
rename from modular_citadel/sound/vox/arrest.ogg
rename to sound/vox/arrest.ogg
diff --git a/modular_citadel/sound/vox/ass.ogg b/sound/vox/ass.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ass.ogg
rename to sound/vox/ass.ogg
diff --git a/modular_citadel/sound/vox/at.ogg b/sound/vox/at.ogg
similarity index 100%
rename from modular_citadel/sound/vox/at.ogg
rename to sound/vox/at.ogg
diff --git a/modular_citadel/sound/vox/atomic.ogg b/sound/vox/atomic.ogg
similarity index 100%
rename from modular_citadel/sound/vox/atomic.ogg
rename to sound/vox/atomic.ogg
diff --git a/modular_citadel/sound/vox/attention.ogg b/sound/vox/attention.ogg
similarity index 100%
rename from modular_citadel/sound/vox/attention.ogg
rename to sound/vox/attention.ogg
diff --git a/modular_citadel/sound/vox/authorize.ogg b/sound/vox/authorize.ogg
similarity index 100%
rename from modular_citadel/sound/vox/authorize.ogg
rename to sound/vox/authorize.ogg
diff --git a/modular_citadel/sound/vox/authorized.ogg b/sound/vox/authorized.ogg
similarity index 100%
rename from modular_citadel/sound/vox/authorized.ogg
rename to sound/vox/authorized.ogg
diff --git a/modular_citadel/sound/vox/automatic.ogg b/sound/vox/automatic.ogg
similarity index 100%
rename from modular_citadel/sound/vox/automatic.ogg
rename to sound/vox/automatic.ogg
diff --git a/modular_citadel/sound/vox/away.ogg b/sound/vox/away.ogg
similarity index 100%
rename from modular_citadel/sound/vox/away.ogg
rename to sound/vox/away.ogg
diff --git a/modular_citadel/sound/vox/b.ogg b/sound/vox/b.ogg
similarity index 100%
rename from modular_citadel/sound/vox/b.ogg
rename to sound/vox/b.ogg
diff --git a/modular_citadel/sound/vox/back.ogg b/sound/vox/back.ogg
similarity index 100%
rename from modular_citadel/sound/vox/back.ogg
rename to sound/vox/back.ogg
diff --git a/modular_citadel/sound/vox/backman.ogg b/sound/vox/backman.ogg
similarity index 100%
rename from modular_citadel/sound/vox/backman.ogg
rename to sound/vox/backman.ogg
diff --git a/modular_citadel/sound/vox/bad.ogg b/sound/vox/bad.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bad.ogg
rename to sound/vox/bad.ogg
diff --git a/modular_citadel/sound/vox/bag.ogg b/sound/vox/bag.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bag.ogg
rename to sound/vox/bag.ogg
diff --git a/modular_citadel/sound/vox/bailey.ogg b/sound/vox/bailey.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bailey.ogg
rename to sound/vox/bailey.ogg
diff --git a/modular_citadel/sound/vox/barracks.ogg b/sound/vox/barracks.ogg
similarity index 100%
rename from modular_citadel/sound/vox/barracks.ogg
rename to sound/vox/barracks.ogg
diff --git a/modular_citadel/sound/vox/base.ogg b/sound/vox/base.ogg
similarity index 100%
rename from modular_citadel/sound/vox/base.ogg
rename to sound/vox/base.ogg
diff --git a/modular_citadel/sound/vox/bay.ogg b/sound/vox/bay.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bay.ogg
rename to sound/vox/bay.ogg
diff --git a/modular_citadel/sound/vox/be.ogg b/sound/vox/be.ogg
similarity index 100%
rename from modular_citadel/sound/vox/be.ogg
rename to sound/vox/be.ogg
diff --git a/modular_citadel/sound/vox/been.ogg b/sound/vox/been.ogg
similarity index 100%
rename from modular_citadel/sound/vox/been.ogg
rename to sound/vox/been.ogg
diff --git a/modular_citadel/sound/vox/before.ogg b/sound/vox/before.ogg
similarity index 100%
rename from modular_citadel/sound/vox/before.ogg
rename to sound/vox/before.ogg
diff --git a/modular_citadel/sound/vox/beyond.ogg b/sound/vox/beyond.ogg
similarity index 100%
rename from modular_citadel/sound/vox/beyond.ogg
rename to sound/vox/beyond.ogg
diff --git a/modular_citadel/sound/vox/biohazard.ogg b/sound/vox/biohazard.ogg
similarity index 100%
rename from modular_citadel/sound/vox/biohazard.ogg
rename to sound/vox/biohazard.ogg
diff --git a/modular_citadel/sound/vox/biological.ogg b/sound/vox/biological.ogg
similarity index 100%
rename from modular_citadel/sound/vox/biological.ogg
rename to sound/vox/biological.ogg
diff --git a/modular_citadel/sound/vox/birdwell.ogg b/sound/vox/birdwell.ogg
similarity index 100%
rename from modular_citadel/sound/vox/birdwell.ogg
rename to sound/vox/birdwell.ogg
diff --git a/modular_citadel/sound/vox/bizwarn.ogg b/sound/vox/bizwarn.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bizwarn.ogg
rename to sound/vox/bizwarn.ogg
diff --git a/modular_citadel/sound/vox/black.ogg b/sound/vox/black.ogg
similarity index 100%
rename from modular_citadel/sound/vox/black.ogg
rename to sound/vox/black.ogg
diff --git a/modular_citadel/sound/vox/blast.ogg b/sound/vox/blast.ogg
similarity index 100%
rename from modular_citadel/sound/vox/blast.ogg
rename to sound/vox/blast.ogg
diff --git a/modular_citadel/sound/vox/blocked.ogg b/sound/vox/blocked.ogg
similarity index 100%
rename from modular_citadel/sound/vox/blocked.ogg
rename to sound/vox/blocked.ogg
diff --git a/modular_citadel/sound/vox/bloop.ogg b/sound/vox/bloop.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bloop.ogg
rename to sound/vox/bloop.ogg
diff --git a/modular_citadel/sound/vox/blue.ogg b/sound/vox/blue.ogg
similarity index 100%
rename from modular_citadel/sound/vox/blue.ogg
rename to sound/vox/blue.ogg
diff --git a/modular_citadel/sound/vox/bottom.ogg b/sound/vox/bottom.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bottom.ogg
rename to sound/vox/bottom.ogg
diff --git a/modular_citadel/sound/vox/bravo.ogg b/sound/vox/bravo.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bravo.ogg
rename to sound/vox/bravo.ogg
diff --git a/modular_citadel/sound/vox/breach.ogg b/sound/vox/breach.ogg
similarity index 100%
rename from modular_citadel/sound/vox/breach.ogg
rename to sound/vox/breach.ogg
diff --git a/modular_citadel/sound/vox/breached.ogg b/sound/vox/breached.ogg
similarity index 100%
rename from modular_citadel/sound/vox/breached.ogg
rename to sound/vox/breached.ogg
diff --git a/modular_citadel/sound/vox/break.ogg b/sound/vox/break.ogg
similarity index 100%
rename from modular_citadel/sound/vox/break.ogg
rename to sound/vox/break.ogg
diff --git a/modular_citadel/sound/vox/bridge.ogg b/sound/vox/bridge.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bridge.ogg
rename to sound/vox/bridge.ogg
diff --git a/modular_citadel/sound/vox/bust.ogg b/sound/vox/bust.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bust.ogg
rename to sound/vox/bust.ogg
diff --git a/modular_citadel/sound/vox/but.ogg b/sound/vox/but.ogg
similarity index 100%
rename from modular_citadel/sound/vox/but.ogg
rename to sound/vox/but.ogg
diff --git a/modular_citadel/sound/vox/button.ogg b/sound/vox/button.ogg
similarity index 100%
rename from modular_citadel/sound/vox/button.ogg
rename to sound/vox/button.ogg
diff --git a/modular_citadel/sound/vox/buzwarn.ogg b/sound/vox/buzwarn.ogg
similarity index 100%
rename from modular_citadel/sound/vox/buzwarn.ogg
rename to sound/vox/buzwarn.ogg
diff --git a/modular_citadel/sound/vox/bypass.ogg b/sound/vox/bypass.ogg
similarity index 100%
rename from modular_citadel/sound/vox/bypass.ogg
rename to sound/vox/bypass.ogg
diff --git a/modular_citadel/sound/vox/c.ogg b/sound/vox/c.ogg
similarity index 100%
rename from modular_citadel/sound/vox/c.ogg
rename to sound/vox/c.ogg
diff --git a/modular_citadel/sound/vox/cable.ogg b/sound/vox/cable.ogg
similarity index 100%
rename from modular_citadel/sound/vox/cable.ogg
rename to sound/vox/cable.ogg
diff --git a/modular_citadel/sound/vox/call.ogg b/sound/vox/call.ogg
similarity index 100%
rename from modular_citadel/sound/vox/call.ogg
rename to sound/vox/call.ogg
diff --git a/modular_citadel/sound/vox/called.ogg b/sound/vox/called.ogg
similarity index 100%
rename from modular_citadel/sound/vox/called.ogg
rename to sound/vox/called.ogg
diff --git a/modular_citadel/sound/vox/canal.ogg b/sound/vox/canal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/canal.ogg
rename to sound/vox/canal.ogg
diff --git a/modular_citadel/sound/vox/cap.ogg b/sound/vox/cap.ogg
similarity index 100%
rename from modular_citadel/sound/vox/cap.ogg
rename to sound/vox/cap.ogg
diff --git a/modular_citadel/sound/vox/captain.ogg b/sound/vox/captain.ogg
similarity index 100%
rename from modular_citadel/sound/vox/captain.ogg
rename to sound/vox/captain.ogg
diff --git a/modular_citadel/sound/vox/capture.ogg b/sound/vox/capture.ogg
similarity index 100%
rename from modular_citadel/sound/vox/capture.ogg
rename to sound/vox/capture.ogg
diff --git a/modular_citadel/sound/vox/captured.ogg b/sound/vox/captured.ogg
similarity index 100%
rename from modular_citadel/sound/vox/captured.ogg
rename to sound/vox/captured.ogg
diff --git a/modular_citadel/sound/vox/ceiling.ogg b/sound/vox/ceiling.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ceiling.ogg
rename to sound/vox/ceiling.ogg
diff --git a/modular_citadel/sound/vox/celsius.ogg b/sound/vox/celsius.ogg
similarity index 100%
rename from modular_citadel/sound/vox/celsius.ogg
rename to sound/vox/celsius.ogg
diff --git a/modular_citadel/sound/vox/center.ogg b/sound/vox/center.ogg
similarity index 100%
rename from modular_citadel/sound/vox/center.ogg
rename to sound/vox/center.ogg
diff --git a/modular_citadel/sound/vox/centi.ogg b/sound/vox/centi.ogg
similarity index 100%
rename from modular_citadel/sound/vox/centi.ogg
rename to sound/vox/centi.ogg
diff --git a/modular_citadel/sound/vox/central.ogg b/sound/vox/central.ogg
similarity index 100%
rename from modular_citadel/sound/vox/central.ogg
rename to sound/vox/central.ogg
diff --git a/modular_citadel/sound/vox/chamber.ogg b/sound/vox/chamber.ogg
similarity index 100%
rename from modular_citadel/sound/vox/chamber.ogg
rename to sound/vox/chamber.ogg
diff --git a/modular_citadel/sound/vox/charlie.ogg b/sound/vox/charlie.ogg
similarity index 100%
rename from modular_citadel/sound/vox/charlie.ogg
rename to sound/vox/charlie.ogg
diff --git a/modular_citadel/sound/vox/check.ogg b/sound/vox/check.ogg
similarity index 100%
rename from modular_citadel/sound/vox/check.ogg
rename to sound/vox/check.ogg
diff --git a/modular_citadel/sound/vox/checkpoint.ogg b/sound/vox/checkpoint.ogg
similarity index 100%
rename from modular_citadel/sound/vox/checkpoint.ogg
rename to sound/vox/checkpoint.ogg
diff --git a/modular_citadel/sound/vox/chemical.ogg b/sound/vox/chemical.ogg
similarity index 100%
rename from modular_citadel/sound/vox/chemical.ogg
rename to sound/vox/chemical.ogg
diff --git a/modular_citadel/sound/vox/cleanup.ogg b/sound/vox/cleanup.ogg
similarity index 100%
rename from modular_citadel/sound/vox/cleanup.ogg
rename to sound/vox/cleanup.ogg
diff --git a/modular_citadel/sound/vox/clear.ogg b/sound/vox/clear.ogg
similarity index 100%
rename from modular_citadel/sound/vox/clear.ogg
rename to sound/vox/clear.ogg
diff --git a/modular_citadel/sound/vox/clearance.ogg b/sound/vox/clearance.ogg
similarity index 100%
rename from modular_citadel/sound/vox/clearance.ogg
rename to sound/vox/clearance.ogg
diff --git a/modular_citadel/sound/vox/close.ogg b/sound/vox/close.ogg
similarity index 100%
rename from modular_citadel/sound/vox/close.ogg
rename to sound/vox/close.ogg
diff --git a/modular_citadel/sound/vox/clown.ogg b/sound/vox/clown.ogg
similarity index 100%
rename from modular_citadel/sound/vox/clown.ogg
rename to sound/vox/clown.ogg
diff --git a/modular_citadel/sound/vox/code.ogg b/sound/vox/code.ogg
similarity index 100%
rename from modular_citadel/sound/vox/code.ogg
rename to sound/vox/code.ogg
diff --git a/modular_citadel/sound/vox/coded.ogg b/sound/vox/coded.ogg
similarity index 100%
rename from modular_citadel/sound/vox/coded.ogg
rename to sound/vox/coded.ogg
diff --git a/modular_citadel/sound/vox/collider.ogg b/sound/vox/collider.ogg
similarity index 100%
rename from modular_citadel/sound/vox/collider.ogg
rename to sound/vox/collider.ogg
diff --git a/modular_citadel/sound/vox/comma.ogg b/sound/vox/comma.ogg
similarity index 100%
rename from modular_citadel/sound/vox/comma.ogg
rename to sound/vox/comma.ogg
diff --git a/modular_citadel/sound/vox/command.ogg b/sound/vox/command.ogg
similarity index 100%
rename from modular_citadel/sound/vox/command.ogg
rename to sound/vox/command.ogg
diff --git a/modular_citadel/sound/vox/communication.ogg b/sound/vox/communication.ogg
similarity index 100%
rename from modular_citadel/sound/vox/communication.ogg
rename to sound/vox/communication.ogg
diff --git a/modular_citadel/sound/vox/complex.ogg b/sound/vox/complex.ogg
similarity index 100%
rename from modular_citadel/sound/vox/complex.ogg
rename to sound/vox/complex.ogg
diff --git a/modular_citadel/sound/vox/computer.ogg b/sound/vox/computer.ogg
similarity index 100%
rename from modular_citadel/sound/vox/computer.ogg
rename to sound/vox/computer.ogg
diff --git a/modular_citadel/sound/vox/condition.ogg b/sound/vox/condition.ogg
similarity index 100%
rename from modular_citadel/sound/vox/condition.ogg
rename to sound/vox/condition.ogg
diff --git a/modular_citadel/sound/vox/containment.ogg b/sound/vox/containment.ogg
similarity index 100%
rename from modular_citadel/sound/vox/containment.ogg
rename to sound/vox/containment.ogg
diff --git a/modular_citadel/sound/vox/contamination.ogg b/sound/vox/contamination.ogg
similarity index 100%
rename from modular_citadel/sound/vox/contamination.ogg
rename to sound/vox/contamination.ogg
diff --git a/modular_citadel/sound/vox/control.ogg b/sound/vox/control.ogg
similarity index 100%
rename from modular_citadel/sound/vox/control.ogg
rename to sound/vox/control.ogg
diff --git a/modular_citadel/sound/vox/coolant.ogg b/sound/vox/coolant.ogg
similarity index 100%
rename from modular_citadel/sound/vox/coolant.ogg
rename to sound/vox/coolant.ogg
diff --git a/modular_citadel/sound/vox/coomer.ogg b/sound/vox/coomer.ogg
similarity index 100%
rename from modular_citadel/sound/vox/coomer.ogg
rename to sound/vox/coomer.ogg
diff --git a/modular_citadel/sound/vox/core.ogg b/sound/vox/core.ogg
similarity index 100%
rename from modular_citadel/sound/vox/core.ogg
rename to sound/vox/core.ogg
diff --git a/modular_citadel/sound/vox/correct.ogg b/sound/vox/correct.ogg
similarity index 100%
rename from modular_citadel/sound/vox/correct.ogg
rename to sound/vox/correct.ogg
diff --git a/modular_citadel/sound/vox/corridor.ogg b/sound/vox/corridor.ogg
similarity index 100%
rename from modular_citadel/sound/vox/corridor.ogg
rename to sound/vox/corridor.ogg
diff --git a/modular_citadel/sound/vox/crew.ogg b/sound/vox/crew.ogg
similarity index 100%
rename from modular_citadel/sound/vox/crew.ogg
rename to sound/vox/crew.ogg
diff --git a/modular_citadel/sound/vox/cross.ogg b/sound/vox/cross.ogg
similarity index 100%
rename from modular_citadel/sound/vox/cross.ogg
rename to sound/vox/cross.ogg
diff --git a/modular_citadel/sound/vox/cryogenic.ogg b/sound/vox/cryogenic.ogg
similarity index 100%
rename from modular_citadel/sound/vox/cryogenic.ogg
rename to sound/vox/cryogenic.ogg
diff --git a/modular_citadel/sound/vox/d.ogg b/sound/vox/d.ogg
similarity index 100%
rename from modular_citadel/sound/vox/d.ogg
rename to sound/vox/d.ogg
diff --git a/modular_citadel/sound/vox/dadeda.ogg b/sound/vox/dadeda.ogg
similarity index 100%
rename from modular_citadel/sound/vox/dadeda.ogg
rename to sound/vox/dadeda.ogg
diff --git a/modular_citadel/sound/vox/damage.ogg b/sound/vox/damage.ogg
similarity index 100%
rename from modular_citadel/sound/vox/damage.ogg
rename to sound/vox/damage.ogg
diff --git a/modular_citadel/sound/vox/damaged.ogg b/sound/vox/damaged.ogg
similarity index 100%
rename from modular_citadel/sound/vox/damaged.ogg
rename to sound/vox/damaged.ogg
diff --git a/modular_citadel/sound/vox/danger.ogg b/sound/vox/danger.ogg
similarity index 100%
rename from modular_citadel/sound/vox/danger.ogg
rename to sound/vox/danger.ogg
diff --git a/modular_citadel/sound/vox/day.ogg b/sound/vox/day.ogg
similarity index 100%
rename from modular_citadel/sound/vox/day.ogg
rename to sound/vox/day.ogg
diff --git a/modular_citadel/sound/vox/deactivated.ogg b/sound/vox/deactivated.ogg
similarity index 100%
rename from modular_citadel/sound/vox/deactivated.ogg
rename to sound/vox/deactivated.ogg
diff --git a/modular_citadel/sound/vox/decompression.ogg b/sound/vox/decompression.ogg
similarity index 100%
rename from modular_citadel/sound/vox/decompression.ogg
rename to sound/vox/decompression.ogg
diff --git a/modular_citadel/sound/vox/decontamination.ogg b/sound/vox/decontamination.ogg
similarity index 100%
rename from modular_citadel/sound/vox/decontamination.ogg
rename to sound/vox/decontamination.ogg
diff --git a/modular_citadel/sound/vox/deeoo.ogg b/sound/vox/deeoo.ogg
similarity index 100%
rename from modular_citadel/sound/vox/deeoo.ogg
rename to sound/vox/deeoo.ogg
diff --git a/modular_citadel/sound/vox/defense.ogg b/sound/vox/defense.ogg
similarity index 100%
rename from modular_citadel/sound/vox/defense.ogg
rename to sound/vox/defense.ogg
diff --git a/modular_citadel/sound/vox/degrees.ogg b/sound/vox/degrees.ogg
similarity index 100%
rename from modular_citadel/sound/vox/degrees.ogg
rename to sound/vox/degrees.ogg
diff --git a/modular_citadel/sound/vox/delta.ogg b/sound/vox/delta.ogg
similarity index 100%
rename from modular_citadel/sound/vox/delta.ogg
rename to sound/vox/delta.ogg
diff --git a/modular_citadel/sound/vox/denied.ogg b/sound/vox/denied.ogg
similarity index 100%
rename from modular_citadel/sound/vox/denied.ogg
rename to sound/vox/denied.ogg
diff --git a/modular_citadel/sound/vox/deploy.ogg b/sound/vox/deploy.ogg
similarity index 100%
rename from modular_citadel/sound/vox/deploy.ogg
rename to sound/vox/deploy.ogg
diff --git a/modular_citadel/sound/vox/deployed.ogg b/sound/vox/deployed.ogg
similarity index 100%
rename from modular_citadel/sound/vox/deployed.ogg
rename to sound/vox/deployed.ogg
diff --git a/modular_citadel/sound/vox/destroy.ogg b/sound/vox/destroy.ogg
similarity index 100%
rename from modular_citadel/sound/vox/destroy.ogg
rename to sound/vox/destroy.ogg
diff --git a/modular_citadel/sound/vox/destroyed.ogg b/sound/vox/destroyed.ogg
similarity index 100%
rename from modular_citadel/sound/vox/destroyed.ogg
rename to sound/vox/destroyed.ogg
diff --git a/modular_citadel/sound/vox/detain.ogg b/sound/vox/detain.ogg
similarity index 100%
rename from modular_citadel/sound/vox/detain.ogg
rename to sound/vox/detain.ogg
diff --git a/modular_citadel/sound/vox/detected.ogg b/sound/vox/detected.ogg
similarity index 100%
rename from modular_citadel/sound/vox/detected.ogg
rename to sound/vox/detected.ogg
diff --git a/modular_citadel/sound/vox/detonation.ogg b/sound/vox/detonation.ogg
similarity index 100%
rename from modular_citadel/sound/vox/detonation.ogg
rename to sound/vox/detonation.ogg
diff --git a/modular_citadel/sound/vox/device.ogg b/sound/vox/device.ogg
similarity index 100%
rename from modular_citadel/sound/vox/device.ogg
rename to sound/vox/device.ogg
diff --git a/modular_citadel/sound/vox/did.ogg b/sound/vox/did.ogg
similarity index 100%
rename from modular_citadel/sound/vox/did.ogg
rename to sound/vox/did.ogg
diff --git a/modular_citadel/sound/vox/die.ogg b/sound/vox/die.ogg
similarity index 100%
rename from modular_citadel/sound/vox/die.ogg
rename to sound/vox/die.ogg
diff --git a/modular_citadel/sound/vox/dimensional.ogg b/sound/vox/dimensional.ogg
similarity index 100%
rename from modular_citadel/sound/vox/dimensional.ogg
rename to sound/vox/dimensional.ogg
diff --git a/modular_citadel/sound/vox/dirt.ogg b/sound/vox/dirt.ogg
similarity index 100%
rename from modular_citadel/sound/vox/dirt.ogg
rename to sound/vox/dirt.ogg
diff --git a/modular_citadel/sound/vox/disengaged.ogg b/sound/vox/disengaged.ogg
similarity index 100%
rename from modular_citadel/sound/vox/disengaged.ogg
rename to sound/vox/disengaged.ogg
diff --git a/modular_citadel/sound/vox/dish.ogg b/sound/vox/dish.ogg
similarity index 100%
rename from modular_citadel/sound/vox/dish.ogg
rename to sound/vox/dish.ogg
diff --git a/modular_citadel/sound/vox/disposal.ogg b/sound/vox/disposal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/disposal.ogg
rename to sound/vox/disposal.ogg
diff --git a/modular_citadel/sound/vox/distance.ogg b/sound/vox/distance.ogg
similarity index 100%
rename from modular_citadel/sound/vox/distance.ogg
rename to sound/vox/distance.ogg
diff --git a/modular_citadel/sound/vox/distortion.ogg b/sound/vox/distortion.ogg
similarity index 100%
rename from modular_citadel/sound/vox/distortion.ogg
rename to sound/vox/distortion.ogg
diff --git a/modular_citadel/sound/vox/do.ogg b/sound/vox/do.ogg
similarity index 100%
rename from modular_citadel/sound/vox/do.ogg
rename to sound/vox/do.ogg
diff --git a/modular_citadel/sound/vox/doctor.ogg b/sound/vox/doctor.ogg
similarity index 100%
rename from modular_citadel/sound/vox/doctor.ogg
rename to sound/vox/doctor.ogg
diff --git a/modular_citadel/sound/vox/doop.ogg b/sound/vox/doop.ogg
similarity index 100%
rename from modular_citadel/sound/vox/doop.ogg
rename to sound/vox/doop.ogg
diff --git a/modular_citadel/sound/vox/door.ogg b/sound/vox/door.ogg
similarity index 100%
rename from modular_citadel/sound/vox/door.ogg
rename to sound/vox/door.ogg
diff --git a/modular_citadel/sound/vox/down.ogg b/sound/vox/down.ogg
similarity index 100%
rename from modular_citadel/sound/vox/down.ogg
rename to sound/vox/down.ogg
diff --git a/modular_citadel/sound/vox/dual.ogg b/sound/vox/dual.ogg
similarity index 100%
rename from modular_citadel/sound/vox/dual.ogg
rename to sound/vox/dual.ogg
diff --git a/modular_citadel/sound/vox/duct.ogg b/sound/vox/duct.ogg
similarity index 100%
rename from modular_citadel/sound/vox/duct.ogg
rename to sound/vox/duct.ogg
diff --git a/modular_citadel/sound/vox/e.ogg b/sound/vox/e.ogg
similarity index 100%
rename from modular_citadel/sound/vox/e.ogg
rename to sound/vox/e.ogg
diff --git a/modular_citadel/sound/vox/east.ogg b/sound/vox/east.ogg
similarity index 100%
rename from modular_citadel/sound/vox/east.ogg
rename to sound/vox/east.ogg
diff --git a/modular_citadel/sound/vox/echo.ogg b/sound/vox/echo.ogg
similarity index 100%
rename from modular_citadel/sound/vox/echo.ogg
rename to sound/vox/echo.ogg
diff --git a/modular_citadel/sound/vox/ed.ogg b/sound/vox/ed.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ed.ogg
rename to sound/vox/ed.ogg
diff --git a/modular_citadel/sound/vox/effect.ogg b/sound/vox/effect.ogg
similarity index 100%
rename from modular_citadel/sound/vox/effect.ogg
rename to sound/vox/effect.ogg
diff --git a/modular_citadel/sound/vox/egress.ogg b/sound/vox/egress.ogg
similarity index 100%
rename from modular_citadel/sound/vox/egress.ogg
rename to sound/vox/egress.ogg
diff --git a/modular_citadel/sound/vox/eight.ogg b/sound/vox/eight.ogg
similarity index 100%
rename from modular_citadel/sound/vox/eight.ogg
rename to sound/vox/eight.ogg
diff --git a/modular_citadel/sound/vox/eighteen.ogg b/sound/vox/eighteen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/eighteen.ogg
rename to sound/vox/eighteen.ogg
diff --git a/modular_citadel/sound/vox/eighty.ogg b/sound/vox/eighty.ogg
similarity index 100%
rename from modular_citadel/sound/vox/eighty.ogg
rename to sound/vox/eighty.ogg
diff --git a/modular_citadel/sound/vox/electric.ogg b/sound/vox/electric.ogg
similarity index 100%
rename from modular_citadel/sound/vox/electric.ogg
rename to sound/vox/electric.ogg
diff --git a/modular_citadel/sound/vox/electromagnetic.ogg b/sound/vox/electromagnetic.ogg
similarity index 100%
rename from modular_citadel/sound/vox/electromagnetic.ogg
rename to sound/vox/electromagnetic.ogg
diff --git a/modular_citadel/sound/vox/elevator.ogg b/sound/vox/elevator.ogg
similarity index 100%
rename from modular_citadel/sound/vox/elevator.ogg
rename to sound/vox/elevator.ogg
diff --git a/modular_citadel/sound/vox/eleven.ogg b/sound/vox/eleven.ogg
similarity index 100%
rename from modular_citadel/sound/vox/eleven.ogg
rename to sound/vox/eleven.ogg
diff --git a/modular_citadel/sound/vox/eliminate.ogg b/sound/vox/eliminate.ogg
similarity index 100%
rename from modular_citadel/sound/vox/eliminate.ogg
rename to sound/vox/eliminate.ogg
diff --git a/modular_citadel/sound/vox/emergency.ogg b/sound/vox/emergency.ogg
similarity index 100%
rename from modular_citadel/sound/vox/emergency.ogg
rename to sound/vox/emergency.ogg
diff --git a/modular_citadel/sound/vox/enemy.ogg b/sound/vox/enemy.ogg
similarity index 100%
rename from modular_citadel/sound/vox/enemy.ogg
rename to sound/vox/enemy.ogg
diff --git a/modular_citadel/sound/vox/energy.ogg b/sound/vox/energy.ogg
similarity index 100%
rename from modular_citadel/sound/vox/energy.ogg
rename to sound/vox/energy.ogg
diff --git a/modular_citadel/sound/vox/engage.ogg b/sound/vox/engage.ogg
similarity index 100%
rename from modular_citadel/sound/vox/engage.ogg
rename to sound/vox/engage.ogg
diff --git a/modular_citadel/sound/vox/engaged.ogg b/sound/vox/engaged.ogg
similarity index 100%
rename from modular_citadel/sound/vox/engaged.ogg
rename to sound/vox/engaged.ogg
diff --git a/modular_citadel/sound/vox/engine.ogg b/sound/vox/engine.ogg
similarity index 100%
rename from modular_citadel/sound/vox/engine.ogg
rename to sound/vox/engine.ogg
diff --git a/modular_citadel/sound/vox/enter.ogg b/sound/vox/enter.ogg
similarity index 100%
rename from modular_citadel/sound/vox/enter.ogg
rename to sound/vox/enter.ogg
diff --git a/modular_citadel/sound/vox/entry.ogg b/sound/vox/entry.ogg
similarity index 100%
rename from modular_citadel/sound/vox/entry.ogg
rename to sound/vox/entry.ogg
diff --git a/modular_citadel/sound/vox/environment.ogg b/sound/vox/environment.ogg
similarity index 100%
rename from modular_citadel/sound/vox/environment.ogg
rename to sound/vox/environment.ogg
diff --git a/modular_citadel/sound/vox/error.ogg b/sound/vox/error.ogg
similarity index 100%
rename from modular_citadel/sound/vox/error.ogg
rename to sound/vox/error.ogg
diff --git a/modular_citadel/sound/vox/escape.ogg b/sound/vox/escape.ogg
similarity index 100%
rename from modular_citadel/sound/vox/escape.ogg
rename to sound/vox/escape.ogg
diff --git a/modular_citadel/sound/vox/evacuate.ogg b/sound/vox/evacuate.ogg
similarity index 100%
rename from modular_citadel/sound/vox/evacuate.ogg
rename to sound/vox/evacuate.ogg
diff --git a/modular_citadel/sound/vox/exchange.ogg b/sound/vox/exchange.ogg
similarity index 100%
rename from modular_citadel/sound/vox/exchange.ogg
rename to sound/vox/exchange.ogg
diff --git a/modular_citadel/sound/vox/exit.ogg b/sound/vox/exit.ogg
similarity index 100%
rename from modular_citadel/sound/vox/exit.ogg
rename to sound/vox/exit.ogg
diff --git a/modular_citadel/sound/vox/expect.ogg b/sound/vox/expect.ogg
similarity index 100%
rename from modular_citadel/sound/vox/expect.ogg
rename to sound/vox/expect.ogg
diff --git a/modular_citadel/sound/vox/experiment.ogg b/sound/vox/experiment.ogg
similarity index 100%
rename from modular_citadel/sound/vox/experiment.ogg
rename to sound/vox/experiment.ogg
diff --git a/modular_citadel/sound/vox/experimental.ogg b/sound/vox/experimental.ogg
similarity index 100%
rename from modular_citadel/sound/vox/experimental.ogg
rename to sound/vox/experimental.ogg
diff --git a/modular_citadel/sound/vox/explode.ogg b/sound/vox/explode.ogg
similarity index 100%
rename from modular_citadel/sound/vox/explode.ogg
rename to sound/vox/explode.ogg
diff --git a/modular_citadel/sound/vox/explosion.ogg b/sound/vox/explosion.ogg
similarity index 100%
rename from modular_citadel/sound/vox/explosion.ogg
rename to sound/vox/explosion.ogg
diff --git a/modular_citadel/sound/vox/exposure.ogg b/sound/vox/exposure.ogg
similarity index 100%
rename from modular_citadel/sound/vox/exposure.ogg
rename to sound/vox/exposure.ogg
diff --git a/modular_citadel/sound/vox/exterminate.ogg b/sound/vox/exterminate.ogg
similarity index 100%
rename from modular_citadel/sound/vox/exterminate.ogg
rename to sound/vox/exterminate.ogg
diff --git a/modular_citadel/sound/vox/extinguish.ogg b/sound/vox/extinguish.ogg
similarity index 100%
rename from modular_citadel/sound/vox/extinguish.ogg
rename to sound/vox/extinguish.ogg
diff --git a/modular_citadel/sound/vox/extinguisher.ogg b/sound/vox/extinguisher.ogg
similarity index 100%
rename from modular_citadel/sound/vox/extinguisher.ogg
rename to sound/vox/extinguisher.ogg
diff --git a/modular_citadel/sound/vox/extreme.ogg b/sound/vox/extreme.ogg
similarity index 100%
rename from modular_citadel/sound/vox/extreme.ogg
rename to sound/vox/extreme.ogg
diff --git a/modular_citadel/sound/vox/f.ogg b/sound/vox/f.ogg
similarity index 100%
rename from modular_citadel/sound/vox/f.ogg
rename to sound/vox/f.ogg
diff --git a/modular_citadel/sound/vox/face.ogg b/sound/vox/face.ogg
similarity index 100%
rename from modular_citadel/sound/vox/face.ogg
rename to sound/vox/face.ogg
diff --git a/modular_citadel/sound/vox/facility.ogg b/sound/vox/facility.ogg
similarity index 100%
rename from modular_citadel/sound/vox/facility.ogg
rename to sound/vox/facility.ogg
diff --git a/modular_citadel/sound/vox/fahrenheit.ogg b/sound/vox/fahrenheit.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fahrenheit.ogg
rename to sound/vox/fahrenheit.ogg
diff --git a/modular_citadel/sound/vox/failed.ogg b/sound/vox/failed.ogg
similarity index 100%
rename from modular_citadel/sound/vox/failed.ogg
rename to sound/vox/failed.ogg
diff --git a/modular_citadel/sound/vox/failure.ogg b/sound/vox/failure.ogg
similarity index 100%
rename from modular_citadel/sound/vox/failure.ogg
rename to sound/vox/failure.ogg
diff --git a/modular_citadel/sound/vox/farthest.ogg b/sound/vox/farthest.ogg
similarity index 100%
rename from modular_citadel/sound/vox/farthest.ogg
rename to sound/vox/farthest.ogg
diff --git a/modular_citadel/sound/vox/fast.ogg b/sound/vox/fast.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fast.ogg
rename to sound/vox/fast.ogg
diff --git a/modular_citadel/sound/vox/feet.ogg b/sound/vox/feet.ogg
similarity index 100%
rename from modular_citadel/sound/vox/feet.ogg
rename to sound/vox/feet.ogg
diff --git a/modular_citadel/sound/vox/field.ogg b/sound/vox/field.ogg
similarity index 100%
rename from modular_citadel/sound/vox/field.ogg
rename to sound/vox/field.ogg
diff --git a/modular_citadel/sound/vox/fifteen.ogg b/sound/vox/fifteen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fifteen.ogg
rename to sound/vox/fifteen.ogg
diff --git a/modular_citadel/sound/vox/fifth.ogg b/sound/vox/fifth.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fifth.ogg
rename to sound/vox/fifth.ogg
diff --git a/modular_citadel/sound/vox/fifty.ogg b/sound/vox/fifty.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fifty.ogg
rename to sound/vox/fifty.ogg
diff --git a/modular_citadel/sound/vox/final.ogg b/sound/vox/final.ogg
similarity index 100%
rename from modular_citadel/sound/vox/final.ogg
rename to sound/vox/final.ogg
diff --git a/modular_citadel/sound/vox/fine.ogg b/sound/vox/fine.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fine.ogg
rename to sound/vox/fine.ogg
diff --git a/modular_citadel/sound/vox/fire.ogg b/sound/vox/fire.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fire.ogg
rename to sound/vox/fire.ogg
diff --git a/modular_citadel/sound/vox/first.ogg b/sound/vox/first.ogg
similarity index 100%
rename from modular_citadel/sound/vox/first.ogg
rename to sound/vox/first.ogg
diff --git a/modular_citadel/sound/vox/five.ogg b/sound/vox/five.ogg
similarity index 100%
rename from modular_citadel/sound/vox/five.ogg
rename to sound/vox/five.ogg
diff --git a/modular_citadel/sound/vox/flag.ogg b/sound/vox/flag.ogg
similarity index 100%
rename from modular_citadel/sound/vox/flag.ogg
rename to sound/vox/flag.ogg
diff --git a/modular_citadel/sound/vox/flooding.ogg b/sound/vox/flooding.ogg
similarity index 100%
rename from modular_citadel/sound/vox/flooding.ogg
rename to sound/vox/flooding.ogg
diff --git a/modular_citadel/sound/vox/floor.ogg b/sound/vox/floor.ogg
similarity index 100%
rename from modular_citadel/sound/vox/floor.ogg
rename to sound/vox/floor.ogg
diff --git a/modular_citadel/sound/vox/fool.ogg b/sound/vox/fool.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fool.ogg
rename to sound/vox/fool.ogg
diff --git a/modular_citadel/sound/vox/for.ogg b/sound/vox/for.ogg
similarity index 100%
rename from modular_citadel/sound/vox/for.ogg
rename to sound/vox/for.ogg
diff --git a/modular_citadel/sound/vox/forbidden.ogg b/sound/vox/forbidden.ogg
similarity index 100%
rename from modular_citadel/sound/vox/forbidden.ogg
rename to sound/vox/forbidden.ogg
diff --git a/modular_citadel/sound/vox/force.ogg b/sound/vox/force.ogg
similarity index 100%
rename from modular_citadel/sound/vox/force.ogg
rename to sound/vox/force.ogg
diff --git a/modular_citadel/sound/vox/forms.ogg b/sound/vox/forms.ogg
similarity index 100%
rename from modular_citadel/sound/vox/forms.ogg
rename to sound/vox/forms.ogg
diff --git a/modular_citadel/sound/vox/found.ogg b/sound/vox/found.ogg
similarity index 100%
rename from modular_citadel/sound/vox/found.ogg
rename to sound/vox/found.ogg
diff --git a/modular_citadel/sound/vox/four.ogg b/sound/vox/four.ogg
similarity index 100%
rename from modular_citadel/sound/vox/four.ogg
rename to sound/vox/four.ogg
diff --git a/modular_citadel/sound/vox/fourteen.ogg b/sound/vox/fourteen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fourteen.ogg
rename to sound/vox/fourteen.ogg
diff --git a/modular_citadel/sound/vox/fourth.ogg b/sound/vox/fourth.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fourth.ogg
rename to sound/vox/fourth.ogg
diff --git a/modular_citadel/sound/vox/fourty.ogg b/sound/vox/fourty.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fourty.ogg
rename to sound/vox/fourty.ogg
diff --git a/modular_citadel/sound/vox/foxtrot.ogg b/sound/vox/foxtrot.ogg
similarity index 100%
rename from modular_citadel/sound/vox/foxtrot.ogg
rename to sound/vox/foxtrot.ogg
diff --git a/modular_citadel/sound/vox/freeman.ogg b/sound/vox/freeman.ogg
similarity index 100%
rename from modular_citadel/sound/vox/freeman.ogg
rename to sound/vox/freeman.ogg
diff --git a/modular_citadel/sound/vox/freezer.ogg b/sound/vox/freezer.ogg
similarity index 100%
rename from modular_citadel/sound/vox/freezer.ogg
rename to sound/vox/freezer.ogg
diff --git a/modular_citadel/sound/vox/from.ogg b/sound/vox/from.ogg
similarity index 100%
rename from modular_citadel/sound/vox/from.ogg
rename to sound/vox/from.ogg
diff --git a/modular_citadel/sound/vox/front.ogg b/sound/vox/front.ogg
similarity index 100%
rename from modular_citadel/sound/vox/front.ogg
rename to sound/vox/front.ogg
diff --git a/modular_citadel/sound/vox/fuel.ogg b/sound/vox/fuel.ogg
similarity index 100%
rename from modular_citadel/sound/vox/fuel.ogg
rename to sound/vox/fuel.ogg
diff --git a/modular_citadel/sound/vox/g.ogg b/sound/vox/g.ogg
similarity index 100%
rename from modular_citadel/sound/vox/g.ogg
rename to sound/vox/g.ogg
diff --git a/modular_citadel/sound/vox/gay.ogg b/sound/vox/gay.ogg
similarity index 100%
rename from modular_citadel/sound/vox/gay.ogg
rename to sound/vox/gay.ogg
diff --git a/modular_citadel/sound/vox/get.ogg b/sound/vox/get.ogg
similarity index 100%
rename from modular_citadel/sound/vox/get.ogg
rename to sound/vox/get.ogg
diff --git a/modular_citadel/sound/vox/go.ogg b/sound/vox/go.ogg
similarity index 100%
rename from modular_citadel/sound/vox/go.ogg
rename to sound/vox/go.ogg
diff --git a/modular_citadel/sound/vox/going.ogg b/sound/vox/going.ogg
similarity index 100%
rename from modular_citadel/sound/vox/going.ogg
rename to sound/vox/going.ogg
diff --git a/modular_citadel/sound/vox/good.ogg b/sound/vox/good.ogg
similarity index 100%
rename from modular_citadel/sound/vox/good.ogg
rename to sound/vox/good.ogg
diff --git a/modular_citadel/sound/vox/goodbye.ogg b/sound/vox/goodbye.ogg
similarity index 100%
rename from modular_citadel/sound/vox/goodbye.ogg
rename to sound/vox/goodbye.ogg
diff --git a/modular_citadel/sound/vox/gordon.ogg b/sound/vox/gordon.ogg
similarity index 100%
rename from modular_citadel/sound/vox/gordon.ogg
rename to sound/vox/gordon.ogg
diff --git a/modular_citadel/sound/vox/got.ogg b/sound/vox/got.ogg
similarity index 100%
rename from modular_citadel/sound/vox/got.ogg
rename to sound/vox/got.ogg
diff --git a/modular_citadel/sound/vox/government.ogg b/sound/vox/government.ogg
similarity index 100%
rename from modular_citadel/sound/vox/government.ogg
rename to sound/vox/government.ogg
diff --git a/modular_citadel/sound/vox/granted.ogg b/sound/vox/granted.ogg
similarity index 100%
rename from modular_citadel/sound/vox/granted.ogg
rename to sound/vox/granted.ogg
diff --git a/modular_citadel/sound/vox/great.ogg b/sound/vox/great.ogg
similarity index 100%
rename from modular_citadel/sound/vox/great.ogg
rename to sound/vox/great.ogg
diff --git a/modular_citadel/sound/vox/green.ogg b/sound/vox/green.ogg
similarity index 100%
rename from modular_citadel/sound/vox/green.ogg
rename to sound/vox/green.ogg
diff --git a/modular_citadel/sound/vox/grenade.ogg b/sound/vox/grenade.ogg
similarity index 100%
rename from modular_citadel/sound/vox/grenade.ogg
rename to sound/vox/grenade.ogg
diff --git a/modular_citadel/sound/vox/guard.ogg b/sound/vox/guard.ogg
similarity index 100%
rename from modular_citadel/sound/vox/guard.ogg
rename to sound/vox/guard.ogg
diff --git a/modular_citadel/sound/vox/gulf.ogg b/sound/vox/gulf.ogg
similarity index 100%
rename from modular_citadel/sound/vox/gulf.ogg
rename to sound/vox/gulf.ogg
diff --git a/modular_citadel/sound/vox/gun.ogg b/sound/vox/gun.ogg
similarity index 100%
rename from modular_citadel/sound/vox/gun.ogg
rename to sound/vox/gun.ogg
diff --git a/modular_citadel/sound/vox/guthrie.ogg b/sound/vox/guthrie.ogg
similarity index 100%
rename from modular_citadel/sound/vox/guthrie.ogg
rename to sound/vox/guthrie.ogg
diff --git a/modular_citadel/sound/vox/handling.ogg b/sound/vox/handling.ogg
similarity index 100%
rename from modular_citadel/sound/vox/handling.ogg
rename to sound/vox/handling.ogg
diff --git a/modular_citadel/sound/vox/hangar.ogg b/sound/vox/hangar.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hangar.ogg
rename to sound/vox/hangar.ogg
diff --git a/modular_citadel/sound/vox/has.ogg b/sound/vox/has.ogg
similarity index 100%
rename from modular_citadel/sound/vox/has.ogg
rename to sound/vox/has.ogg
diff --git a/modular_citadel/sound/vox/have.ogg b/sound/vox/have.ogg
similarity index 100%
rename from modular_citadel/sound/vox/have.ogg
rename to sound/vox/have.ogg
diff --git a/modular_citadel/sound/vox/hazard.ogg b/sound/vox/hazard.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hazard.ogg
rename to sound/vox/hazard.ogg
diff --git a/modular_citadel/sound/vox/head.ogg b/sound/vox/head.ogg
similarity index 100%
rename from modular_citadel/sound/vox/head.ogg
rename to sound/vox/head.ogg
diff --git a/modular_citadel/sound/vox/health.ogg b/sound/vox/health.ogg
similarity index 100%
rename from modular_citadel/sound/vox/health.ogg
rename to sound/vox/health.ogg
diff --git a/modular_citadel/sound/vox/heat.ogg b/sound/vox/heat.ogg
similarity index 100%
rename from modular_citadel/sound/vox/heat.ogg
rename to sound/vox/heat.ogg
diff --git a/modular_citadel/sound/vox/helicopter.ogg b/sound/vox/helicopter.ogg
similarity index 100%
rename from modular_citadel/sound/vox/helicopter.ogg
rename to sound/vox/helicopter.ogg
diff --git a/modular_citadel/sound/vox/helium.ogg b/sound/vox/helium.ogg
similarity index 100%
rename from modular_citadel/sound/vox/helium.ogg
rename to sound/vox/helium.ogg
diff --git a/modular_citadel/sound/vox/hello.ogg b/sound/vox/hello.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hello.ogg
rename to sound/vox/hello.ogg
diff --git a/modular_citadel/sound/vox/help.ogg b/sound/vox/help.ogg
similarity index 100%
rename from modular_citadel/sound/vox/help.ogg
rename to sound/vox/help.ogg
diff --git a/modular_citadel/sound/vox/here.ogg b/sound/vox/here.ogg
similarity index 100%
rename from modular_citadel/sound/vox/here.ogg
rename to sound/vox/here.ogg
diff --git a/modular_citadel/sound/vox/hide.ogg b/sound/vox/hide.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hide.ogg
rename to sound/vox/hide.ogg
diff --git a/modular_citadel/sound/vox/high.ogg b/sound/vox/high.ogg
similarity index 100%
rename from modular_citadel/sound/vox/high.ogg
rename to sound/vox/high.ogg
diff --git a/modular_citadel/sound/vox/highest.ogg b/sound/vox/highest.ogg
similarity index 100%
rename from modular_citadel/sound/vox/highest.ogg
rename to sound/vox/highest.ogg
diff --git a/modular_citadel/sound/vox/hit.ogg b/sound/vox/hit.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hit.ogg
rename to sound/vox/hit.ogg
diff --git a/modular_citadel/sound/vox/holds.ogg b/sound/vox/holds.ogg
similarity index 100%
rename from modular_citadel/sound/vox/holds.ogg
rename to sound/vox/holds.ogg
diff --git a/modular_citadel/sound/vox/hole.ogg b/sound/vox/hole.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hole.ogg
rename to sound/vox/hole.ogg
diff --git a/modular_citadel/sound/vox/hostile.ogg b/sound/vox/hostile.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hostile.ogg
rename to sound/vox/hostile.ogg
diff --git a/modular_citadel/sound/vox/hot.ogg b/sound/vox/hot.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hot.ogg
rename to sound/vox/hot.ogg
diff --git a/modular_citadel/sound/vox/hotel.ogg b/sound/vox/hotel.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hotel.ogg
rename to sound/vox/hotel.ogg
diff --git a/modular_citadel/sound/vox/hour.ogg b/sound/vox/hour.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hour.ogg
rename to sound/vox/hour.ogg
diff --git a/modular_citadel/sound/vox/hours.ogg b/sound/vox/hours.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hours.ogg
rename to sound/vox/hours.ogg
diff --git a/modular_citadel/sound/vox/hundred.ogg b/sound/vox/hundred.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hundred.ogg
rename to sound/vox/hundred.ogg
diff --git a/modular_citadel/sound/vox/hydro.ogg b/sound/vox/hydro.ogg
similarity index 100%
rename from modular_citadel/sound/vox/hydro.ogg
rename to sound/vox/hydro.ogg
diff --git a/modular_citadel/sound/vox/i.ogg b/sound/vox/i.ogg
similarity index 100%
rename from modular_citadel/sound/vox/i.ogg
rename to sound/vox/i.ogg
diff --git a/modular_citadel/sound/vox/idiot.ogg b/sound/vox/idiot.ogg
similarity index 100%
rename from modular_citadel/sound/vox/idiot.ogg
rename to sound/vox/idiot.ogg
diff --git a/modular_citadel/sound/vox/illegal.ogg b/sound/vox/illegal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/illegal.ogg
rename to sound/vox/illegal.ogg
diff --git a/modular_citadel/sound/vox/immediate.ogg b/sound/vox/immediate.ogg
similarity index 100%
rename from modular_citadel/sound/vox/immediate.ogg
rename to sound/vox/immediate.ogg
diff --git a/modular_citadel/sound/vox/immediately.ogg b/sound/vox/immediately.ogg
similarity index 100%
rename from modular_citadel/sound/vox/immediately.ogg
rename to sound/vox/immediately.ogg
diff --git a/modular_citadel/sound/vox/in.ogg b/sound/vox/in.ogg
similarity index 100%
rename from modular_citadel/sound/vox/in.ogg
rename to sound/vox/in.ogg
diff --git a/modular_citadel/sound/vox/inches.ogg b/sound/vox/inches.ogg
similarity index 100%
rename from modular_citadel/sound/vox/inches.ogg
rename to sound/vox/inches.ogg
diff --git a/modular_citadel/sound/vox/india.ogg b/sound/vox/india.ogg
similarity index 100%
rename from modular_citadel/sound/vox/india.ogg
rename to sound/vox/india.ogg
diff --git a/modular_citadel/sound/vox/ing.ogg b/sound/vox/ing.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ing.ogg
rename to sound/vox/ing.ogg
diff --git a/modular_citadel/sound/vox/inoperative.ogg b/sound/vox/inoperative.ogg
similarity index 100%
rename from modular_citadel/sound/vox/inoperative.ogg
rename to sound/vox/inoperative.ogg
diff --git a/modular_citadel/sound/vox/inside.ogg b/sound/vox/inside.ogg
similarity index 100%
rename from modular_citadel/sound/vox/inside.ogg
rename to sound/vox/inside.ogg
diff --git a/modular_citadel/sound/vox/inspection.ogg b/sound/vox/inspection.ogg
similarity index 100%
rename from modular_citadel/sound/vox/inspection.ogg
rename to sound/vox/inspection.ogg
diff --git a/modular_citadel/sound/vox/inspector.ogg b/sound/vox/inspector.ogg
similarity index 100%
rename from modular_citadel/sound/vox/inspector.ogg
rename to sound/vox/inspector.ogg
diff --git a/modular_citadel/sound/vox/interchange.ogg b/sound/vox/interchange.ogg
similarity index 100%
rename from modular_citadel/sound/vox/interchange.ogg
rename to sound/vox/interchange.ogg
diff --git a/modular_citadel/sound/vox/intruder.ogg b/sound/vox/intruder.ogg
similarity index 100%
rename from modular_citadel/sound/vox/intruder.ogg
rename to sound/vox/intruder.ogg
diff --git a/modular_citadel/sound/vox/invallid.ogg b/sound/vox/invallid.ogg
similarity index 100%
rename from modular_citadel/sound/vox/invallid.ogg
rename to sound/vox/invallid.ogg
diff --git a/modular_citadel/sound/vox/invasion.ogg b/sound/vox/invasion.ogg
similarity index 100%
rename from modular_citadel/sound/vox/invasion.ogg
rename to sound/vox/invasion.ogg
diff --git a/modular_citadel/sound/vox/is.ogg b/sound/vox/is.ogg
similarity index 100%
rename from modular_citadel/sound/vox/is.ogg
rename to sound/vox/is.ogg
diff --git a/modular_citadel/sound/vox/it.ogg b/sound/vox/it.ogg
similarity index 100%
rename from modular_citadel/sound/vox/it.ogg
rename to sound/vox/it.ogg
diff --git a/modular_citadel/sound/vox/johnson.ogg b/sound/vox/johnson.ogg
similarity index 100%
rename from modular_citadel/sound/vox/johnson.ogg
rename to sound/vox/johnson.ogg
diff --git a/modular_citadel/sound/vox/juliet.ogg b/sound/vox/juliet.ogg
similarity index 100%
rename from modular_citadel/sound/vox/juliet.ogg
rename to sound/vox/juliet.ogg
diff --git a/modular_citadel/sound/vox/key.ogg b/sound/vox/key.ogg
similarity index 100%
rename from modular_citadel/sound/vox/key.ogg
rename to sound/vox/key.ogg
diff --git a/modular_citadel/sound/vox/kill.ogg b/sound/vox/kill.ogg
similarity index 100%
rename from modular_citadel/sound/vox/kill.ogg
rename to sound/vox/kill.ogg
diff --git a/modular_citadel/sound/vox/kilo.ogg b/sound/vox/kilo.ogg
similarity index 100%
rename from modular_citadel/sound/vox/kilo.ogg
rename to sound/vox/kilo.ogg
diff --git a/modular_citadel/sound/vox/kit.ogg b/sound/vox/kit.ogg
similarity index 100%
rename from modular_citadel/sound/vox/kit.ogg
rename to sound/vox/kit.ogg
diff --git a/modular_citadel/sound/vox/lab.ogg b/sound/vox/lab.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lab.ogg
rename to sound/vox/lab.ogg
diff --git a/modular_citadel/sound/vox/lambda.ogg b/sound/vox/lambda.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lambda.ogg
rename to sound/vox/lambda.ogg
diff --git a/modular_citadel/sound/vox/laser.ogg b/sound/vox/laser.ogg
similarity index 100%
rename from modular_citadel/sound/vox/laser.ogg
rename to sound/vox/laser.ogg
diff --git a/modular_citadel/sound/vox/last.ogg b/sound/vox/last.ogg
similarity index 100%
rename from modular_citadel/sound/vox/last.ogg
rename to sound/vox/last.ogg
diff --git a/modular_citadel/sound/vox/launch.ogg b/sound/vox/launch.ogg
similarity index 100%
rename from modular_citadel/sound/vox/launch.ogg
rename to sound/vox/launch.ogg
diff --git a/modular_citadel/sound/vox/leak.ogg b/sound/vox/leak.ogg
similarity index 100%
rename from modular_citadel/sound/vox/leak.ogg
rename to sound/vox/leak.ogg
diff --git a/modular_citadel/sound/vox/leave.ogg b/sound/vox/leave.ogg
similarity index 100%
rename from modular_citadel/sound/vox/leave.ogg
rename to sound/vox/leave.ogg
diff --git a/modular_citadel/sound/vox/left.ogg b/sound/vox/left.ogg
similarity index 100%
rename from modular_citadel/sound/vox/left.ogg
rename to sound/vox/left.ogg
diff --git a/modular_citadel/sound/vox/legal.ogg b/sound/vox/legal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/legal.ogg
rename to sound/vox/legal.ogg
diff --git a/modular_citadel/sound/vox/level.ogg b/sound/vox/level.ogg
similarity index 100%
rename from modular_citadel/sound/vox/level.ogg
rename to sound/vox/level.ogg
diff --git a/modular_citadel/sound/vox/lever.ogg b/sound/vox/lever.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lever.ogg
rename to sound/vox/lever.ogg
diff --git a/modular_citadel/sound/vox/lie.ogg b/sound/vox/lie.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lie.ogg
rename to sound/vox/lie.ogg
diff --git a/modular_citadel/sound/vox/lieutenant.ogg b/sound/vox/lieutenant.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lieutenant.ogg
rename to sound/vox/lieutenant.ogg
diff --git a/modular_citadel/sound/vox/life.ogg b/sound/vox/life.ogg
similarity index 100%
rename from modular_citadel/sound/vox/life.ogg
rename to sound/vox/life.ogg
diff --git a/modular_citadel/sound/vox/light.ogg b/sound/vox/light.ogg
similarity index 100%
rename from modular_citadel/sound/vox/light.ogg
rename to sound/vox/light.ogg
diff --git a/modular_citadel/sound/vox/lima.ogg b/sound/vox/lima.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lima.ogg
rename to sound/vox/lima.ogg
diff --git a/modular_citadel/sound/vox/liquid.ogg b/sound/vox/liquid.ogg
similarity index 100%
rename from modular_citadel/sound/vox/liquid.ogg
rename to sound/vox/liquid.ogg
diff --git a/modular_citadel/sound/vox/loading.ogg b/sound/vox/loading.ogg
similarity index 100%
rename from modular_citadel/sound/vox/loading.ogg
rename to sound/vox/loading.ogg
diff --git a/modular_citadel/sound/vox/locate.ogg b/sound/vox/locate.ogg
similarity index 100%
rename from modular_citadel/sound/vox/locate.ogg
rename to sound/vox/locate.ogg
diff --git a/modular_citadel/sound/vox/located.ogg b/sound/vox/located.ogg
similarity index 100%
rename from modular_citadel/sound/vox/located.ogg
rename to sound/vox/located.ogg
diff --git a/modular_citadel/sound/vox/location.ogg b/sound/vox/location.ogg
similarity index 100%
rename from modular_citadel/sound/vox/location.ogg
rename to sound/vox/location.ogg
diff --git a/modular_citadel/sound/vox/lock.ogg b/sound/vox/lock.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lock.ogg
rename to sound/vox/lock.ogg
diff --git a/modular_citadel/sound/vox/locked.ogg b/sound/vox/locked.ogg
similarity index 100%
rename from modular_citadel/sound/vox/locked.ogg
rename to sound/vox/locked.ogg
diff --git a/modular_citadel/sound/vox/locker.ogg b/sound/vox/locker.ogg
similarity index 100%
rename from modular_citadel/sound/vox/locker.ogg
rename to sound/vox/locker.ogg
diff --git a/modular_citadel/sound/vox/lockout.ogg b/sound/vox/lockout.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lockout.ogg
rename to sound/vox/lockout.ogg
diff --git a/modular_citadel/sound/vox/lower.ogg b/sound/vox/lower.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lower.ogg
rename to sound/vox/lower.ogg
diff --git a/modular_citadel/sound/vox/lowest.ogg b/sound/vox/lowest.ogg
similarity index 100%
rename from modular_citadel/sound/vox/lowest.ogg
rename to sound/vox/lowest.ogg
diff --git a/modular_citadel/sound/vox/magnetic.ogg b/sound/vox/magnetic.ogg
similarity index 100%
rename from modular_citadel/sound/vox/magnetic.ogg
rename to sound/vox/magnetic.ogg
diff --git a/modular_citadel/sound/vox/main.ogg b/sound/vox/main.ogg
similarity index 100%
rename from modular_citadel/sound/vox/main.ogg
rename to sound/vox/main.ogg
diff --git a/modular_citadel/sound/vox/maintenance.ogg b/sound/vox/maintenance.ogg
similarity index 100%
rename from modular_citadel/sound/vox/maintenance.ogg
rename to sound/vox/maintenance.ogg
diff --git a/modular_citadel/sound/vox/malfunction.ogg b/sound/vox/malfunction.ogg
similarity index 100%
rename from modular_citadel/sound/vox/malfunction.ogg
rename to sound/vox/malfunction.ogg
diff --git a/modular_citadel/sound/vox/man.ogg b/sound/vox/man.ogg
similarity index 100%
rename from modular_citadel/sound/vox/man.ogg
rename to sound/vox/man.ogg
diff --git a/modular_citadel/sound/vox/mass.ogg b/sound/vox/mass.ogg
similarity index 100%
rename from modular_citadel/sound/vox/mass.ogg
rename to sound/vox/mass.ogg
diff --git a/modular_citadel/sound/vox/materials.ogg b/sound/vox/materials.ogg
similarity index 100%
rename from modular_citadel/sound/vox/materials.ogg
rename to sound/vox/materials.ogg
diff --git a/modular_citadel/sound/vox/maximum.ogg b/sound/vox/maximum.ogg
similarity index 100%
rename from modular_citadel/sound/vox/maximum.ogg
rename to sound/vox/maximum.ogg
diff --git a/modular_citadel/sound/vox/may.ogg b/sound/vox/may.ogg
similarity index 100%
rename from modular_citadel/sound/vox/may.ogg
rename to sound/vox/may.ogg
diff --git a/modular_citadel/sound/vox/med.ogg b/sound/vox/med.ogg
similarity index 100%
rename from modular_citadel/sound/vox/med.ogg
rename to sound/vox/med.ogg
diff --git a/modular_citadel/sound/vox/medical.ogg b/sound/vox/medical.ogg
similarity index 100%
rename from modular_citadel/sound/vox/medical.ogg
rename to sound/vox/medical.ogg
diff --git a/modular_citadel/sound/vox/men.ogg b/sound/vox/men.ogg
similarity index 100%
rename from modular_citadel/sound/vox/men.ogg
rename to sound/vox/men.ogg
diff --git a/modular_citadel/sound/vox/mercy.ogg b/sound/vox/mercy.ogg
similarity index 100%
rename from modular_citadel/sound/vox/mercy.ogg
rename to sound/vox/mercy.ogg
diff --git a/modular_citadel/sound/vox/mesa.ogg b/sound/vox/mesa.ogg
similarity index 100%
rename from modular_citadel/sound/vox/mesa.ogg
rename to sound/vox/mesa.ogg
diff --git a/modular_citadel/sound/vox/message.ogg b/sound/vox/message.ogg
similarity index 100%
rename from modular_citadel/sound/vox/message.ogg
rename to sound/vox/message.ogg
diff --git a/modular_citadel/sound/vox/meter.ogg b/sound/vox/meter.ogg
similarity index 100%
rename from modular_citadel/sound/vox/meter.ogg
rename to sound/vox/meter.ogg
diff --git a/modular_citadel/sound/vox/micro.ogg b/sound/vox/micro.ogg
similarity index 100%
rename from modular_citadel/sound/vox/micro.ogg
rename to sound/vox/micro.ogg
diff --git a/modular_citadel/sound/vox/middle.ogg b/sound/vox/middle.ogg
similarity index 100%
rename from modular_citadel/sound/vox/middle.ogg
rename to sound/vox/middle.ogg
diff --git a/modular_citadel/sound/vox/mike.ogg b/sound/vox/mike.ogg
similarity index 100%
rename from modular_citadel/sound/vox/mike.ogg
rename to sound/vox/mike.ogg
diff --git a/modular_citadel/sound/vox/miles.ogg b/sound/vox/miles.ogg
similarity index 100%
rename from modular_citadel/sound/vox/miles.ogg
rename to sound/vox/miles.ogg
diff --git a/modular_citadel/sound/vox/military.ogg b/sound/vox/military.ogg
similarity index 100%
rename from modular_citadel/sound/vox/military.ogg
rename to sound/vox/military.ogg
diff --git a/modular_citadel/sound/vox/milli.ogg b/sound/vox/milli.ogg
similarity index 100%
rename from modular_citadel/sound/vox/milli.ogg
rename to sound/vox/milli.ogg
diff --git a/modular_citadel/sound/vox/million.ogg b/sound/vox/million.ogg
similarity index 100%
rename from modular_citadel/sound/vox/million.ogg
rename to sound/vox/million.ogg
diff --git a/modular_citadel/sound/vox/minefield.ogg b/sound/vox/minefield.ogg
similarity index 100%
rename from modular_citadel/sound/vox/minefield.ogg
rename to sound/vox/minefield.ogg
diff --git a/modular_citadel/sound/vox/minimum.ogg b/sound/vox/minimum.ogg
similarity index 100%
rename from modular_citadel/sound/vox/minimum.ogg
rename to sound/vox/minimum.ogg
diff --git a/modular_citadel/sound/vox/minutes.ogg b/sound/vox/minutes.ogg
similarity index 100%
rename from modular_citadel/sound/vox/minutes.ogg
rename to sound/vox/minutes.ogg
diff --git a/modular_citadel/sound/vox/mister.ogg b/sound/vox/mister.ogg
similarity index 100%
rename from modular_citadel/sound/vox/mister.ogg
rename to sound/vox/mister.ogg
diff --git a/modular_citadel/sound/vox/mode.ogg b/sound/vox/mode.ogg
similarity index 100%
rename from modular_citadel/sound/vox/mode.ogg
rename to sound/vox/mode.ogg
diff --git a/modular_citadel/sound/vox/motor.ogg b/sound/vox/motor.ogg
similarity index 100%
rename from modular_citadel/sound/vox/motor.ogg
rename to sound/vox/motor.ogg
diff --git a/modular_citadel/sound/vox/motorpool.ogg b/sound/vox/motorpool.ogg
similarity index 100%
rename from modular_citadel/sound/vox/motorpool.ogg
rename to sound/vox/motorpool.ogg
diff --git a/modular_citadel/sound/vox/move.ogg b/sound/vox/move.ogg
similarity index 100%
rename from modular_citadel/sound/vox/move.ogg
rename to sound/vox/move.ogg
diff --git a/modular_citadel/sound/vox/must.ogg b/sound/vox/must.ogg
similarity index 100%
rename from modular_citadel/sound/vox/must.ogg
rename to sound/vox/must.ogg
diff --git a/modular_citadel/sound/vox/nearest.ogg b/sound/vox/nearest.ogg
similarity index 100%
rename from modular_citadel/sound/vox/nearest.ogg
rename to sound/vox/nearest.ogg
diff --git a/modular_citadel/sound/vox/nice.ogg b/sound/vox/nice.ogg
similarity index 100%
rename from modular_citadel/sound/vox/nice.ogg
rename to sound/vox/nice.ogg
diff --git a/modular_citadel/sound/vox/nine.ogg b/sound/vox/nine.ogg
similarity index 100%
rename from modular_citadel/sound/vox/nine.ogg
rename to sound/vox/nine.ogg
diff --git a/modular_citadel/sound/vox/nineteen.ogg b/sound/vox/nineteen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/nineteen.ogg
rename to sound/vox/nineteen.ogg
diff --git a/modular_citadel/sound/vox/ninety.ogg b/sound/vox/ninety.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ninety.ogg
rename to sound/vox/ninety.ogg
diff --git a/modular_citadel/sound/vox/no.ogg b/sound/vox/no.ogg
similarity index 100%
rename from modular_citadel/sound/vox/no.ogg
rename to sound/vox/no.ogg
diff --git a/modular_citadel/sound/vox/nominal.ogg b/sound/vox/nominal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/nominal.ogg
rename to sound/vox/nominal.ogg
diff --git a/modular_citadel/sound/vox/north.ogg b/sound/vox/north.ogg
similarity index 100%
rename from modular_citadel/sound/vox/north.ogg
rename to sound/vox/north.ogg
diff --git a/modular_citadel/sound/vox/not.ogg b/sound/vox/not.ogg
similarity index 100%
rename from modular_citadel/sound/vox/not.ogg
rename to sound/vox/not.ogg
diff --git a/modular_citadel/sound/vox/november.ogg b/sound/vox/november.ogg
similarity index 100%
rename from modular_citadel/sound/vox/november.ogg
rename to sound/vox/november.ogg
diff --git a/modular_citadel/sound/vox/now.ogg b/sound/vox/now.ogg
similarity index 100%
rename from modular_citadel/sound/vox/now.ogg
rename to sound/vox/now.ogg
diff --git a/modular_citadel/sound/vox/number.ogg b/sound/vox/number.ogg
similarity index 100%
rename from modular_citadel/sound/vox/number.ogg
rename to sound/vox/number.ogg
diff --git a/modular_citadel/sound/vox/objective.ogg b/sound/vox/objective.ogg
similarity index 100%
rename from modular_citadel/sound/vox/objective.ogg
rename to sound/vox/objective.ogg
diff --git a/modular_citadel/sound/vox/observation.ogg b/sound/vox/observation.ogg
similarity index 100%
rename from modular_citadel/sound/vox/observation.ogg
rename to sound/vox/observation.ogg
diff --git a/modular_citadel/sound/vox/of.ogg b/sound/vox/of.ogg
similarity index 100%
rename from modular_citadel/sound/vox/of.ogg
rename to sound/vox/of.ogg
diff --git a/modular_citadel/sound/vox/officer.ogg b/sound/vox/officer.ogg
similarity index 100%
rename from modular_citadel/sound/vox/officer.ogg
rename to sound/vox/officer.ogg
diff --git a/modular_citadel/sound/vox/ok.ogg b/sound/vox/ok.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ok.ogg
rename to sound/vox/ok.ogg
diff --git a/modular_citadel/sound/vox/on.ogg b/sound/vox/on.ogg
similarity index 100%
rename from modular_citadel/sound/vox/on.ogg
rename to sound/vox/on.ogg
diff --git a/modular_citadel/sound/vox/one.ogg b/sound/vox/one.ogg
similarity index 100%
rename from modular_citadel/sound/vox/one.ogg
rename to sound/vox/one.ogg
diff --git a/modular_citadel/sound/vox/open.ogg b/sound/vox/open.ogg
similarity index 100%
rename from modular_citadel/sound/vox/open.ogg
rename to sound/vox/open.ogg
diff --git a/modular_citadel/sound/vox/operating.ogg b/sound/vox/operating.ogg
similarity index 100%
rename from modular_citadel/sound/vox/operating.ogg
rename to sound/vox/operating.ogg
diff --git a/modular_citadel/sound/vox/operations.ogg b/sound/vox/operations.ogg
similarity index 100%
rename from modular_citadel/sound/vox/operations.ogg
rename to sound/vox/operations.ogg
diff --git a/modular_citadel/sound/vox/operative.ogg b/sound/vox/operative.ogg
similarity index 100%
rename from modular_citadel/sound/vox/operative.ogg
rename to sound/vox/operative.ogg
diff --git a/modular_citadel/sound/vox/option.ogg b/sound/vox/option.ogg
similarity index 100%
rename from modular_citadel/sound/vox/option.ogg
rename to sound/vox/option.ogg
diff --git a/modular_citadel/sound/vox/order.ogg b/sound/vox/order.ogg
similarity index 100%
rename from modular_citadel/sound/vox/order.ogg
rename to sound/vox/order.ogg
diff --git a/modular_citadel/sound/vox/organic.ogg b/sound/vox/organic.ogg
similarity index 100%
rename from modular_citadel/sound/vox/organic.ogg
rename to sound/vox/organic.ogg
diff --git a/modular_citadel/sound/vox/oscar.ogg b/sound/vox/oscar.ogg
similarity index 100%
rename from modular_citadel/sound/vox/oscar.ogg
rename to sound/vox/oscar.ogg
diff --git a/modular_citadel/sound/vox/out.ogg b/sound/vox/out.ogg
similarity index 100%
rename from modular_citadel/sound/vox/out.ogg
rename to sound/vox/out.ogg
diff --git a/modular_citadel/sound/vox/outside.ogg b/sound/vox/outside.ogg
similarity index 100%
rename from modular_citadel/sound/vox/outside.ogg
rename to sound/vox/outside.ogg
diff --git a/modular_citadel/sound/vox/over.ogg b/sound/vox/over.ogg
similarity index 100%
rename from modular_citadel/sound/vox/over.ogg
rename to sound/vox/over.ogg
diff --git a/modular_citadel/sound/vox/overload.ogg b/sound/vox/overload.ogg
similarity index 100%
rename from modular_citadel/sound/vox/overload.ogg
rename to sound/vox/overload.ogg
diff --git a/modular_citadel/sound/vox/override.ogg b/sound/vox/override.ogg
similarity index 100%
rename from modular_citadel/sound/vox/override.ogg
rename to sound/vox/override.ogg
diff --git a/modular_citadel/sound/vox/pacify.ogg b/sound/vox/pacify.ogg
similarity index 100%
rename from modular_citadel/sound/vox/pacify.ogg
rename to sound/vox/pacify.ogg
diff --git a/modular_citadel/sound/vox/pain.ogg b/sound/vox/pain.ogg
similarity index 100%
rename from modular_citadel/sound/vox/pain.ogg
rename to sound/vox/pain.ogg
diff --git a/modular_citadel/sound/vox/pal.ogg b/sound/vox/pal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/pal.ogg
rename to sound/vox/pal.ogg
diff --git a/modular_citadel/sound/vox/panel.ogg b/sound/vox/panel.ogg
similarity index 100%
rename from modular_citadel/sound/vox/panel.ogg
rename to sound/vox/panel.ogg
diff --git a/modular_citadel/sound/vox/percent.ogg b/sound/vox/percent.ogg
similarity index 100%
rename from modular_citadel/sound/vox/percent.ogg
rename to sound/vox/percent.ogg
diff --git a/modular_citadel/sound/vox/perimeter.ogg b/sound/vox/perimeter.ogg
similarity index 100%
rename from modular_citadel/sound/vox/perimeter.ogg
rename to sound/vox/perimeter.ogg
diff --git a/modular_citadel/sound/vox/period.ogg b/sound/vox/period.ogg
similarity index 100%
rename from modular_citadel/sound/vox/period.ogg
rename to sound/vox/period.ogg
diff --git a/modular_citadel/sound/vox/permitted.ogg b/sound/vox/permitted.ogg
similarity index 100%
rename from modular_citadel/sound/vox/permitted.ogg
rename to sound/vox/permitted.ogg
diff --git a/modular_citadel/sound/vox/personnel.ogg b/sound/vox/personnel.ogg
similarity index 100%
rename from modular_citadel/sound/vox/personnel.ogg
rename to sound/vox/personnel.ogg
diff --git a/modular_citadel/sound/vox/pipe.ogg b/sound/vox/pipe.ogg
similarity index 100%
rename from modular_citadel/sound/vox/pipe.ogg
rename to sound/vox/pipe.ogg
diff --git a/modular_citadel/sound/vox/plant.ogg b/sound/vox/plant.ogg
similarity index 100%
rename from modular_citadel/sound/vox/plant.ogg
rename to sound/vox/plant.ogg
diff --git a/modular_citadel/sound/vox/platform.ogg b/sound/vox/platform.ogg
similarity index 100%
rename from modular_citadel/sound/vox/platform.ogg
rename to sound/vox/platform.ogg
diff --git a/modular_citadel/sound/vox/please.ogg b/sound/vox/please.ogg
similarity index 100%
rename from modular_citadel/sound/vox/please.ogg
rename to sound/vox/please.ogg
diff --git a/modular_citadel/sound/vox/point.ogg b/sound/vox/point.ogg
similarity index 100%
rename from modular_citadel/sound/vox/point.ogg
rename to sound/vox/point.ogg
diff --git a/modular_citadel/sound/vox/portal.ogg b/sound/vox/portal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/portal.ogg
rename to sound/vox/portal.ogg
diff --git a/modular_citadel/sound/vox/power.ogg b/sound/vox/power.ogg
similarity index 100%
rename from modular_citadel/sound/vox/power.ogg
rename to sound/vox/power.ogg
diff --git a/modular_citadel/sound/vox/presence.ogg b/sound/vox/presence.ogg
similarity index 100%
rename from modular_citadel/sound/vox/presence.ogg
rename to sound/vox/presence.ogg
diff --git a/modular_citadel/sound/vox/press.ogg b/sound/vox/press.ogg
similarity index 100%
rename from modular_citadel/sound/vox/press.ogg
rename to sound/vox/press.ogg
diff --git a/modular_citadel/sound/vox/primary.ogg b/sound/vox/primary.ogg
similarity index 100%
rename from modular_citadel/sound/vox/primary.ogg
rename to sound/vox/primary.ogg
diff --git a/modular_citadel/sound/vox/proceed.ogg b/sound/vox/proceed.ogg
similarity index 100%
rename from modular_citadel/sound/vox/proceed.ogg
rename to sound/vox/proceed.ogg
diff --git a/modular_citadel/sound/vox/processing.ogg b/sound/vox/processing.ogg
similarity index 100%
rename from modular_citadel/sound/vox/processing.ogg
rename to sound/vox/processing.ogg
diff --git a/modular_citadel/sound/vox/progress.ogg b/sound/vox/progress.ogg
similarity index 100%
rename from modular_citadel/sound/vox/progress.ogg
rename to sound/vox/progress.ogg
diff --git a/modular_citadel/sound/vox/proper.ogg b/sound/vox/proper.ogg
similarity index 100%
rename from modular_citadel/sound/vox/proper.ogg
rename to sound/vox/proper.ogg
diff --git a/modular_citadel/sound/vox/propulsion.ogg b/sound/vox/propulsion.ogg
similarity index 100%
rename from modular_citadel/sound/vox/propulsion.ogg
rename to sound/vox/propulsion.ogg
diff --git a/modular_citadel/sound/vox/prosecute.ogg b/sound/vox/prosecute.ogg
similarity index 100%
rename from modular_citadel/sound/vox/prosecute.ogg
rename to sound/vox/prosecute.ogg
diff --git a/modular_citadel/sound/vox/protective.ogg b/sound/vox/protective.ogg
similarity index 100%
rename from modular_citadel/sound/vox/protective.ogg
rename to sound/vox/protective.ogg
diff --git a/modular_citadel/sound/vox/push.ogg b/sound/vox/push.ogg
similarity index 100%
rename from modular_citadel/sound/vox/push.ogg
rename to sound/vox/push.ogg
diff --git a/modular_citadel/sound/vox/quantum.ogg b/sound/vox/quantum.ogg
similarity index 100%
rename from modular_citadel/sound/vox/quantum.ogg
rename to sound/vox/quantum.ogg
diff --git a/modular_citadel/sound/vox/quebec.ogg b/sound/vox/quebec.ogg
similarity index 100%
rename from modular_citadel/sound/vox/quebec.ogg
rename to sound/vox/quebec.ogg
diff --git a/modular_citadel/sound/vox/question.ogg b/sound/vox/question.ogg
similarity index 100%
rename from modular_citadel/sound/vox/question.ogg
rename to sound/vox/question.ogg
diff --git a/modular_citadel/sound/vox/questioning.ogg b/sound/vox/questioning.ogg
similarity index 100%
rename from modular_citadel/sound/vox/questioning.ogg
rename to sound/vox/questioning.ogg
diff --git a/modular_citadel/sound/vox/quick.ogg b/sound/vox/quick.ogg
similarity index 100%
rename from modular_citadel/sound/vox/quick.ogg
rename to sound/vox/quick.ogg
diff --git a/modular_citadel/sound/vox/quit.ogg b/sound/vox/quit.ogg
similarity index 100%
rename from modular_citadel/sound/vox/quit.ogg
rename to sound/vox/quit.ogg
diff --git a/modular_citadel/sound/vox/radiation.ogg b/sound/vox/radiation.ogg
similarity index 100%
rename from modular_citadel/sound/vox/radiation.ogg
rename to sound/vox/radiation.ogg
diff --git a/modular_citadel/sound/vox/radioactive.ogg b/sound/vox/radioactive.ogg
similarity index 100%
rename from modular_citadel/sound/vox/radioactive.ogg
rename to sound/vox/radioactive.ogg
diff --git a/modular_citadel/sound/vox/rads.ogg b/sound/vox/rads.ogg
similarity index 100%
rename from modular_citadel/sound/vox/rads.ogg
rename to sound/vox/rads.ogg
diff --git a/modular_citadel/sound/vox/rapid.ogg b/sound/vox/rapid.ogg
similarity index 100%
rename from modular_citadel/sound/vox/rapid.ogg
rename to sound/vox/rapid.ogg
diff --git a/modular_citadel/sound/vox/reach.ogg b/sound/vox/reach.ogg
similarity index 100%
rename from modular_citadel/sound/vox/reach.ogg
rename to sound/vox/reach.ogg
diff --git a/modular_citadel/sound/vox/reached.ogg b/sound/vox/reached.ogg
similarity index 100%
rename from modular_citadel/sound/vox/reached.ogg
rename to sound/vox/reached.ogg
diff --git a/modular_citadel/sound/vox/reactor.ogg b/sound/vox/reactor.ogg
similarity index 100%
rename from modular_citadel/sound/vox/reactor.ogg
rename to sound/vox/reactor.ogg
diff --git a/modular_citadel/sound/vox/red.ogg b/sound/vox/red.ogg
similarity index 100%
rename from modular_citadel/sound/vox/red.ogg
rename to sound/vox/red.ogg
diff --git a/modular_citadel/sound/vox/relay.ogg b/sound/vox/relay.ogg
similarity index 100%
rename from modular_citadel/sound/vox/relay.ogg
rename to sound/vox/relay.ogg
diff --git a/modular_citadel/sound/vox/released.ogg b/sound/vox/released.ogg
similarity index 100%
rename from modular_citadel/sound/vox/released.ogg
rename to sound/vox/released.ogg
diff --git a/modular_citadel/sound/vox/remaining.ogg b/sound/vox/remaining.ogg
similarity index 100%
rename from modular_citadel/sound/vox/remaining.ogg
rename to sound/vox/remaining.ogg
diff --git a/modular_citadel/sound/vox/renegade.ogg b/sound/vox/renegade.ogg
similarity index 100%
rename from modular_citadel/sound/vox/renegade.ogg
rename to sound/vox/renegade.ogg
diff --git a/modular_citadel/sound/vox/repair.ogg b/sound/vox/repair.ogg
similarity index 100%
rename from modular_citadel/sound/vox/repair.ogg
rename to sound/vox/repair.ogg
diff --git a/modular_citadel/sound/vox/report.ogg b/sound/vox/report.ogg
similarity index 100%
rename from modular_citadel/sound/vox/report.ogg
rename to sound/vox/report.ogg
diff --git a/modular_citadel/sound/vox/reports.ogg b/sound/vox/reports.ogg
similarity index 100%
rename from modular_citadel/sound/vox/reports.ogg
rename to sound/vox/reports.ogg
diff --git a/modular_citadel/sound/vox/required.ogg b/sound/vox/required.ogg
similarity index 100%
rename from modular_citadel/sound/vox/required.ogg
rename to sound/vox/required.ogg
diff --git a/modular_citadel/sound/vox/research.ogg b/sound/vox/research.ogg
similarity index 100%
rename from modular_citadel/sound/vox/research.ogg
rename to sound/vox/research.ogg
diff --git a/modular_citadel/sound/vox/reset.ogg b/sound/vox/reset.ogg
similarity index 100%
rename from modular_citadel/sound/vox/reset.ogg
rename to sound/vox/reset.ogg
diff --git a/modular_citadel/sound/vox/resevoir.ogg b/sound/vox/resevoir.ogg
similarity index 100%
rename from modular_citadel/sound/vox/resevoir.ogg
rename to sound/vox/resevoir.ogg
diff --git a/modular_citadel/sound/vox/resistance.ogg b/sound/vox/resistance.ogg
similarity index 100%
rename from modular_citadel/sound/vox/resistance.ogg
rename to sound/vox/resistance.ogg
diff --git a/modular_citadel/sound/vox/returned.ogg b/sound/vox/returned.ogg
similarity index 100%
rename from modular_citadel/sound/vox/returned.ogg
rename to sound/vox/returned.ogg
diff --git a/modular_citadel/sound/vox/right.ogg b/sound/vox/right.ogg
similarity index 100%
rename from modular_citadel/sound/vox/right.ogg
rename to sound/vox/right.ogg
diff --git a/modular_citadel/sound/vox/rocket.ogg b/sound/vox/rocket.ogg
similarity index 100%
rename from modular_citadel/sound/vox/rocket.ogg
rename to sound/vox/rocket.ogg
diff --git a/modular_citadel/sound/vox/roger.ogg b/sound/vox/roger.ogg
similarity index 100%
rename from modular_citadel/sound/vox/roger.ogg
rename to sound/vox/roger.ogg
diff --git a/modular_citadel/sound/vox/romeo.ogg b/sound/vox/romeo.ogg
similarity index 100%
rename from modular_citadel/sound/vox/romeo.ogg
rename to sound/vox/romeo.ogg
diff --git a/modular_citadel/sound/vox/room.ogg b/sound/vox/room.ogg
similarity index 100%
rename from modular_citadel/sound/vox/room.ogg
rename to sound/vox/room.ogg
diff --git a/modular_citadel/sound/vox/round.ogg b/sound/vox/round.ogg
similarity index 100%
rename from modular_citadel/sound/vox/round.ogg
rename to sound/vox/round.ogg
diff --git a/modular_citadel/sound/vox/run.ogg b/sound/vox/run.ogg
similarity index 100%
rename from modular_citadel/sound/vox/run.ogg
rename to sound/vox/run.ogg
diff --git a/modular_citadel/sound/vox/safe.ogg b/sound/vox/safe.ogg
similarity index 100%
rename from modular_citadel/sound/vox/safe.ogg
rename to sound/vox/safe.ogg
diff --git a/modular_citadel/sound/vox/safety.ogg b/sound/vox/safety.ogg
similarity index 100%
rename from modular_citadel/sound/vox/safety.ogg
rename to sound/vox/safety.ogg
diff --git a/modular_citadel/sound/vox/sargeant.ogg b/sound/vox/sargeant.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sargeant.ogg
rename to sound/vox/sargeant.ogg
diff --git a/modular_citadel/sound/vox/satellite.ogg b/sound/vox/satellite.ogg
similarity index 100%
rename from modular_citadel/sound/vox/satellite.ogg
rename to sound/vox/satellite.ogg
diff --git a/modular_citadel/sound/vox/save.ogg b/sound/vox/save.ogg
similarity index 100%
rename from modular_citadel/sound/vox/save.ogg
rename to sound/vox/save.ogg
diff --git a/modular_citadel/sound/vox/science.ogg b/sound/vox/science.ogg
similarity index 100%
rename from modular_citadel/sound/vox/science.ogg
rename to sound/vox/science.ogg
diff --git a/modular_citadel/sound/vox/scores.ogg b/sound/vox/scores.ogg
similarity index 100%
rename from modular_citadel/sound/vox/scores.ogg
rename to sound/vox/scores.ogg
diff --git a/modular_citadel/sound/vox/scream.ogg b/sound/vox/scream.ogg
similarity index 100%
rename from modular_citadel/sound/vox/scream.ogg
rename to sound/vox/scream.ogg
diff --git a/modular_citadel/sound/vox/screen.ogg b/sound/vox/screen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/screen.ogg
rename to sound/vox/screen.ogg
diff --git a/modular_citadel/sound/vox/search.ogg b/sound/vox/search.ogg
similarity index 100%
rename from modular_citadel/sound/vox/search.ogg
rename to sound/vox/search.ogg
diff --git a/modular_citadel/sound/vox/second.ogg b/sound/vox/second.ogg
similarity index 100%
rename from modular_citadel/sound/vox/second.ogg
rename to sound/vox/second.ogg
diff --git a/modular_citadel/sound/vox/secondary.ogg b/sound/vox/secondary.ogg
similarity index 100%
rename from modular_citadel/sound/vox/secondary.ogg
rename to sound/vox/secondary.ogg
diff --git a/modular_citadel/sound/vox/seconds.ogg b/sound/vox/seconds.ogg
similarity index 100%
rename from modular_citadel/sound/vox/seconds.ogg
rename to sound/vox/seconds.ogg
diff --git a/modular_citadel/sound/vox/sector.ogg b/sound/vox/sector.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sector.ogg
rename to sound/vox/sector.ogg
diff --git a/modular_citadel/sound/vox/secure.ogg b/sound/vox/secure.ogg
similarity index 100%
rename from modular_citadel/sound/vox/secure.ogg
rename to sound/vox/secure.ogg
diff --git a/modular_citadel/sound/vox/secured.ogg b/sound/vox/secured.ogg
similarity index 100%
rename from modular_citadel/sound/vox/secured.ogg
rename to sound/vox/secured.ogg
diff --git a/modular_citadel/sound/vox/security.ogg b/sound/vox/security.ogg
similarity index 100%
rename from modular_citadel/sound/vox/security.ogg
rename to sound/vox/security.ogg
diff --git a/modular_citadel/sound/vox/select.ogg b/sound/vox/select.ogg
similarity index 100%
rename from modular_citadel/sound/vox/select.ogg
rename to sound/vox/select.ogg
diff --git a/modular_citadel/sound/vox/selected.ogg b/sound/vox/selected.ogg
similarity index 100%
rename from modular_citadel/sound/vox/selected.ogg
rename to sound/vox/selected.ogg
diff --git a/modular_citadel/sound/vox/service.ogg b/sound/vox/service.ogg
similarity index 100%
rename from modular_citadel/sound/vox/service.ogg
rename to sound/vox/service.ogg
diff --git a/modular_citadel/sound/vox/seven.ogg b/sound/vox/seven.ogg
similarity index 100%
rename from modular_citadel/sound/vox/seven.ogg
rename to sound/vox/seven.ogg
diff --git a/modular_citadel/sound/vox/seventeen.ogg b/sound/vox/seventeen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/seventeen.ogg
rename to sound/vox/seventeen.ogg
diff --git a/modular_citadel/sound/vox/seventy.ogg b/sound/vox/seventy.ogg
similarity index 100%
rename from modular_citadel/sound/vox/seventy.ogg
rename to sound/vox/seventy.ogg
diff --git a/modular_citadel/sound/vox/severe.ogg b/sound/vox/severe.ogg
similarity index 100%
rename from modular_citadel/sound/vox/severe.ogg
rename to sound/vox/severe.ogg
diff --git a/modular_citadel/sound/vox/sewage.ogg b/sound/vox/sewage.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sewage.ogg
rename to sound/vox/sewage.ogg
diff --git a/modular_citadel/sound/vox/sewer.ogg b/sound/vox/sewer.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sewer.ogg
rename to sound/vox/sewer.ogg
diff --git a/modular_citadel/sound/vox/shield.ogg b/sound/vox/shield.ogg
similarity index 100%
rename from modular_citadel/sound/vox/shield.ogg
rename to sound/vox/shield.ogg
diff --git a/modular_citadel/sound/vox/shipment.ogg b/sound/vox/shipment.ogg
similarity index 100%
rename from modular_citadel/sound/vox/shipment.ogg
rename to sound/vox/shipment.ogg
diff --git a/modular_citadel/sound/vox/shock.ogg b/sound/vox/shock.ogg
similarity index 100%
rename from modular_citadel/sound/vox/shock.ogg
rename to sound/vox/shock.ogg
diff --git a/modular_citadel/sound/vox/shoot.ogg b/sound/vox/shoot.ogg
similarity index 100%
rename from modular_citadel/sound/vox/shoot.ogg
rename to sound/vox/shoot.ogg
diff --git a/modular_citadel/sound/vox/shower.ogg b/sound/vox/shower.ogg
similarity index 100%
rename from modular_citadel/sound/vox/shower.ogg
rename to sound/vox/shower.ogg
diff --git a/modular_citadel/sound/vox/shut.ogg b/sound/vox/shut.ogg
similarity index 100%
rename from modular_citadel/sound/vox/shut.ogg
rename to sound/vox/shut.ogg
diff --git a/modular_citadel/sound/vox/side.ogg b/sound/vox/side.ogg
similarity index 100%
rename from modular_citadel/sound/vox/side.ogg
rename to sound/vox/side.ogg
diff --git a/modular_citadel/sound/vox/sierra.ogg b/sound/vox/sierra.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sierra.ogg
rename to sound/vox/sierra.ogg
diff --git a/modular_citadel/sound/vox/sight.ogg b/sound/vox/sight.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sight.ogg
rename to sound/vox/sight.ogg
diff --git a/modular_citadel/sound/vox/silo.ogg b/sound/vox/silo.ogg
similarity index 100%
rename from modular_citadel/sound/vox/silo.ogg
rename to sound/vox/silo.ogg
diff --git a/modular_citadel/sound/vox/six.ogg b/sound/vox/six.ogg
similarity index 100%
rename from modular_citadel/sound/vox/six.ogg
rename to sound/vox/six.ogg
diff --git a/modular_citadel/sound/vox/sixteen.ogg b/sound/vox/sixteen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sixteen.ogg
rename to sound/vox/sixteen.ogg
diff --git a/modular_citadel/sound/vox/sixty.ogg b/sound/vox/sixty.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sixty.ogg
rename to sound/vox/sixty.ogg
diff --git a/modular_citadel/sound/vox/slime.ogg b/sound/vox/slime.ogg
similarity index 100%
rename from modular_citadel/sound/vox/slime.ogg
rename to sound/vox/slime.ogg
diff --git a/modular_citadel/sound/vox/slow.ogg b/sound/vox/slow.ogg
similarity index 100%
rename from modular_citadel/sound/vox/slow.ogg
rename to sound/vox/slow.ogg
diff --git a/modular_citadel/sound/vox/soldier.ogg b/sound/vox/soldier.ogg
similarity index 100%
rename from modular_citadel/sound/vox/soldier.ogg
rename to sound/vox/soldier.ogg
diff --git a/modular_citadel/sound/vox/some.ogg b/sound/vox/some.ogg
similarity index 100%
rename from modular_citadel/sound/vox/some.ogg
rename to sound/vox/some.ogg
diff --git a/modular_citadel/sound/vox/someone.ogg b/sound/vox/someone.ogg
similarity index 100%
rename from modular_citadel/sound/vox/someone.ogg
rename to sound/vox/someone.ogg
diff --git a/modular_citadel/sound/vox/something.ogg b/sound/vox/something.ogg
similarity index 100%
rename from modular_citadel/sound/vox/something.ogg
rename to sound/vox/something.ogg
diff --git a/modular_citadel/sound/vox/son.ogg b/sound/vox/son.ogg
similarity index 100%
rename from modular_citadel/sound/vox/son.ogg
rename to sound/vox/son.ogg
diff --git a/modular_citadel/sound/vox/sorry.ogg b/sound/vox/sorry.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sorry.ogg
rename to sound/vox/sorry.ogg
diff --git a/modular_citadel/sound/vox/south.ogg b/sound/vox/south.ogg
similarity index 100%
rename from modular_citadel/sound/vox/south.ogg
rename to sound/vox/south.ogg
diff --git a/modular_citadel/sound/vox/squad.ogg b/sound/vox/squad.ogg
similarity index 100%
rename from modular_citadel/sound/vox/squad.ogg
rename to sound/vox/squad.ogg
diff --git a/modular_citadel/sound/vox/square.ogg b/sound/vox/square.ogg
similarity index 100%
rename from modular_citadel/sound/vox/square.ogg
rename to sound/vox/square.ogg
diff --git a/modular_citadel/sound/vox/stairway.ogg b/sound/vox/stairway.ogg
similarity index 100%
rename from modular_citadel/sound/vox/stairway.ogg
rename to sound/vox/stairway.ogg
diff --git a/modular_citadel/sound/vox/status.ogg b/sound/vox/status.ogg
similarity index 100%
rename from modular_citadel/sound/vox/status.ogg
rename to sound/vox/status.ogg
diff --git a/modular_citadel/sound/vox/sterile.ogg b/sound/vox/sterile.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sterile.ogg
rename to sound/vox/sterile.ogg
diff --git a/modular_citadel/sound/vox/sterilization.ogg b/sound/vox/sterilization.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sterilization.ogg
rename to sound/vox/sterilization.ogg
diff --git a/modular_citadel/sound/vox/stolen.ogg b/sound/vox/stolen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/stolen.ogg
rename to sound/vox/stolen.ogg
diff --git a/modular_citadel/sound/vox/storage.ogg b/sound/vox/storage.ogg
similarity index 100%
rename from modular_citadel/sound/vox/storage.ogg
rename to sound/vox/storage.ogg
diff --git a/modular_citadel/sound/vox/sub.ogg b/sound/vox/sub.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sub.ogg
rename to sound/vox/sub.ogg
diff --git a/modular_citadel/sound/vox/subsurface.ogg b/sound/vox/subsurface.ogg
similarity index 100%
rename from modular_citadel/sound/vox/subsurface.ogg
rename to sound/vox/subsurface.ogg
diff --git a/modular_citadel/sound/vox/sudden.ogg b/sound/vox/sudden.ogg
similarity index 100%
rename from modular_citadel/sound/vox/sudden.ogg
rename to sound/vox/sudden.ogg
diff --git a/modular_citadel/sound/vox/suit.ogg b/sound/vox/suit.ogg
similarity index 100%
rename from modular_citadel/sound/vox/suit.ogg
rename to sound/vox/suit.ogg
diff --git a/modular_citadel/sound/vox/superconducting.ogg b/sound/vox/superconducting.ogg
similarity index 100%
rename from modular_citadel/sound/vox/superconducting.ogg
rename to sound/vox/superconducting.ogg
diff --git a/modular_citadel/sound/vox/supercooled.ogg b/sound/vox/supercooled.ogg
similarity index 100%
rename from modular_citadel/sound/vox/supercooled.ogg
rename to sound/vox/supercooled.ogg
diff --git a/modular_citadel/sound/vox/supply.ogg b/sound/vox/supply.ogg
similarity index 100%
rename from modular_citadel/sound/vox/supply.ogg
rename to sound/vox/supply.ogg
diff --git a/modular_citadel/sound/vox/surface.ogg b/sound/vox/surface.ogg
similarity index 100%
rename from modular_citadel/sound/vox/surface.ogg
rename to sound/vox/surface.ogg
diff --git a/modular_citadel/sound/vox/surrender.ogg b/sound/vox/surrender.ogg
similarity index 100%
rename from modular_citadel/sound/vox/surrender.ogg
rename to sound/vox/surrender.ogg
diff --git a/modular_citadel/sound/vox/surround.ogg b/sound/vox/surround.ogg
similarity index 100%
rename from modular_citadel/sound/vox/surround.ogg
rename to sound/vox/surround.ogg
diff --git a/modular_citadel/sound/vox/surrounded.ogg b/sound/vox/surrounded.ogg
similarity index 100%
rename from modular_citadel/sound/vox/surrounded.ogg
rename to sound/vox/surrounded.ogg
diff --git a/modular_citadel/sound/vox/switch.ogg b/sound/vox/switch.ogg
similarity index 100%
rename from modular_citadel/sound/vox/switch.ogg
rename to sound/vox/switch.ogg
diff --git a/modular_citadel/sound/vox/system.ogg b/sound/vox/system.ogg
similarity index 100%
rename from modular_citadel/sound/vox/system.ogg
rename to sound/vox/system.ogg
diff --git a/modular_citadel/sound/vox/systems.ogg b/sound/vox/systems.ogg
similarity index 100%
rename from modular_citadel/sound/vox/systems.ogg
rename to sound/vox/systems.ogg
diff --git a/modular_citadel/sound/vox/tactical.ogg b/sound/vox/tactical.ogg
similarity index 100%
rename from modular_citadel/sound/vox/tactical.ogg
rename to sound/vox/tactical.ogg
diff --git a/modular_citadel/sound/vox/take.ogg b/sound/vox/take.ogg
similarity index 100%
rename from modular_citadel/sound/vox/take.ogg
rename to sound/vox/take.ogg
diff --git a/modular_citadel/sound/vox/talk.ogg b/sound/vox/talk.ogg
similarity index 100%
rename from modular_citadel/sound/vox/talk.ogg
rename to sound/vox/talk.ogg
diff --git a/modular_citadel/sound/vox/tango.ogg b/sound/vox/tango.ogg
similarity index 100%
rename from modular_citadel/sound/vox/tango.ogg
rename to sound/vox/tango.ogg
diff --git a/modular_citadel/sound/vox/tank.ogg b/sound/vox/tank.ogg
similarity index 100%
rename from modular_citadel/sound/vox/tank.ogg
rename to sound/vox/tank.ogg
diff --git a/modular_citadel/sound/vox/target.ogg b/sound/vox/target.ogg
similarity index 100%
rename from modular_citadel/sound/vox/target.ogg
rename to sound/vox/target.ogg
diff --git a/modular_citadel/sound/vox/team.ogg b/sound/vox/team.ogg
similarity index 100%
rename from modular_citadel/sound/vox/team.ogg
rename to sound/vox/team.ogg
diff --git a/modular_citadel/sound/vox/temperature.ogg b/sound/vox/temperature.ogg
similarity index 100%
rename from modular_citadel/sound/vox/temperature.ogg
rename to sound/vox/temperature.ogg
diff --git a/modular_citadel/sound/vox/temporal.ogg b/sound/vox/temporal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/temporal.ogg
rename to sound/vox/temporal.ogg
diff --git a/modular_citadel/sound/vox/ten.ogg b/sound/vox/ten.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ten.ogg
rename to sound/vox/ten.ogg
diff --git a/modular_citadel/sound/vox/terminal.ogg b/sound/vox/terminal.ogg
similarity index 100%
rename from modular_citadel/sound/vox/terminal.ogg
rename to sound/vox/terminal.ogg
diff --git a/modular_citadel/sound/vox/terminated.ogg b/sound/vox/terminated.ogg
similarity index 100%
rename from modular_citadel/sound/vox/terminated.ogg
rename to sound/vox/terminated.ogg
diff --git a/modular_citadel/sound/vox/termination.ogg b/sound/vox/termination.ogg
similarity index 100%
rename from modular_citadel/sound/vox/termination.ogg
rename to sound/vox/termination.ogg
diff --git a/modular_citadel/sound/vox/test.ogg b/sound/vox/test.ogg
similarity index 100%
rename from modular_citadel/sound/vox/test.ogg
rename to sound/vox/test.ogg
diff --git a/modular_citadel/sound/vox/that.ogg b/sound/vox/that.ogg
similarity index 100%
rename from modular_citadel/sound/vox/that.ogg
rename to sound/vox/that.ogg
diff --git a/modular_citadel/sound/vox/the.ogg b/sound/vox/the.ogg
similarity index 100%
rename from modular_citadel/sound/vox/the.ogg
rename to sound/vox/the.ogg
diff --git a/modular_citadel/sound/vox/then.ogg b/sound/vox/then.ogg
similarity index 100%
rename from modular_citadel/sound/vox/then.ogg
rename to sound/vox/then.ogg
diff --git a/modular_citadel/sound/vox/there.ogg b/sound/vox/there.ogg
similarity index 100%
rename from modular_citadel/sound/vox/there.ogg
rename to sound/vox/there.ogg
diff --git a/modular_citadel/sound/vox/third.ogg b/sound/vox/third.ogg
similarity index 100%
rename from modular_citadel/sound/vox/third.ogg
rename to sound/vox/third.ogg
diff --git a/modular_citadel/sound/vox/thirteen.ogg b/sound/vox/thirteen.ogg
similarity index 100%
rename from modular_citadel/sound/vox/thirteen.ogg
rename to sound/vox/thirteen.ogg
diff --git a/modular_citadel/sound/vox/thirty.ogg b/sound/vox/thirty.ogg
similarity index 100%
rename from modular_citadel/sound/vox/thirty.ogg
rename to sound/vox/thirty.ogg
diff --git a/modular_citadel/sound/vox/this.ogg b/sound/vox/this.ogg
similarity index 100%
rename from modular_citadel/sound/vox/this.ogg
rename to sound/vox/this.ogg
diff --git a/modular_citadel/sound/vox/those.ogg b/sound/vox/those.ogg
similarity index 100%
rename from modular_citadel/sound/vox/those.ogg
rename to sound/vox/those.ogg
diff --git a/modular_citadel/sound/vox/thousand.ogg b/sound/vox/thousand.ogg
similarity index 100%
rename from modular_citadel/sound/vox/thousand.ogg
rename to sound/vox/thousand.ogg
diff --git a/modular_citadel/sound/vox/threat.ogg b/sound/vox/threat.ogg
similarity index 100%
rename from modular_citadel/sound/vox/threat.ogg
rename to sound/vox/threat.ogg
diff --git a/modular_citadel/sound/vox/three.ogg b/sound/vox/three.ogg
similarity index 100%
rename from modular_citadel/sound/vox/three.ogg
rename to sound/vox/three.ogg
diff --git a/modular_citadel/sound/vox/through.ogg b/sound/vox/through.ogg
similarity index 100%
rename from modular_citadel/sound/vox/through.ogg
rename to sound/vox/through.ogg
diff --git a/modular_citadel/sound/vox/time.ogg b/sound/vox/time.ogg
similarity index 100%
rename from modular_citadel/sound/vox/time.ogg
rename to sound/vox/time.ogg
diff --git a/modular_citadel/sound/vox/to.ogg b/sound/vox/to.ogg
similarity index 100%
rename from modular_citadel/sound/vox/to.ogg
rename to sound/vox/to.ogg
diff --git a/modular_citadel/sound/vox/top.ogg b/sound/vox/top.ogg
similarity index 100%
rename from modular_citadel/sound/vox/top.ogg
rename to sound/vox/top.ogg
diff --git a/modular_citadel/sound/vox/topside.ogg b/sound/vox/topside.ogg
similarity index 100%
rename from modular_citadel/sound/vox/topside.ogg
rename to sound/vox/topside.ogg
diff --git a/modular_citadel/sound/vox/touch.ogg b/sound/vox/touch.ogg
similarity index 100%
rename from modular_citadel/sound/vox/touch.ogg
rename to sound/vox/touch.ogg
diff --git a/modular_citadel/sound/vox/towards.ogg b/sound/vox/towards.ogg
similarity index 100%
rename from modular_citadel/sound/vox/towards.ogg
rename to sound/vox/towards.ogg
diff --git a/modular_citadel/sound/vox/track.ogg b/sound/vox/track.ogg
similarity index 100%
rename from modular_citadel/sound/vox/track.ogg
rename to sound/vox/track.ogg
diff --git a/modular_citadel/sound/vox/train.ogg b/sound/vox/train.ogg
similarity index 100%
rename from modular_citadel/sound/vox/train.ogg
rename to sound/vox/train.ogg
diff --git a/modular_citadel/sound/vox/transportation.ogg b/sound/vox/transportation.ogg
similarity index 100%
rename from modular_citadel/sound/vox/transportation.ogg
rename to sound/vox/transportation.ogg
diff --git a/modular_citadel/sound/vox/truck.ogg b/sound/vox/truck.ogg
similarity index 100%
rename from modular_citadel/sound/vox/truck.ogg
rename to sound/vox/truck.ogg
diff --git a/modular_citadel/sound/vox/tunnel.ogg b/sound/vox/tunnel.ogg
similarity index 100%
rename from modular_citadel/sound/vox/tunnel.ogg
rename to sound/vox/tunnel.ogg
diff --git a/modular_citadel/sound/vox/turn.ogg b/sound/vox/turn.ogg
similarity index 100%
rename from modular_citadel/sound/vox/turn.ogg
rename to sound/vox/turn.ogg
diff --git a/modular_citadel/sound/vox/turret.ogg b/sound/vox/turret.ogg
similarity index 100%
rename from modular_citadel/sound/vox/turret.ogg
rename to sound/vox/turret.ogg
diff --git a/modular_citadel/sound/vox/twelve.ogg b/sound/vox/twelve.ogg
similarity index 100%
rename from modular_citadel/sound/vox/twelve.ogg
rename to sound/vox/twelve.ogg
diff --git a/modular_citadel/sound/vox/twenty.ogg b/sound/vox/twenty.ogg
similarity index 100%
rename from modular_citadel/sound/vox/twenty.ogg
rename to sound/vox/twenty.ogg
diff --git a/modular_citadel/sound/vox/two.ogg b/sound/vox/two.ogg
similarity index 100%
rename from modular_citadel/sound/vox/two.ogg
rename to sound/vox/two.ogg
diff --git a/modular_citadel/sound/vox/unauthorized.ogg b/sound/vox/unauthorized.ogg
similarity index 100%
rename from modular_citadel/sound/vox/unauthorized.ogg
rename to sound/vox/unauthorized.ogg
diff --git a/modular_citadel/sound/vox/under.ogg b/sound/vox/under.ogg
similarity index 100%
rename from modular_citadel/sound/vox/under.ogg
rename to sound/vox/under.ogg
diff --git a/modular_citadel/sound/vox/uniform.ogg b/sound/vox/uniform.ogg
similarity index 100%
rename from modular_citadel/sound/vox/uniform.ogg
rename to sound/vox/uniform.ogg
diff --git a/modular_citadel/sound/vox/unlocked.ogg b/sound/vox/unlocked.ogg
similarity index 100%
rename from modular_citadel/sound/vox/unlocked.ogg
rename to sound/vox/unlocked.ogg
diff --git a/modular_citadel/sound/vox/until.ogg b/sound/vox/until.ogg
similarity index 100%
rename from modular_citadel/sound/vox/until.ogg
rename to sound/vox/until.ogg
diff --git a/modular_citadel/sound/vox/up.ogg b/sound/vox/up.ogg
similarity index 100%
rename from modular_citadel/sound/vox/up.ogg
rename to sound/vox/up.ogg
diff --git a/modular_citadel/sound/vox/upper.ogg b/sound/vox/upper.ogg
similarity index 100%
rename from modular_citadel/sound/vox/upper.ogg
rename to sound/vox/upper.ogg
diff --git a/modular_citadel/sound/vox/uranium.ogg b/sound/vox/uranium.ogg
similarity index 100%
rename from modular_citadel/sound/vox/uranium.ogg
rename to sound/vox/uranium.ogg
diff --git a/modular_citadel/sound/vox/us.ogg b/sound/vox/us.ogg
similarity index 100%
rename from modular_citadel/sound/vox/us.ogg
rename to sound/vox/us.ogg
diff --git a/modular_citadel/sound/vox/usa.ogg b/sound/vox/usa.ogg
similarity index 100%
rename from modular_citadel/sound/vox/usa.ogg
rename to sound/vox/usa.ogg
diff --git a/modular_citadel/sound/vox/use.ogg b/sound/vox/use.ogg
similarity index 100%
rename from modular_citadel/sound/vox/use.ogg
rename to sound/vox/use.ogg
diff --git a/modular_citadel/sound/vox/used.ogg b/sound/vox/used.ogg
similarity index 100%
rename from modular_citadel/sound/vox/used.ogg
rename to sound/vox/used.ogg
diff --git a/modular_citadel/sound/vox/user.ogg b/sound/vox/user.ogg
similarity index 100%
rename from modular_citadel/sound/vox/user.ogg
rename to sound/vox/user.ogg
diff --git a/modular_citadel/sound/vox/vacate.ogg b/sound/vox/vacate.ogg
similarity index 100%
rename from modular_citadel/sound/vox/vacate.ogg
rename to sound/vox/vacate.ogg
diff --git a/modular_citadel/sound/vox/valid.ogg b/sound/vox/valid.ogg
similarity index 100%
rename from modular_citadel/sound/vox/valid.ogg
rename to sound/vox/valid.ogg
diff --git a/modular_citadel/sound/vox/vapor.ogg b/sound/vox/vapor.ogg
similarity index 100%
rename from modular_citadel/sound/vox/vapor.ogg
rename to sound/vox/vapor.ogg
diff --git a/modular_citadel/sound/vox/vent.ogg b/sound/vox/vent.ogg
similarity index 100%
rename from modular_citadel/sound/vox/vent.ogg
rename to sound/vox/vent.ogg
diff --git a/modular_citadel/sound/vox/ventillation.ogg b/sound/vox/ventillation.ogg
similarity index 100%
rename from modular_citadel/sound/vox/ventillation.ogg
rename to sound/vox/ventillation.ogg
diff --git a/modular_citadel/sound/vox/victor.ogg b/sound/vox/victor.ogg
similarity index 100%
rename from modular_citadel/sound/vox/victor.ogg
rename to sound/vox/victor.ogg
diff --git a/modular_citadel/sound/vox/violated.ogg b/sound/vox/violated.ogg
similarity index 100%
rename from modular_citadel/sound/vox/violated.ogg
rename to sound/vox/violated.ogg
diff --git a/modular_citadel/sound/vox/violation.ogg b/sound/vox/violation.ogg
similarity index 100%
rename from modular_citadel/sound/vox/violation.ogg
rename to sound/vox/violation.ogg
diff --git a/modular_citadel/sound/vox/voltage.ogg b/sound/vox/voltage.ogg
similarity index 100%
rename from modular_citadel/sound/vox/voltage.ogg
rename to sound/vox/voltage.ogg
diff --git a/modular_citadel/sound/vox/vox_login.ogg b/sound/vox/vox_login.ogg
similarity index 100%
rename from modular_citadel/sound/vox/vox_login.ogg
rename to sound/vox/vox_login.ogg
diff --git a/modular_citadel/sound/vox/walk.ogg b/sound/vox/walk.ogg
similarity index 100%
rename from modular_citadel/sound/vox/walk.ogg
rename to sound/vox/walk.ogg
diff --git a/modular_citadel/sound/vox/wall.ogg b/sound/vox/wall.ogg
similarity index 100%
rename from modular_citadel/sound/vox/wall.ogg
rename to sound/vox/wall.ogg
diff --git a/modular_citadel/sound/vox/want.ogg b/sound/vox/want.ogg
similarity index 100%
rename from modular_citadel/sound/vox/want.ogg
rename to sound/vox/want.ogg
diff --git a/modular_citadel/sound/vox/wanted.ogg b/sound/vox/wanted.ogg
similarity index 100%
rename from modular_citadel/sound/vox/wanted.ogg
rename to sound/vox/wanted.ogg
diff --git a/modular_citadel/sound/vox/warm.ogg b/sound/vox/warm.ogg
similarity index 100%
rename from modular_citadel/sound/vox/warm.ogg
rename to sound/vox/warm.ogg
diff --git a/modular_citadel/sound/vox/warn.ogg b/sound/vox/warn.ogg
similarity index 100%
rename from modular_citadel/sound/vox/warn.ogg
rename to sound/vox/warn.ogg
diff --git a/modular_citadel/sound/vox/warning.ogg b/sound/vox/warning.ogg
similarity index 100%
rename from modular_citadel/sound/vox/warning.ogg
rename to sound/vox/warning.ogg
diff --git a/modular_citadel/sound/vox/waste.ogg b/sound/vox/waste.ogg
similarity index 100%
rename from modular_citadel/sound/vox/waste.ogg
rename to sound/vox/waste.ogg
diff --git a/modular_citadel/sound/vox/water.ogg b/sound/vox/water.ogg
similarity index 100%
rename from modular_citadel/sound/vox/water.ogg
rename to sound/vox/water.ogg
diff --git a/modular_citadel/sound/vox/we.ogg b/sound/vox/we.ogg
similarity index 100%
rename from modular_citadel/sound/vox/we.ogg
rename to sound/vox/we.ogg
diff --git a/modular_citadel/sound/vox/weapon.ogg b/sound/vox/weapon.ogg
similarity index 100%
rename from modular_citadel/sound/vox/weapon.ogg
rename to sound/vox/weapon.ogg
diff --git a/modular_citadel/sound/vox/west.ogg b/sound/vox/west.ogg
similarity index 100%
rename from modular_citadel/sound/vox/west.ogg
rename to sound/vox/west.ogg
diff --git a/modular_citadel/sound/vox/whiskey.ogg b/sound/vox/whiskey.ogg
similarity index 100%
rename from modular_citadel/sound/vox/whiskey.ogg
rename to sound/vox/whiskey.ogg
diff --git a/modular_citadel/sound/vox/white.ogg b/sound/vox/white.ogg
similarity index 100%
rename from modular_citadel/sound/vox/white.ogg
rename to sound/vox/white.ogg
diff --git a/modular_citadel/sound/vox/wilco.ogg b/sound/vox/wilco.ogg
similarity index 100%
rename from modular_citadel/sound/vox/wilco.ogg
rename to sound/vox/wilco.ogg
diff --git a/modular_citadel/sound/vox/will.ogg b/sound/vox/will.ogg
similarity index 100%
rename from modular_citadel/sound/vox/will.ogg
rename to sound/vox/will.ogg
diff --git a/modular_citadel/sound/vox/with.ogg b/sound/vox/with.ogg
similarity index 100%
rename from modular_citadel/sound/vox/with.ogg
rename to sound/vox/with.ogg
diff --git a/modular_citadel/sound/vox/without.ogg b/sound/vox/without.ogg
similarity index 100%
rename from modular_citadel/sound/vox/without.ogg
rename to sound/vox/without.ogg
diff --git a/modular_citadel/sound/vox/woop.ogg b/sound/vox/woop.ogg
similarity index 100%
rename from modular_citadel/sound/vox/woop.ogg
rename to sound/vox/woop.ogg
diff --git a/modular_citadel/sound/vox/xeno.ogg b/sound/vox/xeno.ogg
similarity index 100%
rename from modular_citadel/sound/vox/xeno.ogg
rename to sound/vox/xeno.ogg
diff --git a/modular_citadel/sound/vox/yankee.ogg b/sound/vox/yankee.ogg
similarity index 100%
rename from modular_citadel/sound/vox/yankee.ogg
rename to sound/vox/yankee.ogg
diff --git a/modular_citadel/sound/vox/yards.ogg b/sound/vox/yards.ogg
similarity index 100%
rename from modular_citadel/sound/vox/yards.ogg
rename to sound/vox/yards.ogg
diff --git a/modular_citadel/sound/vox/year.ogg b/sound/vox/year.ogg
similarity index 100%
rename from modular_citadel/sound/vox/year.ogg
rename to sound/vox/year.ogg
diff --git a/modular_citadel/sound/vox/yellow.ogg b/sound/vox/yellow.ogg
similarity index 100%
rename from modular_citadel/sound/vox/yellow.ogg
rename to sound/vox/yellow.ogg
diff --git a/modular_citadel/sound/vox/yes.ogg b/sound/vox/yes.ogg
similarity index 100%
rename from modular_citadel/sound/vox/yes.ogg
rename to sound/vox/yes.ogg
diff --git a/modular_citadel/sound/vox/you.ogg b/sound/vox/you.ogg
similarity index 100%
rename from modular_citadel/sound/vox/you.ogg
rename to sound/vox/you.ogg
diff --git a/modular_citadel/sound/vox/your.ogg b/sound/vox/your.ogg
similarity index 100%
rename from modular_citadel/sound/vox/your.ogg
rename to sound/vox/your.ogg
diff --git a/modular_citadel/sound/vox/yourself.ogg b/sound/vox/yourself.ogg
similarity index 100%
rename from modular_citadel/sound/vox/yourself.ogg
rename to sound/vox/yourself.ogg
diff --git a/modular_citadel/sound/vox/zero.ogg b/sound/vox/zero.ogg
similarity index 100%
rename from modular_citadel/sound/vox/zero.ogg
rename to sound/vox/zero.ogg
diff --git a/modular_citadel/sound/vox/zone.ogg b/sound/vox/zone.ogg
similarity index 100%
rename from modular_citadel/sound/vox/zone.ogg
rename to sound/vox/zone.ogg
diff --git a/modular_citadel/sound/vox/zulu.ogg b/sound/vox/zulu.ogg
similarity index 100%
rename from modular_citadel/sound/vox/zulu.ogg
rename to sound/vox/zulu.ogg
diff --git a/modular_citadel/sound/weapons/LaserSlugv3.ogg b/sound/weapons/LaserSlugv3.ogg
similarity index 100%
rename from modular_citadel/sound/weapons/LaserSlugv3.ogg
rename to sound/weapons/LaserSlugv3.ogg
diff --git a/modular_citadel/sound/weapons/ParticleBlaster.ogg b/sound/weapons/ParticleBlaster.ogg
similarity index 100%
rename from modular_citadel/sound/weapons/ParticleBlaster.ogg
rename to sound/weapons/ParticleBlaster.ogg
diff --git a/sound/weapons/gatling.ogg b/sound/weapons/gatling.ogg
deleted file mode 100644
index 0f8045560d..0000000000
Binary files a/sound/weapons/gatling.ogg and /dev/null differ
diff --git a/modular_citadel/sound/weapons/laserPump.ogg b/sound/weapons/laserPump.ogg
similarity index 100%
rename from modular_citadel/sound/weapons/laserPump.ogg
rename to sound/weapons/laserPump.ogg
diff --git a/modular_citadel/sound/weapons/laserPumpEmpty.ogg b/sound/weapons/laserPumpEmpty.ogg
similarity index 100%
rename from modular_citadel/sound/weapons/laserPumpEmpty.ogg
rename to sound/weapons/laserPumpEmpty.ogg
diff --git a/sound/weapons/neovgre_laser.ogg b/sound/weapons/neovgre_laser.ogg
new file mode 100644
index 0000000000..da97117ae8
Binary files /dev/null and b/sound/weapons/neovgre_laser.ogg differ
diff --git a/strings/dwarf_replacement.json b/strings/dwarf_replacement.json
new file mode 100644
index 0000000000..2049c5ab26
--- /dev/null
+++ b/strings/dwarf_replacement.json
@@ -0,0 +1,1461 @@
+{
+
+ "dwarf": {
+ "ability": "abeelitie",
+ "about": "aboot",
+ "above": "abuin",
+ "abroad": "abraid",
+ "absorb": "drack",
+ "absorbing": "drackin'",
+ "absorbs": "dracks",
+ "accuse": "delate",
+ "accused": "delated",
+ "across": "athwart",
+ "act": "ect",
+ "acts": "ects",
+ "add": "eik",
+ "added": "eikit",
+ "adds": "eiks",
+ "admit": "admeet",
+ "admits": "admeets",
+ "afraid": "feart",
+ "africa": "afrikey",
+ "after": "efter",
+ "against": "agin",
+ "alarm": "alairm",
+ "ale": "yill",
+ "all": "a'",
+ "allow": "allou",
+ "almost": "naur",
+ "along": "yont",
+ "aloof": "abeich",
+ "aloud": "lood out",
+ "also": "an a'",
+ "always": "aye",
+ "amazed": "dumfoundert",
+ "america": "amerikie",
+ "amidst": "'midst",
+ "among": [
+ "'mang",
+ "amang"
+ ],
+ "amount": [
+ "amoont",
+ "feck"
+ ],
+ "and": "an'",
+ "animal": "beist",
+ "animals": "beists",
+ "ankle": "cuit",
+ "ankles": "cuits",
+ "announce": "annoonce",
+ "announces": "annoonces",
+ "another": "anither",
+ "answered": "answert",
+ "ant": "eemock",
+ "ants": "eemocks",
+ "anxiety": "anxeeitie",
+ "any": "ony",
+ "anybody": "aebodie",
+ "apprentice": "prentice",
+ "apprentices": "prentices",
+ "are": "ar",
+ "aren't": "arena",
+ "arm": "airm",
+ "arrange": "dispone",
+ "arranged": "dispon'd",
+ "arranges": "dispones",
+ "arrest": "lift",
+ "arrested": "liftit",
+ "arrests": "lifts",
+ "arse": "erse",
+ "arses": "erses",
+ "artificial": "artifeicial",
+ "ash": "ase",
+ "ashes": "ase",
+ "aside": "ascient",
+ "ask": "aks",
+ "asked": "akst",
+ "asks": "aks",
+ "ass": "erse",
+ "asses": "erses",
+ "asshole": "hurdie",
+ "ate": "ett",
+ "aunt": "auntie",
+ "author": "owthor",
+ "awaken": "awauken",
+ "awakens": "awaukens",
+ "away": "awa",
+ "awful": "awfu",
+ "awfully": "awfy",
+ "awkward": "thrawart",
+ "awry": [
+ "aglae",
+ "ajee"
+ ],
+ "axe": "aix",
+ "axle": "aixle",
+ "back": "hint",
+ "bacon": "ham",
+ "bad": "ill",
+ "bags": "begs",
+ "bake": "bak",
+ "baked": "bakken",
+ "bakes": "baks",
+ "bald": "beld",
+ "ball": "baw",
+ "balls": "baws",
+ "bar": "baur",
+ "barber's": "baurber's",
+ "barber": "baurber",
+ "barbers": "baurbers",
+ "bastard": "bas",
+ "bat": "flichtermoose",
+ "baton": "rung",
+ "batons": "rungs",
+ "bats": "flichtermooses",
+ "beach": "foreland",
+ "beard": "bairds",
+ "beards": "bairds",
+ "beautiful": "bonnie",
+ "because": "kis",
+ "become": "set",
+ "becomes": "sets",
+ "bed": "scratcher",
+ "beds": "scratchers",
+ "bee's": "skep-bee's",
+ "bee": "skep-bee",
+ "bees": "skep-bees",
+ "beetle": "clock",
+ "beetles": "clocks",
+ "before": "afore",
+ "began": "begoud",
+ "being": "bein",
+ "belong": "belang",
+ "belonged": "belangit",
+ "belongs": "belangs",
+ "below": "ablo",
+ "beneath": "inunner",
+ "bent": "bowlt",
+ "besides": "forby",
+ "between": "atween",
+ "beware": "bewaur",
+ "bilberry": "blaeberry",
+ "bind": "thirl",
+ "binds": "thirls",
+ "bird": "burd",
+ "birds": "burdies",
+ "biscuit": "bannock",
+ "biscuits": "bannocks",
+ "bitch": "bick",
+ "bitches": "bicks",
+ "bitching": "bickerin'",
+ "bitter": "wersh",
+ "blackbird": "bleckie",
+ "blackbirds": "bleckies",
+ "blame": "wyse",
+ "blamed": "wysed",
+ "blames": "wyses",
+ "blast": "tout",
+ "blind": "blinnd",
+ "blood": "bluid",
+ "bloody": "bluidy",
+ "blue": "blae",
+ "boil": "bile",
+ "boils": "biles",
+ "bold": "bauld",
+ "bolder": "baulder",
+ "boldest": "bauldest",
+ "boldly": "baudly",
+ "bolt": "bowt",
+ "bone": "bane",
+ "bones": "banes",
+ "bony": "bainie",
+ "book": "beuk",
+ "books": "beuks",
+ "boot": "buit",
+ "borrow": "borrae",
+ "borrowed": "borraed",
+ "borrowing": "borrain'",
+ "borrows": "borraes",
+ "both": "baith",
+ "bother": "fash",
+ "box": [
+ "boax",
+ "kist"
+ ],
+ "boy": "laddie",
+ "boys": "laddies",
+ "brawl": "brulyie",
+ "breath": "braith",
+ "brew": "broo",
+ "broad": "braid",
+ "broke": "bruck",
+ "broken": "brustit",
+ "brood": "bairntime",
+ "broom": "besom",
+ "brooms": "besoms",
+ "broth": "brose",
+ "brother's": "brither's",
+ "brother": "brither",
+ "brothers": "brithers",
+ "brown": "broon",
+ "bucket": "backit",
+ "buckets": "backits",
+ "build": "big",
+ "built": "biggit",
+ "bump": "bumfle",
+ "buried": "yirdit",
+ "burnt": "brunt",
+ "bury": "birrie",
+ "busy": "bizzie",
+ "butcher": "flesher",
+ "butt": "dowp",
+ "buttocks": "dowp",
+ "button": "gornal",
+ "buttons": "gornals",
+ "butts": "bahookies",
+ "by": "bi",
+ "call": "ca'",
+ "called": "caad",
+ "calls": "ca'",
+ "came": "cam",
+ "can't": "cannae",
+ "cap": "kaip",
+ "caps": "kaips",
+ "captain's": "chief's",
+ "captain": "chief",
+ "car": "caur",
+ "card": "kerd",
+ "cards": "kerds",
+ "careful": "canny",
+ "careless": "feckless",
+ "carpenter": "jyner",
+ "carpenters": "jyners",
+ "carpet": "cairpet",
+ "carried": "cairiet",
+ "carries": "cairies",
+ "carry": "cairie",
+ "cart": "cairt",
+ "cash": "clink",
+ "cat's": "cheetie's",
+ "cat": "cheetie",
+ "catch": "kep",
+ "catched": "keppit",
+ "cats": "cheeties",
+ "caught": "keppit",
+ "cause": "gar",
+ "caused": "gart",
+ "certainly": "fairly",
+ "chance": "chaunce",
+ "chances": "chaunces",
+ "change": "chynge",
+ "changed": "chynged",
+ "changeling": "chyngelin'",
+ "chatter": "blether",
+ "cheer": "chear",
+ "cheerful": "chearfu'",
+ "cheerless": "chearless",
+ "cheers": "chears",
+ "cheery": "cheary",
+ "chest": "kist",
+ "chests": "kist",
+ "chick": "pout",
+ "chicks": "pouts",
+ "child": "bairn",
+ "chilly": "snell",
+ "chimney": "chimley",
+ "chimneys": "chimleys",
+ "choose": "chuise",
+ "chooses": "chuises",
+ "chosen": "chuist",
+ "christmas": "Yule",
+ "chunk": "dod",
+ "chunks": "dods",
+ "church": "kirk",
+ "cigarette": "baccie",
+ "cigarettes": "baccies",
+ "city": "ceity",
+ "clean": "clane",
+ "cloth": "cloot",
+ "clothes": "claes",
+ "cold": "cauld",
+ "comb": "kaim",
+ "commotion": "stramash",
+ "concerning": "anent",
+ "consider": "see",
+ "conspicuous": "kenspeckle",
+ "cool": "cuil",
+ "corner": "neuk",
+ "correctly": "swash",
+ "cosy": "codgie",
+ "cottage": "but and ben",
+ "cough": "hoast",
+ "could": "coud",
+ "couldn't": "coudnae",
+ "couldnt": "coudnae",
+ "country": "kintra",
+ "cow": "coo",
+ "crate": "kist",
+ "crates": "kists",
+ "creak": "jarg",
+ "creaked": "jarg'd",
+ "creaking": "jargin'",
+ "creaks": "jargs",
+ "creature": "cretter",
+ "creatures": "cretters",
+ "cries": "girns",
+ "critter": "cretter",
+ "critters": "cretters",
+ "crooked": "cruikit",
+ "crow": "corbie",
+ "crowbar": "louder",
+ "crowbars": "louders",
+ "crowd": "byke",
+ "cruel": "fell",
+ "crush": "brousle",
+ "crusher": "brousler",
+ "cry": "greet",
+ "crying": "greetin",
+ "cuff": "shackle",
+ "cuffed": "shackled",
+ "cuffing": "shackling",
+ "cuffs": "shangies",
+ "cup": "tassie",
+ "cut": "sned",
+ "cute": "gainin",
+ "cuts": "sneds",
+ "cutters": "sheers",
+ "daft": "dunderheided",
+ "damage": "skaith",
+ "dare": "daur",
+ "dared": "durst",
+ "daren't": "daurnae",
+ "darent": "daurnae",
+ "dares": "daurs",
+ "dark": "daurk",
+ "darken": "daurken",
+ "dawn": "cockcrow",
+ "dead": "deid",
+ "deaf": "deif",
+ "deafen": "deave",
+ "death": "dead",
+ "deaths": "deads",
+ "delightful": "lichtsome",
+ "delve": "del",
+ "deny": "forsay",
+ "depressed": "dumpie",
+ "describe": "descrive",
+ "devil": "de'il",
+ "didn't": "didnae",
+ "didnt": "didnae",
+ "die": "dee",
+ "died": "dee'd",
+ "dies": "dees",
+ "difficult": "difeecult",
+ "dig": "howk",
+ "directed": "airtit",
+ "directions": "airts",
+ "dirty": "clarty",
+ "discover": "diskiver",
+ "discovered": "diskiver'd",
+ "discovers": "diskivers",
+ "disgust": [
+ "sconner",
+ "scunner"
+ ],
+ "disgusting": "scunnersome",
+ "dishonest": "unhonest",
+ "dive": "dyve",
+ "dives": "dyves",
+ "diving": "dyvin'",
+ "do": "dae",
+ "does": "dis",
+ "dog": [
+ "dug",
+ "tyke"
+ ],
+ "dogs": "tykes",
+ "don't": "dinnae",
+ "done": "duin",
+ "dont": "dinnae",
+ "doom": "deim",
+ "doomed": "deim'd",
+ "door": "dorr",
+ "doors": "dorrs",
+ "doubt": "dout",
+ "doubted": "doutit",
+ "doubting": "doutin'",
+ "doubts": "douts",
+ "dough": "daugh",
+ "dove": "doo",
+ "down": "doun",
+ "downfall": "dounfaa",
+ "downtrodden": "dounhauden",
+ "drain": "stank",
+ "dread": "dreid",
+ "dream": "draim",
+ "dreams": "draims",
+ "drew": "draw",
+ "drink": "beb",
+ "drinks": "bebs",
+ "drip": "dreep",
+ "drive": "caw",
+ "drone": "bum",
+ "drones": "bums",
+ "drop": "drap",
+ "drown": "droun",
+ "drowned": "drount",
+ "drowning": "drounin'",
+ "drowns": "drouns",
+ "drug": "drog",
+ "drugs": "drogs",
+ "drunk": "drunken",
+ "drunkard": "sot",
+ "dry": "freuch",
+ "duck": "dook",
+ "ducked": "douked",
+ "dusk": "gloaming",
+ "dust": "stoor",
+ "dusty": "stourie",
+ "dwell": "wone",
+ "dying": "diein'",
+ "each": "ilk",
+ "eagle": [
+ "aigle",
+ "earn"
+ ],
+ "eagles": "earns",
+ "ear": "lug",
+ "early": "earlie",
+ "earth": "yird",
+ "east": "aist",
+ "eastern": "eastlin",
+ "easternmost": "eastmaist",
+ "eastmost": "eastmaist",
+ "eastward": "aistart",
+ "eat": "aet",
+ "eaten": "etten",
+ "eats": "aets",
+ "eden": "aidin",
+ "edinburgh": "auld reekie",
+ "eight": "eighct",
+ "eighteen": "aughten",
+ "else": "ense",
+ "empty": [
+ "empie",
+ "toom"
+ ],
+ "end": "en",
+ "endure": "thole",
+ "engine's": "ingine's",
+ "engine": "ingine",
+ "engineer's": "ingineer's",
+ "engineer": "ingineer",
+ "engineers'": "ingineers'",
+ "engineers": "ingineers",
+ "engines": "ingines",
+ "english": "soothron",
+ "enough's": "eneuch's",
+ "enough": "eneuch",
+ "equal": "match",
+ "escaped": "gat awa",
+ "eternal": "ayebidin",
+ "even": "e'en",
+ "evening": "e'en",
+ "ever": "iver",
+ "every": "ilka",
+ "everything": "iveriehott",
+ "everywhere": "aa wey",
+ "ewe": "yowe",
+ "example": "ensaumple",
+ "extraordinarily": "unco",
+ "extremely": "unco",
+ "eye": "ee",
+ "eyebrow": "e'ebrie",
+ "eyebrows": "e'ebries",
+ "eyes": "een",
+ "fall": "fa'",
+ "fallen": "fa'n",
+ "falling": "faain",
+ "falls": "fa's",
+ "false": "fause",
+ "family": "faimly",
+ "far": "faur",
+ "fart": "pump",
+ "farther": "faurer",
+ "farts": "pumps",
+ "father": "faither",
+ "fault": [
+ "blame",
+ "faut"
+ ],
+ "faults": "fauts",
+ "feeble": "doweless",
+ "feed": "beet",
+ "fellow": "chiel",
+ "fetch": "fuish",
+ "fetched": "fuishen",
+ "fetches": "fuishes",
+ "few": "puckle",
+ "fight": "fecht",
+ "fill": "ful",
+ "filled": "fult",
+ "find": "fin",
+ "fine": "braw",
+ "finely": "brawlie",
+ "fish": "fush",
+ "flake": "flichan",
+ "flakes": "flichans",
+ "flap": "flaff",
+ "flapped": "flaff'd",
+ "flapping": "flaffin",
+ "flaps": "flaffs",
+ "flea": "flaich",
+ "fleas": "flaich",
+ "flood": "speat",
+ "flour": "floor",
+ "flown": "flewn",
+ "flutter": "flitter",
+ "fluttered": "flittered",
+ "fluttering": "flittering",
+ "flutters": "flitter",
+ "fly": "flee",
+ "foam": "faem",
+ "folk": "fowk",
+ "food": "fuid",
+ "foot": "fuit",
+ "for": "fur",
+ "forget": "forgit",
+ "forgets": "forgits",
+ "forgive": "forgie",
+ "forgives": "forgies",
+ "forgot": "forgat",
+ "forsake": "forhou",
+ "forward": "forrit",
+ "fought": "feuchen",
+ "foul": "fyle",
+ "found": "funnd",
+ "four": "fower",
+ "fox": "tod",
+ "friend": "pal",
+ "friends": "mukkers",
+ "from": "fae",
+ "front": "foreside",
+ "frown": "glunch",
+ "frowned": "glunch'd",
+ "full": "stowed oot",
+ "fumble": "ficher",
+ "fumbled": "ficher'd",
+ "fumbles": "fichers",
+ "further": "farder",
+ "furthest": "benmaist",
+ "fussy": "fykie",
+ "gate": "yett",
+ "get": "git",
+ "gets": "gits",
+ "ghost": "ghaist",
+ "ghostdrone": "ghaistbum",
+ "ghostdrones": "ghaistbums",
+ "ghosts": "ghaists",
+ "gibberish": "blethers",
+ "girl": "lassie",
+ "girls": "lassies ",
+ "give": "gie",
+ "given": "gied",
+ "gives": "gies",
+ "glare": "glower",
+ "glared": "glower'd",
+ "glove": "gluive",
+ "gloves": "gluives",
+ "glow": "glowe",
+ "glows": "glowes",
+ "go": "gae",
+ "goat": "gait",
+ "goats": "gaits",
+ "goes": "gaes",
+ "going": "gaein",
+ "gone": "gaen",
+ "good": [
+ "braw",
+ "guid"
+ ],
+ "goodbye": "fare ye weel",
+ "gosh": "jings",
+ "got": "gat",
+ "grandmother": "aulddame",
+ "great": [
+ "braw",
+ "stoatin"
+ ],
+ "grin": "gandge",
+ "grip": "yoke",
+ "groin": "lisk",
+ "grow": "growe",
+ "grown": "growed",
+ "grows": "growes",
+ "guard": "waird",
+ "guess": "jalouse",
+ "guest": "caa'er",
+ "guests": "caa'ers",
+ "had": "haed",
+ "hadn't": "haednae",
+ "hadnt": "haednae",
+ "haggling": "priggin",
+ "half": "hauf",
+ "halfwit": "haiverel",
+ "halfwits": "haiverel",
+ "hall": "haa",
+ "halt": "stoppit",
+ "hammer": "haimer",
+ "hammers": "haimers",
+ "hand": "haun",
+ "handcuff": "haundshackle",
+ "handcuffed": "haundshackled",
+ "handcuffing": "haundshackling",
+ "handcuffs": "shangies",
+ "handle": "haunnle",
+ "hands": "hauns",
+ "hang": "hing",
+ "happy": "blythe",
+ "hard": "haurd",
+ "hardly": "haurdlie",
+ "harm": "skaith",
+ "harvest": "hairst",
+ "harvests": "hairsts",
+ "have": "hae",
+ "haven't": "hinna",
+ "havent": "hinna",
+ "head": "heid",
+ "healthy": "brosie",
+ "heard": "haurd",
+ "heart": "hert",
+ "hearty": "herty",
+ "hedgehog": "hurchin",
+ "hedgehogs": "hurchins",
+ "hello": "hullo",
+ "helmet": "helm",
+ "helmets": "helms",
+ "help": "hulp",
+ "helped": "helpit",
+ "hen": "chuck",
+ "hens": "chucks",
+ "hid": "dern'd",
+ "hidden": "dern'd",
+ "hide": "dern",
+ "hides": "derns",
+ "high": "hie",
+ "highest": "hiest",
+ "highland": "hielan'",
+ "highlands": "hielands",
+ "hit": "clout",
+ "hits": "clouts",
+ "hoarse": "hersh",
+ "holy": "halie",
+ "home": "hame",
+ "honey": "hinnie",
+ "hope": "houpe",
+ "hopes": "houpes",
+ "horrible": "gruesome",
+ "hot": "het",
+ "house": "hoose",
+ "how": "howfur",
+ "howl": "yowl",
+ "howled": "yowled",
+ "howling": "yowling",
+ "howls": "yowls",
+ "hungry": "hungert",
+ "husband": "guidman",
+ "husbands": "guidmen",
+ "idea": "conceit",
+ "ideas": "conceits",
+ "idiot": "eejit",
+ "idiots": "eejits",
+ "ill": "unweel",
+ "im": "a'm",
+ "i'm": "a'm",
+ "import": "inbring",
+ "incantation": "cantrip",
+ "incantations": "cantrips",
+ "industrious": "eydent",
+ "infinite": "mairchless",
+ "inject": "jag",
+ "injected": "jagit",
+ "injection": "jag",
+ "injections": "jag",
+ "insect": "beastie",
+ "insects": "beasties",
+ "inside": "inby",
+ "into": "intae",
+ "ireland": "airlan",
+ "island": "islan",
+ "islands": "islans",
+ "isn't": "isna",
+ "isnt": "isna",
+ "issue": "aishan",
+ "it's": "hit's",
+ "it": "hit",
+ "its": "hits",
+ "jar": "jaur",
+ "jars": "jaurs",
+ "jig's": "jeeg's",
+ "jig": "jeeg",
+ "jigs": "jeegs",
+ "join": "jine",
+ "jolly": "waulie",
+ "judge": "juidge",
+ "judged": "juidgit",
+ "judges": "juidges",
+ "jump": "loup",
+ "jumped": "lowpen",
+ "jumping": "loupin",
+ "jumpsuit's": "carsakie's",
+ "jumpsuit": "carsackie",
+ "jumpsuits": "carsakies",
+ "just": "jist",
+ "kept": "keepit",
+ "killed": "kilt",
+ "kind": "kin",
+ "kindly": "kin'ly",
+ "kitchen": "keetchin",
+ "know": "ken",
+ "known": "kent",
+ "knows": "ken",
+ "laid": "leen",
+ "lake": "loch",
+ "lakes": "lochs",
+ "land": "lan",
+ "large": "muckle",
+ "last": "lest",
+ "lasted": "lestit",
+ "lasts": "lests",
+ "lawyer": "lawer",
+ "lawyers": "lawers",
+ "lay": "lee",
+ "lazy": "thowless",
+ "leap": "loup",
+ "leaping": "loupin",
+ "leapt": "lowpen",
+ "learn": "lairn",
+ "learned": "lairnt",
+ "learns": "lairns",
+ "leave": "lea'",
+ "lend": "len",
+ "length": "lenth",
+ "lengths": "lenths",
+ "let": "lat",
+ "letter": "screive",
+ "liar": "leear",
+ "liars": "leears",
+ "lie": "lee",
+ "lifted": "liftit",
+ "light": "licht",
+ "lightning": "fire-flaucht",
+ "like": "lik",
+ "liked": "likit",
+ "limp": "hirple",
+ "liquor": "spunkie",
+ "list": "leet",
+ "little": "wee",
+ "live": "bide",
+ "lived": "bade",
+ "lively": "birkie",
+ "lives": "bides",
+ "load": "lade",
+ "loaded": "laden",
+ "loading": "laden'",
+ "loads": "lades",
+ "lobster": "lapster",
+ "lobsters": "lapsters",
+ "long": "lang",
+ "look": "leuk",
+ "looked": "leukit",
+ "looks": "leuks",
+ "lore": "lear",
+ "lose": "tyne",
+ "loses": "tynes",
+ "lost": "tint",
+ "lot": "wheen",
+ "loud": "lood",
+ "louse": "cootie",
+ "love": "loo",
+ "loved": "loo'd",
+ "loves": "loos",
+ "loving": "looin",
+ "low": "wee",
+ "lowest": "blomaist",
+ "lump": "dod",
+ "made": "makkit",
+ "magic": "glammerie",
+ "make": "mak",
+ "man": "jimmy",
+ "manure": "aidle",
+ "many": "mony",
+ "married": "merrit",
+ "may": "can",
+ "maybe": "mibbie",
+ "meat": "flesh",
+ "merchant's": "packman's",
+ "merchant": "packman",
+ "merchants'": "packmens'",
+ "merchants": "packmen",
+ "mess": "fankle",
+ "mice": "myce",
+ "might": "micht",
+ "mightn't": "michtna",
+ "mightnt": "michtna",
+ "milk": "mulk",
+ "min": "min'",
+ "mine": "mines",
+ "mire": "glaur",
+ "mischeivous": "ill-trickit",
+ "miss": "tyne",
+ "misses": "tynes",
+ "missing": "amissin",
+ "mistake": "mistak",
+ "mistaken": "mistaen",
+ "mixture": "mixtur",
+ "mole": "mowdiewarp",
+ "moles": "mowdiewarps",
+ "money": "clink",
+ "monkey": "puggie",
+ "monkeys": "puggies",
+ "monkies": "puggies",
+ "moor": "muir",
+ "more": "mair",
+ "moron": "baw juggler",
+ "morons": "dunderheids",
+ "most": "maist",
+ "moth": "blinnd-bat",
+ "mother": "maw",
+ "moths": "blinnd-bats",
+ "mountain": "ben",
+ "mountains": "bens",
+ "mouse": "moose",
+ "moustache": "mouser",
+ "moustaches": "mousers",
+ "mouth": "gob",
+ "move": "flit",
+ "moved": "flittit",
+ "moves": "flits",
+ "much": "muckle",
+ "muddled": "doited",
+ "music": "muisic",
+ "must": "maun",
+ "mustache": "mouser",
+ "mustaches": "mousers",
+ "mustn't": "maunna",
+ "mustnt": "maunna",
+ "my": "ma",
+ "myself": "masel",
+ "naked": "nakit",
+ "nanotrasen": "nanotraisen",
+ "natural": "naitral",
+ "nature": "naitur",
+ "near": "naur",
+ "nearer": "naurer",
+ "nearest": "naurmaist",
+ "needed": "needit",
+ "needn't": "needna",
+ "neednt": "needna",
+ "neither": "nane",
+ "nestle": "coorie",
+ "never": "ne'er",
+ "news": "bizz",
+ "next": "neist",
+ "nice": "crakin",
+ "night": "nicht",
+ "nights": "nichts",
+ "nit": "cootie",
+ "no": "nae",
+ "none": "nane",
+ "nonsense": [
+ "haivers",
+ "havers",
+ "pish"
+ ],
+ "north": "nor",
+ "northern": "norlins",
+ "northernmost": "normaist",
+ "northmost": "normasit",
+ "not": "no",
+ "nothing": "hee haw",
+ "now": "nou",
+ "number": "hantle",
+ "numbers": "hantles",
+ "oak": "aik",
+ "oat": "aits",
+ "oats": "aits",
+ "obliged": "behauden",
+ "of": "o'",
+ "off": "aff",
+ "officer": "boaby",
+ "officers": "boabies",
+ "often": "aften",
+ "oh": "och",
+ "oil": "ile",
+ "old": "auld",
+ "once": "yinst",
+ "one": "ane",
+ "onion": "ingan",
+ "onions": "ingans",
+ "opened": "opent",
+ "opposite": "forgain",
+ "oppressed": "dounhauden",
+ "other": "ither",
+ "our": "oor",
+ "ourselves": "oorsels",
+ "out": "oot",
+ "outside": "ootside",
+ "oven": "uin",
+ "ovens": "uins",
+ "over": "oot ower",
+ "owe": "awe",
+ "owes": "awes",
+ "owl": "howlet",
+ "owls": "howlets",
+ "own": "ain",
+ "owned": "awned",
+ "owns": "awns",
+ "painting": "pentin",
+ "pale": "peely-wally",
+ "pants": "trews",
+ "parcel": "paircel",
+ "parched": "drouchtit",
+ "park": "pairk",
+ "part": "pairt",
+ "parted": "pairted",
+ "partial": "pairtial",
+ "parts": "pairts",
+ "path": "pad",
+ "pebble": [
+ "chuckie",
+ "chuckie-stane"
+ ],
+ "pebbles": "chuckie-stanes",
+ "pee": "strone",
+ "peed": "stroned",
+ "pees": "strones",
+ "people": "fowk",
+ "person": "chiel",
+ "pet": "daut",
+ "pets": "dauts",
+ "petted": "dautit",
+ "petting": "dautin'",
+ "phantom": "bogle",
+ "phone": "phane",
+ "phones": "phanes",
+ "picture": "pictur",
+ "pictures": "picturs",
+ "pierce": "thirl",
+ "pigeon": "doo",
+ "piss": "pish",
+ "pissed": "pished",
+ "pisses": "pishes",
+ "place": "stell",
+ "placed": "stellt",
+ "places": "airts",
+ "play": "daff",
+ "played": "dafft",
+ "plays": "daffs",
+ "pocket": "pooch",
+ "pockets": "pooches",
+ "point": "pynt",
+ "pointed": "pynted",
+ "points": "pynt",
+ "poison": "pushion",
+ "poisoned": "pushionit",
+ "poisoning": "pushionin'",
+ "poisons": "pushions",
+ "poke": "powk",
+ "poked": "powkit",
+ "pokes": "powks",
+ "poking": "powkin'",
+ "police": "polis",
+ "poo": "keech",
+ "pool": "puil",
+ "poor": "pair",
+ "position": "poseetion",
+ "potato": "tattie",
+ "potatoes": "tatties",
+ "powder": "pouther",
+ "power": "pouer",
+ "present": "praisent",
+ "pretty": "bonny",
+ "prick": "jag",
+ "pricked": "jagit",
+ "pricks": "jags",
+ "probably": "likelie",
+ "proof": "prief",
+ "properly": "swash",
+ "proud": "prood",
+ "prove": "pruve",
+ "proved": "pruved",
+ "proves": "pruves",
+ "pub": "inns",
+ "puddle": "dub",
+ "pull": "pu'",
+ "pulled": "pu'd",
+ "pulls": "pu's",
+ "punch": "batter",
+ "punches": "batters",
+ "push": "pouss",
+ "pushed": "poussit",
+ "pushes": "pouss'",
+ "pushing": "poussin'",
+ "put": "pat",
+ "puts": "pits",
+ "quiet": "weesht",
+ "quit": "quitten",
+ "quite": "fair",
+ "rain": "smirr",
+ "ran": "run",
+ "raspberry": "rasp",
+ "rat": "rottan",
+ "rather": "raither",
+ "raven": "raen",
+ "real": "rael",
+ "reaper": "shearer",
+ "reason": "raison",
+ "reasons": "raisons",
+ "red": "rid",
+ "remember": "mind",
+ "replied": "reponed",
+ "reply": "repone",
+ "resident": "indwaller",
+ "residents": "indwallers",
+ "resign": "demit",
+ "retch": "boak",
+ "retches": "boaks",
+ "ridge": "rig",
+ "ridges": "rigs",
+ "right": "richt",
+ "roar": "rair",
+ "roared": "rair't",
+ "roars": "rairs",
+ "rob": "rab",
+ "room": "chaummer",
+ "root": "ruit",
+ "rope": "raip",
+ "rubber": "cahoutchie",
+ "ruffle": "tousle",
+ "run": "rin",
+ "rural": "landwart",
+ "rush": "breeshle",
+ "rust": "roust",
+ "sad": "dowie",
+ "said": "sayed",
+ "scare": "scaur",
+ "scariest": "skeeriest",
+ "scary": "scaury",
+ "school": "schuil",
+ "scientific": "scienteefic",
+ "scissors": "sheers",
+ "scold": "scaud",
+ "scone": "bannock",
+ "scorch": "birsle",
+ "scowl": "scoul",
+ "scowls": "scouls",
+ "scratch": "scart",
+ "scream": "skriegh",
+ "screaming": "skrieghin'",
+ "screams": "skreighs",
+ "seal": "cowan",
+ "seals": "cowans",
+ "sec": "polis",
+ "second": "saicont",
+ "security": "polis",
+ "seem": "kythe",
+ "seemed": "kythed",
+ "seems": "kythes",
+ "separate": "twyne",
+ "servant": "skivvy",
+ "seven": "sieven",
+ "shake": "shak",
+ "shaken": "shakit",
+ "shakes": "shaks",
+ "shall": "sall",
+ "shell": "sheel",
+ "shelter": "bield",
+ "sherrif": "shirra",
+ "shivering": "ourie",
+ "shoes": "shoon",
+ "shook": [
+ "shakit",
+ "sheuk"
+ ],
+ "shop": "shap",
+ "shopping": "messages",
+ "shops": "shaps",
+ "should": "shoud",
+ "shouldn't": "shoudna",
+ "shouldnt": "shoudna",
+ "shovel": "shool",
+ "shovels": "shools",
+ "shrunken": "cruppen",
+ "shy": "blate",
+ "sicken": "scunner",
+ "sickening": "scunnersome",
+ "sigh": "sech",
+ "sighs": "soughs",
+ "silver": "sillar",
+ "singed": "singet",
+ "skip": "fimmer",
+ "skips": "fimmers",
+ "slap": "clout",
+ "slaps": "clouts",
+ "slept": "sleepit",
+ "slid": "slidden",
+ "slip": "slup",
+ "slippery": "slidie",
+ "slips": "slups",
+ "slope": "brae",
+ "sly": "slee",
+ "smack": "skelp",
+ "smacks": "skelps",
+ "small": "wee",
+ "smart": "snap",
+ "smile": "smirk",
+ "smiles": "smous",
+ "smoke": "reek",
+ "smoked": "reekit",
+ "smokes": "reeks",
+ "smoking": "reekin'",
+ "sneeze": "sneesh",
+ "snow": "snaw",
+ "snowflake": "pyle",
+ "so": "sae",
+ "soap": "saip",
+ "sold": "selt",
+ "some": "som",
+ "someone": "a bodie",
+ "sometimes": "whyles",
+ "somewhat": "fair",
+ "song": "sang",
+ "songs": "sangs",
+ "soothe": "dill",
+ "sore": "sair",
+ "sound": "soond",
+ "sounded": "soonded",
+ "sounds": "soonds",
+ "soup": "broo",
+ "south": "sooth",
+ "southern": "soothron",
+ "southernmost": "soothmaist",
+ "southmost": "soothmaist",
+ "spacemas": "Yule",
+ "sparkle": "glint",
+ "sparkled": "glintit",
+ "sparkles": "glints",
+ "sparkling": "begesserant",
+ "spat": "sputten",
+ "speak": "spaek",
+ "speaks": "spaeks",
+ "spelled": "spellt",
+ "spider": "speeder",
+ "spin": "birl",
+ "spine": "rig",
+ "spines": "rigs",
+ "spinning": "birlin'",
+ "spins": "birls",
+ "spit": "speet",
+ "spoil": "blaud",
+ "spoils": "blauds",
+ "spoke": "spak",
+ "spoon": "spuin",
+ "squeal": "squyle",
+ "squint": "skelly",
+ "stagger": "stoiter",
+ "staggered": "stoiter'd",
+ "staggers": "stoiters",
+ "stand": "staun",
+ "star": "starn",
+ "stare": "gove",
+ "stared": "glourt",
+ "stares": "goves",
+ "stars": "starns",
+ "start": "stert",
+ "started": "stertit",
+ "starts": "sterts",
+ "stay": "bide",
+ "stays": "bides",
+ "stead": "steid",
+ "stench": "bowf",
+ "stiff": "stechie",
+ "still": "yet",
+ "stink": "bowf",
+ "stinks": "bowfs",
+ "stir": "steer",
+ "stirs": "steers",
+ "stole": "stealt",
+ "stolen": "stown",
+ "stomach": "wame",
+ "stone": "stane",
+ "stones": "stanes",
+ "stopped": "stoppit",
+ "stout": "stoot",
+ "stream": "burn",
+ "stretch": "streek",
+ "stretched": "streekit",
+ "stretches": "streeks",
+ "striped": "strippit",
+ "stroll": "daunder",
+ "struck": "strak",
+ "stuck": "stickit",
+ "stuff": "stech",
+ "stumble": "doiter",
+ "stumbled": "stoited",
+ "stumbles": "doiters",
+ "stunned": "donnert",
+ "stupid": "glaikit",
+ "such": "sic",
+ "sunset": "sindoun",
+ "suppose": "daursay",
+ "sure": "shuir",
+ "surely": "shuirlie",
+ "swallow": "swallae",
+ "swallowed": "swallae'd",
+ "swallows": "swallaes",
+ "swarm": "byke",
+ "swear": "sweir",
+ "sweared": "sweired",
+ "swearing": "sweiring",
+ "swears": "sweirs",
+ "swell": "swall",
+ "swelled": "swall'd",
+ "table": "boord",
+ "tables": "boords",
+ "tadpole": "poweheid",
+ "take": "tak",
+ "taken": "taen",
+ "takes": "taks",
+ "talk": "tauk",
+ "tangled": "tousled",
+ "taste": "pree",
+ "tasted": "pree'd",
+ "tasteless": "warsh",
+ "tastes": "prees",
+ "tavern": "inns",
+ "terrible": "tairible",
+ "than": "nor",
+ "thank": "thenk",
+ "that": "thon",
+ "the": "th'",
+ "their": "thair",
+ "theirs": "thairs",
+ "them": "thaim",
+ "themselves": "thairsels",
+ "then": "than",
+ "there's": "thonder's",
+ "there": "thonder",
+ "they": "thay",
+ "thirst": "drouth",
+ "thirsts": "drouths",
+ "thirsty": "drouthy",
+ "those": "they",
+ "thought": "thocht",
+ "thousand": "thoosan",
+ "thousands": "thoosans",
+ "thousandth": "thoosant",
+ "thrashed": "thruishen",
+ "thrilled": "thirl'd",
+ "throat": "thrapple",
+ "through": "throu'",
+ "thundering": "dunderin",
+ "tidy": "doss",
+ "tingle": "fissle",
+ "tiny": [
+ "tottie",
+ "toty"
+ ],
+ "to": "tae",
+ "tobacco": "baccie",
+ "today": "th'day",
+ "together": "thegither",
+ "toilet": "cludgie",
+ "toilets": "cludgies",
+ "token": "taiken",
+ "told": "tellt",
+ "tomorrow": "th' morra",
+ "tonight": "thenicht",
+ "too": "tae",
+ "took": "teuk",
+ "top": "tap",
+ "tore": "tuir",
+ "tortoise": "tortie",
+ "tough": "teugh",
+ "town": "toon",
+ "trader's": "dealer's",
+ "trader": "dealer",
+ "traders'": "dealers'",
+ "traders": "dealers",
+ "translated": "owerset",
+ "treason": "traison",
+ "trick": "brogue",
+ "tried": "ettelt",
+ "tries": "ettles",
+ "trigger": "tricker",
+ "triggered": "tricker'd",
+ "triggering": "trickerin'",
+ "triggers": "trickers",
+ "trouble": "trauchle",
+ "trousers": "breeks",
+ "trurth": "trowth",
+ "try": "huv a go",
+ "tumble": "cowp",
+ "turf": "divot",
+ "turfs": "divots",
+ "turn": "birl",
+ "turned": "birlt",
+ "turning": "birlin'",
+ "turnip": "neep",
+ "turnips": "neeps",
+ "turns": "birls",
+ "twist": "swirl",
+ "twisted": "swirlie",
+ "twists": "skewls",
+ "two": "twa",
+ "unbolt": "unsnib",
+ "uncertain": "unsicker",
+ "under": "unner",
+ "understand": "unnerstaund",
+ "understands": "unnerstaunds",
+ "unhurt": "unskaithed",
+ "uninvited": "unbidden",
+ "unknown": "unkent",
+ "unlucky": "wanchancie",
+ "until": "till",
+ "us": "hus",
+ "usage": "uisage",
+ "use": "uise",
+ "used": "uised",
+ "useless": "uissless",
+ "uses": "uises",
+ "valley": "glen",
+ "valleys": "glens",
+ "value": "feck",
+ "vegetables": "greens",
+ "venture": "anter",
+ "very": "verra",
+ "vessel": "veshel",
+ "vessels": "veshel",
+ "vision": "veesion",
+ "visions": "veesion",
+ "visit": "veesit",
+ "visitor": "caa'er",
+ "visitors": "caa'ers",
+ "vomit": "boak",
+ "vomits": "boaks",
+ "wages": "wauges",
+ "walk": "traivel",
+ "walked": "traivelt",
+ "walks": "traivels",
+ "wall": "dike",
+ "walls": "dikes",
+ "wand": "wannd",
+ "wander": "daunder",
+ "wandered": "daundert",
+ "wanders": "daunders",
+ "want": "waant",
+ "wanted": "wantit",
+ "warm": "beek",
+ "was": "wis",
+ "washed": "washt",
+ "wasn't": "wisna",
+ "wasnt": "wisna",
+ "watched": "watcht",
+ "water": "watter",
+ "way": "gate",
+ "ways": "gates",
+ "weak": "fushionless",
+ "website": "wasteid",
+ "weep": "greet",
+ "welcome": "walcome",
+ "well": "weel",
+ "went": "gaed",
+ "were": "war",
+ "weren't": "warna",
+ "werent": "warna",
+ "west": "wast",
+ "westernmost": "wastmaist",
+ "westmost": "wastmaist",
+ "westward": "wastart",
+ "wet": "drookit",
+ "what": "whit",
+ "whatever": "whitsomiver",
+ "whatsoever": "whitsaeiver",
+ "where's": "whaur's",
+ "where": "whaur",
+ "whiskey": "usquebaugh",
+ "whistle": "wheiple",
+ "whistles": "wheiples",
+ "who": "wha",
+ "whole": "hail",
+ "whom": "wham",
+ "whose": "whase",
+ "wife": "guidwife",
+ "will": "wull",
+ "win": "wun",
+ "wind": "wynd",
+ "window": "winnock",
+ "windows": "winnocks",
+ "wing": "weeng",
+ "wings": "weengs",
+ "wipe": "dight",
+ "wipes": "dights",
+ "wire-cutters": "weir-sheers",
+ "wire": "weir",
+ "wirecutters": "weirsheers",
+ "wisdom": "gumption",
+ "wish": "wiss",
+ "wished": "wisst",
+ "wishes": "wisses",
+ "witch's": "carlin's",
+ "witch": "carlin",
+ "witches": "carlins",
+ "with": "wi",
+ "within": "aithin",
+ "without": "athoot",
+ "witless": "doitert",
+ "wives": "guidwifes",
+ "wizard's": "warlock's",
+ "wizard": "warlock",
+ "wizards": "warlocks",
+ "woman": "hen",
+ "women": "kimmers",
+ "won't": "winna",
+ "won": "wun",
+ "wonder": "wonner",
+ "wont": "winna",
+ "wood": "wid",
+ "wool": "woo'",
+ "word": "wird",
+ "words": "wirds",
+ "work": "wark",
+ "worked": "wrocht",
+ "world": "warld",
+ "worried": "wirried",
+ "worries": "wirries",
+ "worry": "wirrie",
+ "worst": "wast",
+ "worth": "wirth",
+ "would": "wad",
+ "wouldn't": "wadna",
+ "wouldnt": "wadna",
+ "wrench": "wranch",
+ "wrenches": "wranches",
+ "writ": "wrate",
+ "write": "screive",
+ "writes": "scrieves",
+ "wrong": "wrang",
+ "wrote": "wrat",
+ "yes": "aye",
+ "you": "ye",
+ "your": "yer",
+ "yeah": "aye",
+ "yourself": "yersel",
+ "yourselves": "yersels",
+ "youth": "weans",
+ "zero": "hee-haw"
+ }
+}
\ No newline at end of file
diff --git a/strings/names/dwarf_first.txt b/strings/names/dwarf_first.txt
new file mode 100644
index 0000000000..a5de072053
--- /dev/null
+++ b/strings/names/dwarf_first.txt
@@ -0,0 +1,42 @@
+Thizuil
+Dondock
+Nemdout
+Ararhir
+Kadeag
+Elminister
+Nursan
+Grimm
+Matgroir
+Thosotir
+Jatdrouc
+Kaschei
+Khelben
+Kreol
+Dalofrubelyn
+Reirgrebyrn
+Hosdrum
+Mordenkainen
+Sarbarra
+Mystryl
+Nihilus
+Palando
+Prospero
+Radagast
+Burroutalyn
+Vargibela
+Saruman
+Tenser
+Terefi
+Tzeentch
+Gotdrilyn
+Vaarsuvius
+Erisseadrid
+Arazzanelyn
+Zagyg
+Dargroungrid
+Urist
+Durimarlum
+Matgrous
+Kissaet
+Magni
+Muradin
\ No newline at end of file
diff --git a/strings/names/dwarf_last.txt b/strings/names/dwarf_last.txt
new file mode 100644
index 0000000000..17fdb7f4d2
--- /dev/null
+++ b/strings/names/dwarf_last.txt
@@ -0,0 +1,45 @@
+Brightjaw
+Steelbrew
+Grimtank
+Mudback
+Brickbane
+Smeltmaster
+Lavabrow
+Woldtoe
+Deephelm
+Earthpike
+Berylshield
+Asharmour
+Caskspine
+Rubygrip
+Noblemaster
+Flintgrip
+Thunderchest
+Ignotchest
+Cragborg
+Jadearm
+Hornbelt
+Fierygranite
+Twilightbane
+Leadforge
+Kragthane
+Oakenaxe
+Beastback
+Coinbender
+Bronzejaw
+Mithrilrock
+Barrelhood
+Grumblesphere
+Graybane
+Flattoe
+Steelmaker
+Bronzebeard
+Kragcloak
+Magmaborn
+Gravelbasher
+Whitbrew
+McUristurister
+Mountaincoat
+Chaosbane
+Darksunder
+Bronzebeard
\ No newline at end of file
diff --git a/tgstation.dme b/tgstation.dme
index cceeb1f915..9e52889df7 100755
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -16,6 +16,7 @@
#include "_maps\_basemap.dm"
#include "code\_compile_options.dm"
#include "code\world.dm"
+#include "code\__DEFINES\__513_compatibility.dm"
#include "code\__DEFINES\_globals.dm"
#include "code\__DEFINES\_protect.dm"
#include "code\__DEFINES\_tick.dm"
@@ -44,10 +45,10 @@
#include "code\__DEFINES\donator_groupings.dm"
#include "code\__DEFINES\events.dm"
#include "code\__DEFINES\exports.dm"
+#include "code\__DEFINES\fantasy_affixes.dm"
#include "code\__DEFINES\flags.dm"
#include "code\__DEFINES\food.dm"
#include "code\__DEFINES\footsteps.dm"
-#include "code\__DEFINES\forensics.dm"
#include "code\__DEFINES\hud.dm"
#include "code\__DEFINES\integrated_electronics.dm"
#include "code\__DEFINES\interaction_flags.dm"
@@ -231,6 +232,7 @@
#include "code\controllers\subsystem\atoms.dm"
#include "code\controllers\subsystem\augury.dm"
#include "code\controllers\subsystem\blackbox.dm"
+#include "code\controllers\subsystem\chat.dm"
#include "code\controllers\subsystem\communications.dm"
#include "code\controllers\subsystem\dbcore.dm"
#include "code\controllers\subsystem\dcs.dm"
@@ -343,6 +345,7 @@
#include "code\datums\components\_component.dm"
#include "code\datums\components\anti_magic.dm"
#include "code\datums\components\armor_plate.dm"
+#include "code\datums\components\bane.dm"
#include "code\datums\components\bouncy.dm"
#include "code\datums\components\butchering.dm"
#include "code\datums\components\caltrop.dm"
@@ -356,10 +359,12 @@
#include "code\datums\components\empprotection.dm"
#include "code\datums\components\footstep.dm"
#include "code\datums\components\forced_gravity.dm"
-#include "code\datums\components\forensics.dm"
+#include "code\datums\components\igniter.dm"
#include "code\datums\components\infective.dm"
#include "code\datums\components\jousting.dm"
+#include "code\datums\components\knockback.dm"
#include "code\datums\components\knockoff.dm"
+#include "code\datums\components\lifesteal.dm"
#include "code\datums\components\lockon_aiming.dm"
#include "code\datums\components\magnetic_catch.dm"
#include "code\datums\components\material_container.dm"
@@ -369,22 +374,29 @@
#include "code\datums\components\ntnet_interface.dm"
#include "code\datums\components\orbiter.dm"
#include "code\datums\components\paintable.dm"
+#include "code\datums\components\phantomthief.dm"
#include "code\datums\components\rad_insulation.dm"
#include "code\datums\components\radioactive.dm"
#include "code\datums\components\remote_materials.dm"
#include "code\datums\components\riding.dm"
#include "code\datums\components\rotation.dm"
-#include "code\datums\components\signal_redirect.dm"
+#include "code\datums\components\shrapnel.dm"
#include "code\datums\components\slippery.dm"
#include "code\datums\components\spooky.dm"
#include "code\datums\components\squeak.dm"
#include "code\datums\components\stationloving.dm"
+#include "code\datums\components\summoning.dm"
#include "code\datums\components\swarming.dm"
+#include "code\datums\components\tactical.dm"
#include "code\datums\components\thermite.dm"
#include "code\datums\components\uplink.dm"
+#include "code\datums\components\virtual_reality.dm"
#include "code\datums\components\wearertargeting.dm"
#include "code\datums\components\wet_floor.dm"
-#include "code\datums\components\decals\blood.dm"
+#include "code\datums\components\fantasy\_fantasy.dm"
+#include "code\datums\components\fantasy\affix.dm"
+#include "code\datums\components\fantasy\prefixes.dm"
+#include "code\datums\components\fantasy\suffixes.dm"
#include "code\datums\components\storage\storage.dm"
#include "code\datums\components\storage\concrete\_concrete.dm"
#include "code\datums\components\storage\concrete\bag_of_holding.dm"
@@ -577,10 +589,12 @@
#include "code\game\machinery\autolathe.dm"
#include "code\game\machinery\bank_machine.dm"
#include "code\game\machinery\Beacon.dm"
+#include "code\game\machinery\bloodbankgen.dm"
#include "code\game\machinery\buttons.dm"
#include "code\game\machinery\cell_charger.dm"
#include "code\game\machinery\cloning.dm"
#include "code\game\machinery\constructable_frame.dm"
+#include "code\game\machinery\cryopod.dm"
#include "code\game\machinery\dance_machine.dm"
#include "code\game\machinery\defibrillator_mount.dm"
#include "code\game\machinery\deployable.dm"
@@ -620,6 +634,7 @@
#include "code\game\machinery\syndicatebomb.dm"
#include "code\game\machinery\teleporter.dm"
#include "code\game\machinery\transformer.dm"
+#include "code\game\machinery\turnstile.dm"
#include "code\game\machinery\washing_machine.dm"
#include "code\game\machinery\wishgranter.dm"
#include "code\game\machinery\camera\camera.dm"
@@ -641,13 +656,11 @@
#include "code\game\machinery\computer\communications.dm"
#include "code\game\machinery\computer\crew.dm"
#include "code\game\machinery\computer\dna_console.dm"
-#include "code\game\machinery\computer\gulag_teleporter.dm"
#include "code\game\machinery\computer\launchpad_control.dm"
#include "code\game\machinery\computer\law.dm"
#include "code\game\machinery\computer\medical.dm"
#include "code\game\machinery\computer\Operating.dm"
#include "code\game\machinery\computer\pod.dm"
-#include "code\game\machinery\computer\prisoner.dm"
#include "code\game\machinery\computer\robot.dm"
#include "code\game\machinery\computer\security.dm"
#include "code\game\machinery\computer\station_alert.dm"
@@ -712,6 +725,7 @@
#include "code\game\mecha\combat\gygax.dm"
#include "code\game\mecha\combat\honker.dm"
#include "code\game\mecha\combat\marauder.dm"
+#include "code\game\mecha\combat\neovgre.dm"
#include "code\game\mecha\combat\phazon.dm"
#include "code\game\mecha\combat\reticence.dm"
#include "code\game\mecha\equipment\mecha_equipment.dm"
@@ -754,6 +768,7 @@
#include "code\game\objects\effects\decals\misc.dm"
#include "code\game\objects\effects\decals\remains.dm"
#include "code\game\objects\effects\decals\cleanable\aliens.dm"
+#include "code\game\objects\effects\decals\cleanable\gibs.dm"
#include "code\game\objects\effects\decals\cleanable\humans.dm"
#include "code\game\objects\effects\decals\cleanable\misc.dm"
#include "code\game\objects\effects\decals\cleanable\robots.dm"
@@ -914,15 +929,16 @@
#include "code\game\objects\items\implants\implant_krav_maga.dm"
#include "code\game\objects\items\implants\implant_mindshield.dm"
#include "code\game\objects\items\implants\implant_misc.dm"
+#include "code\game\objects\items\implants\implant_radio.dm"
#include "code\game\objects\items\implants\implant_spell.dm"
#include "code\game\objects\items\implants\implant_stealth.dm"
#include "code\game\objects\items\implants\implant_storage.dm"
#include "code\game\objects\items\implants\implant_track.dm"
+#include "code\game\objects\items\implants\implant_uplink.dm"
#include "code\game\objects\items\implants\implantcase.dm"
#include "code\game\objects\items\implants\implantchair.dm"
#include "code\game\objects\items\implants\implanter.dm"
#include "code\game\objects\items\implants\implantpad.dm"
-#include "code\game\objects\items\implants\implantuplink.dm"
#include "code\game\objects\items\melee\energy.dm"
#include "code\game\objects\items\melee\misc.dm"
#include "code\game\objects\items\melee\transforming.dm"
@@ -1035,6 +1051,7 @@
#include "code\game\objects\structures\crates_lockers\closets\bodybag.dm"
#include "code\game\objects\structures\crates_lockers\closets\cardboardbox.dm"
#include "code\game\objects\structures\crates_lockers\closets\fitness.dm"
+#include "code\game\objects\structures\crates_lockers\closets\genpop.dm"
#include "code\game\objects\structures\crates_lockers\closets\gimmick.dm"
#include "code\game\objects\structures\crates_lockers\closets\job_closets.dm"
#include "code\game\objects\structures\crates_lockers\closets\l3closet.dm"
@@ -1186,6 +1203,7 @@
#include "code\modules\antagonists\blob\blob\blobs\node.dm"
#include "code\modules\antagonists\blob\blob\blobs\resource.dm"
#include "code\modules\antagonists\blob\blob\blobs\shield.dm"
+#include "code\modules\antagonists\blood_contract\blood_contract.dm"
#include "code\modules\antagonists\brainwashing\brainwashing.dm"
#include "code\modules\antagonists\brother\brother.dm"
#include "code\modules\antagonists\changeling\cellular_emporium.dm"
@@ -1296,6 +1314,7 @@
#include "code\modules\antagonists\greentext\greentext.dm"
#include "code\modules\antagonists\greybois\greybois.dm"
#include "code\modules\antagonists\highlander\highlander.dm"
+#include "code\modules\antagonists\magic_servant\magic_servant.dm"
#include "code\modules\antagonists\monkey\monkey.dm"
#include "code\modules\antagonists\morph\morph.dm"
#include "code\modules\antagonists\morph\morph_antag.dm"
@@ -1317,6 +1336,7 @@
#include "code\modules\antagonists\revenant\revenant_blight.dm"
#include "code\modules\antagonists\revenant\revenant_spawn_event.dm"
#include "code\modules\antagonists\revolution\revolution.dm"
+#include "code\modules\antagonists\santa\santa.dm"
#include "code\modules\antagonists\separatist\separatist.dm"
#include "code\modules\antagonists\slaughter\slaughter.dm"
#include "code\modules\antagonists\slaughter\slaughter_antag.dm"
@@ -1462,11 +1482,25 @@
#include "code\modules\cargo\exports\large_objects.dm"
#include "code\modules\cargo\exports\manifest.dm"
#include "code\modules\cargo\exports\materials.dm"
+#include "code\modules\cargo\exports\orgains_robotics.dm"
#include "code\modules\cargo\exports\parts.dm"
#include "code\modules\cargo\exports\seeds.dm"
#include "code\modules\cargo\exports\sheets.dm"
#include "code\modules\cargo\exports\tools.dm"
#include "code\modules\cargo\exports\weapons.dm"
+#include "code\modules\cargo\packs\armory.dm"
+#include "code\modules\cargo\packs\costumes_toys.dm"
+#include "code\modules\cargo\packs\emergency.dm"
+#include "code\modules\cargo\packs\engine.dm"
+#include "code\modules\cargo\packs\engineering.dm"
+#include "code\modules\cargo\packs\livestock.dm"
+#include "code\modules\cargo\packs\materials.dm"
+#include "code\modules\cargo\packs\medical.dm"
+#include "code\modules\cargo\packs\misc.dm"
+#include "code\modules\cargo\packs\organic.dm"
+#include "code\modules\cargo\packs\science.dm"
+#include "code\modules\cargo\packs\security.dm"
+#include "code\modules\cargo\packs\service.dm"
#include "code\modules\chatter\chatter.dm"
#include "code\modules\client\asset_cache.dm"
#include "code\modules\client\client_colour.dm"
@@ -1519,6 +1553,7 @@
#include "code\modules\clothing\neck\_neck.dm"
#include "code\modules\clothing\outfits\ert.dm"
#include "code\modules\clothing\outfits\event.dm"
+#include "code\modules\clothing\outfits\plasmaman.dm"
#include "code\modules\clothing\outfits\standard.dm"
#include "code\modules\clothing\outfits\vr.dm"
#include "code\modules\clothing\outfits\vv_outfit.dm"
@@ -1561,9 +1596,18 @@
#include "code\modules\clothing\under\jobs\engineering.dm"
#include "code\modules\clothing\under\jobs\medsci.dm"
#include "code\modules\clothing\under\jobs\security.dm"
+#include "code\modules\clothing\under\jobs\Plasmaman\civilian_service.dm"
+#include "code\modules\clothing\under\jobs\Plasmaman\engineering.dm"
+#include "code\modules\clothing\under\jobs\Plasmaman\medsci.dm"
+#include "code\modules\clothing\under\jobs\Plasmaman\security.dm"
#include "code\modules\crafting\craft.dm"
#include "code\modules\crafting\guncrafting.dm"
#include "code\modules\crafting\recipes.dm"
+#include "code\modules\crafting\recipes\recipes_clothing.dm"
+#include "code\modules\crafting\recipes\recipes_misc.dm"
+#include "code\modules\crafting\recipes\recipes_primal.dm"
+#include "code\modules\crafting\recipes\recipes_robot.dm"
+#include "code\modules\crafting\recipes\recipes_weapon_and_ammo.dm"
#include "code\modules\detectivework\detective_work.dm"
#include "code\modules\detectivework\evidence.dm"
#include "code\modules\detectivework\scanner.dm"
@@ -1699,6 +1743,9 @@
#include "code\modules\goonchat\jsErrorHandler.dm"
#include "code\modules\holiday\easter.dm"
#include "code\modules\holiday\holidays.dm"
+#include "code\modules\holiday\halloween\bartholomew.dm"
+#include "code\modules\holiday\halloween\halloween.dm"
+#include "code\modules\holiday\halloween\jacqueen.dm"
#include "code\modules\holodeck\area_copy.dm"
#include "code\modules\holodeck\computer.dm"
#include "code\modules\holodeck\holo_effect.dm"
@@ -2060,6 +2107,7 @@
#include "code\modules\mob\living\carbon\human\species_types\bugmen.dm"
#include "code\modules\mob\living\carbon\human\species_types\corporate.dm"
#include "code\modules\mob\living\carbon\human\species_types\dullahan.dm"
+#include "code\modules\mob\living\carbon\human\species_types\dwarves.dm"
#include "code\modules\mob\living\carbon\human\species_types\felinid.dm"
#include "code\modules\mob\living\carbon\human\species_types\flypeople.dm"
#include "code\modules\mob\living\carbon\human\species_types\furrypeople.dm"
@@ -2136,6 +2184,7 @@
#include "code\modules\mob\living\simple_animal\shade.dm"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
#include "code\modules\mob\living\simple_animal\simple_animal_vr.dm"
+#include "code\modules\mob\living\simple_animal\simplemob_vore_values.dm"
#include "code\modules\mob\living\simple_animal\spawner.dm"
#include "code\modules\mob\living\simple_animal\status_procs.dm"
#include "code\modules\mob\living\simple_animal\bot\bot.dm"
@@ -2185,6 +2234,7 @@
#include "code\modules\mob\living\simple_animal\guardian\types\standard.dm"
#include "code\modules\mob\living\simple_animal\guardian\types\support.dm"
#include "code\modules\mob\living\simple_animal\hostile\alien.dm"
+#include "code\modules\mob\living\simple_animal\hostile\banana_spider.dm"
#include "code\modules\mob\living\simple_animal\hostile\bear.dm"
#include "code\modules\mob\living\simple_animal\hostile\bees.dm"
#include "code\modules\mob\living\simple_animal\hostile\carp.dm"
@@ -2192,6 +2242,7 @@
#include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm"
#include "code\modules\mob\living\simple_animal\hostile\faithless.dm"
#include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm"
+#include "code\modules\mob\living\simple_animal\hostile\goose.dm"
#include "code\modules\mob\living\simple_animal\hostile\headcrab.dm"
#include "code\modules\mob\living\simple_animal\hostile\hivebot.dm"
#include "code\modules\mob\living\simple_animal\hostile\hostile.dm"
@@ -2459,7 +2510,6 @@
#include "code\modules\projectiles\guns\energy\kinetic_accelerator.dm"
#include "code\modules\projectiles\guns\energy\laser.dm"
#include "code\modules\projectiles\guns\energy\megabuster.dm"
-#include "code\modules\projectiles\guns\energy\minigun.dm"
#include "code\modules\projectiles\guns\energy\mounted.dm"
#include "code\modules\projectiles\guns\energy\plasma_cit.dm"
#include "code\modules\projectiles\guns\energy\pulse.dm"
@@ -2514,6 +2564,7 @@
#include "code\modules\projectiles\projectile\special\temperature.dm"
#include "code\modules\projectiles\projectile\special\wormhole.dm"
#include "code\modules\reagents\chem_splash.dm"
+#include "code\modules\reagents\chem_wiki_render.dm"
#include "code\modules\reagents\reagent_containers.dm"
#include "code\modules\reagents\reagent_dispenser.dm"
#include "code\modules\reagents\chemistry\colors.dm"
@@ -2532,6 +2583,7 @@
#include "code\modules\reagents\chemistry\reagents\drink_reagents.dm"
#include "code\modules\reagents\chemistry\reagents\drug_reagents.dm"
#include "code\modules\reagents\chemistry\reagents\food_reagents.dm"
+#include "code\modules\reagents\chemistry\reagents\impure_reagents.dm"
#include "code\modules\reagents\chemistry\reagents\medicine_reagents.dm"
#include "code\modules\reagents\chemistry\reagents\other_reagents.dm"
#include "code\modules\reagents\chemistry\reagents\pyrotechnic_reagents.dm"
@@ -2549,6 +2601,7 @@
#include "code\modules\reagents\reagent_containers\dropper.dm"
#include "code\modules\reagents\reagent_containers\glass.dm"
#include "code\modules\reagents\reagent_containers\hypospray.dm"
+#include "code\modules\reagents\reagent_containers\hypovial.dm"
#include "code\modules\reagents\reagent_containers\medspray.dm"
#include "code\modules\reagents\reagent_containers\patch.dm"
#include "code\modules\reagents\reagent_containers\pill.dm"
@@ -2674,6 +2727,7 @@
#include "code\modules\ruins\spaceruin_code\crashedship.dm"
#include "code\modules\ruins\spaceruin_code\deepstorage.dm"
#include "code\modules\ruins\spaceruin_code\DJstation.dm"
+#include "code\modules\ruins\spaceruin_code\hilbertshotel.dm"
#include "code\modules\ruins\spaceruin_code\listeningstation.dm"
#include "code\modules\ruins\spaceruin_code\miracle.dm"
#include "code\modules\ruins\spaceruin_code\oldstation.dm"
@@ -2734,6 +2788,7 @@
#include "code\modules\spells\spell_types\spacetime_distortion.dm"
#include "code\modules\spells\spell_types\summonitem.dm"
#include "code\modules\spells\spell_types\taeclowndo.dm"
+#include "code\modules\spells\spell_types\telepathy.dm"
#include "code\modules\spells\spell_types\the_traps.dm"
#include "code\modules\spells\spell_types\touch_attacks.dm"
#include "code\modules\spells\spell_types\trigger.dm"
@@ -2748,13 +2803,18 @@
#include "code\modules\surgery\brain_surgery.dm"
#include "code\modules\surgery\cavity_implant.dm"
#include "code\modules\surgery\core_removal.dm"
+#include "code\modules\surgery\coronary_bypass.dm"
#include "code\modules\surgery\dental_implant.dm"
#include "code\modules\surgery\embalming.dm"
+#include "code\modules\surgery\experimental_dissection.dm"
#include "code\modules\surgery\eye_surgery.dm"
+#include "code\modules\surgery\graft_synthtissue.dm"
+#include "code\modules\surgery\healing.dm"
#include "code\modules\surgery\helpers.dm"
#include "code\modules\surgery\implant_removal.dm"
#include "code\modules\surgery\limb_augmentation.dm"
#include "code\modules\surgery\lipoplasty.dm"
+#include "code\modules\surgery\lobectomy.dm"
#include "code\modules\surgery\mechanic_steps.dm"
#include "code\modules\surgery\nutcracker.dm"
#include "code\modules\surgery\organ_manipulation.dm"
@@ -2769,15 +2829,14 @@
#include "code\modules\surgery\advanced\lobotomy.dm"
#include "code\modules\surgery\advanced\necrotic_revival.dm"
#include "code\modules\surgery\advanced\pacification.dm"
-#include "code\modules\surgery\advanced\reconstruction.dm"
#include "code\modules\surgery\advanced\revival.dm"
#include "code\modules\surgery\advanced\toxichealing.dm"
#include "code\modules\surgery\advanced\viral_bonding.dm"
#include "code\modules\surgery\advanced\bioware\bioware.dm"
#include "code\modules\surgery\advanced\bioware\bioware_surgery.dm"
-#include "code\modules\surgery\advanced\bioware\experimental_dissection.dm"
#include "code\modules\surgery\advanced\bioware\ligament_hook.dm"
#include "code\modules\surgery\advanced\bioware\ligament_reinforcement.dm"
+#include "code\modules\surgery\advanced\bioware\muscled_veins.dm"
#include "code\modules\surgery\advanced\bioware\nerve_grounding.dm"
#include "code\modules\surgery\advanced\bioware\nerve_splicing.dm"
#include "code\modules\surgery\advanced\bioware\vein_threading.dm"
@@ -2873,7 +2932,18 @@
#include "code\modules\vending\toys.dm"
#include "code\modules\vending\wardrobes.dm"
#include "code\modules\vending\youtool.dm"
-#include "code\modules\VR\vr_human.dm"
+#include "code\modules\vore\hook-defs.dm"
+#include "code\modules\vore\persistence.dm"
+#include "code\modules\vore\trycatch.dm"
+#include "code\modules\vore\eating\belly_dat_vr.dm"
+#include "code\modules\vore\eating\belly_obj.dm"
+#include "code\modules\vore\eating\bellymodes.dm"
+#include "code\modules\vore\eating\digest_act.dm"
+#include "code\modules\vore\eating\living.dm"
+#include "code\modules\vore\eating\vore.dm"
+#include "code\modules\vore\eating\voreitems.dm"
+#include "code\modules\vore\eating\vorepanel.dm"
+#include "code\modules\VR\vr_mob.dm"
#include "code\modules\VR\vr_sleeper.dm"
#include "code\modules\zombie\items.dm"
#include "code\modules\zombie\organs.dm"
@@ -2895,7 +2965,6 @@
#include "modular_citadel\code\controllers\subsystem\job.dm"
#include "modular_citadel\code\controllers\subsystem\shuttle.dm"
#include "modular_citadel\code\datums\components\material_container.dm"
-#include "modular_citadel\code\datums\components\phantomthief.dm"
#include "modular_citadel\code\datums\components\souldeath.dm"
#include "modular_citadel\code\datums\mood_events\chem_events.dm"
#include "modular_citadel\code\datums\mood_events\generic_negative_events.dm"
@@ -2905,7 +2974,6 @@
#include "modular_citadel\code\datums\status_effects\chems.dm"
#include "modular_citadel\code\datums\status_effects\debuffs.dm"
#include "modular_citadel\code\datums\traits\negative.dm"
-#include "modular_citadel\code\datums\traits\neutral.dm"
#include "modular_citadel\code\datums\wires\airlock.dm"
#include "modular_citadel\code\datums\wires\autoylathe.dm"
#include "modular_citadel\code\game\area\cit_areas.dm"
@@ -2922,7 +2990,6 @@
#include "modular_citadel\code\game\gamemodes\gangs\implant_gang.dm"
#include "modular_citadel\code\game\gamemodes\miniantags\bot_swarm\swarmer_event.dm"
#include "modular_citadel\code\game\gamemodes\revolution\revolution.dm"
-#include "modular_citadel\code\game\machinery\cryopod.dm"
#include "modular_citadel\code\game\machinery\displaycases.dm"
#include "modular_citadel\code\game\machinery\firealarm.dm"
#include "modular_citadel\code\game\machinery\Sleeper.dm"
@@ -2933,7 +3000,6 @@
#include "modular_citadel\code\game\machinery\doors\airlock.dm"
#include "modular_citadel\code\game\machinery\doors\airlock_types.dm"
#include "modular_citadel\code\game\objects\cit_screenshake.dm"
-#include "modular_citadel\code\game\objects\ids.dm"
#include "modular_citadel\code\game\objects\items.dm"
#include "modular_citadel\code\game\objects\tools.dm"
#include "modular_citadel\code\game\objects\effects\spawner\spawners.dm"
@@ -2948,35 +3014,31 @@
#include "modular_citadel\code\game\objects\items\stunsword.dm"
#include "modular_citadel\code\game\objects\items\vending_items.dm"
#include "modular_citadel\code\game\objects\items\circuitboards\machine_circuitboards.dm"
-#include "modular_citadel\code\game\objects\items\devices\aicard.dm"
#include "modular_citadel\code\game\objects\items\devices\radio\encryptionkey.dm"
#include "modular_citadel\code\game\objects\items\devices\radio\headset.dm"
#include "modular_citadel\code\game\objects\items\devices\radio\shockcollar.dm"
-#include "modular_citadel\code\game\objects\items\melee\eutactic_blades.dm"
#include "modular_citadel\code\game\objects\items\storage\firstaid.dm"
#include "modular_citadel\code\game\objects\structures\tables_racks.dm"
#include "modular_citadel\code\game\objects\structures\beds_chairs\chair.dm"
#include "modular_citadel\code\game\objects\structures\crates_lockers\closets\fitness.dm"
#include "modular_citadel\code\game\objects\structures\crates_lockers\closets\wardrobe.dm"
#include "modular_citadel\code\game\objects\structures\crates_lockers\closets\secure\citadel_lockers.dm"
-#include "modular_citadel\code\game\turfs\cit_turfs.dm"
#include "modular_citadel\code\modules\admin\admin.dm"
#include "modular_citadel\code\modules\admin\chat_commands.dm"
#include "modular_citadel\code\modules\admin\holder2.dm"
#include "modular_citadel\code\modules\admin\secrets.dm"
#include "modular_citadel\code\modules\admin\topic.dm"
#include "modular_citadel\code\modules\arousal\arousal.dm"
+#include "modular_citadel\code\modules\arousal\genitals.dm"
+#include "modular_citadel\code\modules\arousal\genitals_sprite_accessories.dm"
#include "modular_citadel\code\modules\arousal\organs\breasts.dm"
#include "modular_citadel\code\modules\arousal\organs\eggsack.dm"
-#include "modular_citadel\code\modules\arousal\organs\genitals.dm"
-#include "modular_citadel\code\modules\arousal\organs\genitals_sprite_accessories.dm"
#include "modular_citadel\code\modules\arousal\organs\ovipositor.dm"
#include "modular_citadel\code\modules\arousal\organs\penis.dm"
#include "modular_citadel\code\modules\arousal\organs\testicles.dm"
#include "modular_citadel\code\modules\arousal\organs\vagina.dm"
#include "modular_citadel\code\modules\arousal\organs\womb.dm"
#include "modular_citadel\code\modules\arousal\toys\dildos.dm"
-#include "modular_citadel\code\modules\awaymissions\citadel_ghostrole_spawners.dm"
#include "modular_citadel\code\modules\cargo\console.dm"
#include "modular_citadel\code\modules\client\client_defines.dm"
#include "modular_citadel\code\modules\client\client_procs.dm"
@@ -3003,7 +3065,6 @@
#include "modular_citadel\code\modules\clothing\neck.dm"
#include "modular_citadel\code\modules\clothing\glasses\phantomthief.dm"
#include "modular_citadel\code\modules\clothing\head\head.dm"
-#include "modular_citadel\code\modules\clothing\spacesuits\cydonian_armor.dm"
#include "modular_citadel\code\modules\clothing\spacesuits\flightsuit.dm"
#include "modular_citadel\code\modules\clothing\suits\polychromic_cloaks.dm"
#include "modular_citadel\code\modules\clothing\suits\suits.dm"
@@ -3014,17 +3075,8 @@
#include "modular_citadel\code\modules\custom_loadout\custom_items.dm"
#include "modular_citadel\code\modules\custom_loadout\load_to_mob.dm"
#include "modular_citadel\code\modules\custom_loadout\read_from_file.dm"
-#include "modular_citadel\code\modules\events\blob.dm"
-#include "modular_citadel\code\modules\events\wizard\magicarp.dm"
#include "modular_citadel\code\modules\food_and_drinks\snacks\meat.dm"
#include "modular_citadel\code\modules\integrated_electronics\subtypes\manipulation.dm"
-#include "modular_citadel\code\modules\jobs\dresscode_values.dm"
-#include "modular_citadel\code\modules\jobs\job_types\captain.dm"
-#include "modular_citadel\code\modules\jobs\job_types\cargo_service.dm"
-#include "modular_citadel\code\modules\jobs\job_types\engineering.dm"
-#include "modular_citadel\code\modules\jobs\job_types\medical.dm"
-#include "modular_citadel\code\modules\jobs\job_types\science.dm"
-#include "modular_citadel\code\modules\jobs\job_types\security.dm"
#include "modular_citadel\code\modules\keybindings\bindings_carbon.dm"
#include "modular_citadel\code\modules\keybindings\bindings_human.dm"
#include "modular_citadel\code\modules\keybindings\bindings_robot.dm"
@@ -3047,14 +3099,10 @@
#include "modular_citadel\code\modules\mob\living\carbon\human\human.dm"
#include "modular_citadel\code\modules\mob\living\carbon\human\human_defense.dm"
#include "modular_citadel\code\modules\mob\living\carbon\human\human_movement.dm"
-#include "modular_citadel\code\modules\mob\living\silicon\ai\vox_sounds.dm"
#include "modular_citadel\code\modules\mob\living\silicon\robot\dogborg_equipment.dm"
#include "modular_citadel\code\modules\mob\living\silicon\robot\robot.dm"
#include "modular_citadel\code\modules\mob\living\silicon\robot\robot_modules.dm"
#include "modular_citadel\code\modules\mob\living\silicon\robot\robot_movement.dm"
-#include "modular_citadel\code\modules\mob\living\simple_animal\banana_spider.dm"
-#include "modular_citadel\code\modules\mob\living\simple_animal\kiwi.dm"
-#include "modular_citadel\code\modules\mob\living\simple_animal\simplemob_vore_values.dm"
#include "modular_citadel\code\modules\power\lighting.dm"
#include "modular_citadel\code\modules\projectiles\gun.dm"
#include "modular_citadel\code\modules\projectiles\ammunition\caseless.dm"
@@ -3073,7 +3121,6 @@
#include "modular_citadel\code\modules\projectiles\guns\ballistic\spinfusor.dm"
#include "modular_citadel\code\modules\projectiles\guns\energy\energy_gun.dm"
#include "modular_citadel\code\modules\projectiles\guns\energy\laser.dm"
-#include "modular_citadel\code\modules\projectiles\projectile\energy.dm"
#include "modular_citadel\code\modules\projectiles\projectiles\reusable.dm"
#include "modular_citadel\code\modules\reagents\chemistry\reagents\astrogen.dm"
#include "modular_citadel\code\modules\reagents\chemistry\reagents\eigentstasium.dm"
@@ -3086,29 +3133,8 @@
#include "modular_citadel\code\modules\reagents\chemistry\recipes\fermi.dm"
#include "modular_citadel\code\modules\reagents\objects\clothes.dm"
#include "modular_citadel\code\modules\reagents\objects\items.dm"
-#include "modular_citadel\code\modules\reagents\reagent container\cit_kegs.dm"
-#include "modular_citadel\code\modules\reagents\reagent container\hypospraymkii.dm"
-#include "modular_citadel\code\modules\reagents\reagent container\hypovial.dm"
#include "modular_citadel\code\modules\reagents\reagents\cit_reagents.dm"
#include "modular_citadel\code\modules\recycling\disposal\bin.dm"
#include "modular_citadel\code\modules\research\designs\autoylathe_designs.dm"
-#include "modular_citadel\code\modules\research\designs\machine_designs.dm"
-#include "modular_citadel\code\modules\research\designs\weapon_designs.dm"
-#include "modular_citadel\code\modules\research\designs\xenobio_designs.dm"
-#include "modular_citadel\code\modules\research\designs\weapon_designs\weapon_designs.dm"
-#include "modular_citadel\code\modules\research\techweb\_techweb.dm"
-#include "modular_citadel\code\modules\research\xenobiology\xenobio_camera.dm"
-#include "modular_citadel\code\modules\vehicles\secway.dm"
-#include "modular_citadel\code\modules\vore\hook-defs_vr.dm"
-#include "modular_citadel\code\modules\vore\persistence.dm"
-#include "modular_citadel\code\modules\vore\trycatch_vr.dm"
-#include "modular_citadel\code\modules\vore\eating\belly_dat_vr.dm"
-#include "modular_citadel\code\modules\vore\eating\belly_obj_vr.dm"
-#include "modular_citadel\code\modules\vore\eating\bellymodes_vr.dm"
-#include "modular_citadel\code\modules\vore\eating\digest_act_vr.dm"
-#include "modular_citadel\code\modules\vore\eating\living_vr.dm"
-#include "modular_citadel\code\modules\vore\eating\vore_vr.dm"
-#include "modular_citadel\code\modules\vore\eating\voreitems.dm"
-#include "modular_citadel\code\modules\vore\eating\vorepanel_vr.dm"
#include "modular_citadel\interface\skin.dmf"
// END_INCLUDE
diff --git a/tgui/assets/tgui.css b/tgui/assets/tgui.css
index c73fc2adfa..256b53c106 100644
--- a/tgui/assets/tgui.css
+++ b/tgui/assets/tgui.css
@@ -1 +1 @@
-@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCA0MjUgMjAwIiBvcGFjaXR5PSIuMzMiPgogIDxwYXRoIGQ9Im0gMTc4LjAwMzk5LDAuMDM4NjkgLTcxLjIwMzkzLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM0LDYuMDI1NTUgbCAwLDE4Ny44NzE0NyBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgNi43NjEzNCw2LjAyNTU0IGwgNTMuMTA3MiwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTAxLjU0NDAxOCA3Mi4yMTYyOCwxMDQuNjk5Mzk4IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA1Ljc2MDE1LDIuODcwMTYgbCA3My41NTQ4NywwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM1LC02LjAyNTU0IGwgMCwtMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzNSwtNi4wMjU1NSBsIC01NC43MTY0NCwwIGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNi43NjEzMyw2LjAyNTU1IGwgMCwxMDIuNjE5MzUgTCAxODMuNzY0MTMsMi45MDg4NiBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTUuNzYwMTQsLTIuODcwMTcgeiIgLz4KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPgogIDxwYXRoIGQ9Im0gNDIwLjE1NTM1LDE3Ny44OTExOSBhIDEzLjQxMjAzOCwxMi41MDE4NDIgMCAwIDEgLTguNjMyOTUsMjIuMDY5NTEgbCAtNjYuMTE4MzIsMCBhIDUuMzY0ODE1Miw1LjAwMDczNyAwIDAgMSAtNS4zNjQ4MiwtNS4wMDA3NCBsIDAsLTc5Ljg3OTMxIHoiIC8+Cjwvc3ZnPgo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4KPCEtLSBodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9saWNlbnNlcy9ieS1zYS80LjAvIC0tPgo=") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjAiIHZpZXdCb3g9IjAgMCAyMDAgMjg5Ljc0MiIgb3BhY2l0eT0iLjMzIj4KICA8cGF0aCBkPSJtIDkzLjUzNzY3NywwIGMgLTE4LjExMzEyNSwwIC0zNC4yMjAxMzMsMy4xMTE2NCAtNDguMzIzNDg0LDkuMzM0MzcgLTEzLjk2NTA5Miw2LjIyMTY3IC0yNC42MTI0NDIsMTUuMDcxMTQgLTMxLjk0MDY1MSwyNi41NDcxIC03LjE4OTkzOTgsMTEuMzM3ODkgLTEwLjMwMTIyNjYsMjQuNzQ5MTEgLTEwLjMwMTIyNjYsNDAuMjM0NzggMCwxMC42NDY2MiAyLjcyNTAwMjYsMjAuNDY0NjUgOC4xNzUxMTE2LDI5LjQ1MjU4IDUuNjE1Mjc3LDguOTg2ODYgMTQuMDM4Mjc3LDE3LjM1MjA0IDI1LjI2ODgyMSwyNS4wOTQzNiAxMS4yMzA1NDQsNy42MDUzMSAyNi41MDc0MjEsMTUuNDE4MzUgNDUuODMwNTE0LDIzLjQzNzgyIDE5Ljk4Mzc0OCw4LjI5NTU3IDM0Ljg0ODg0OCwxNS41NTQ3MSA0NC41OTI5OTgsMjEuNzc2MzggOS43NDQxNCw2LjIyMjczIDE2Ljc2MTcsMTIuODU4NSAyMS4wNTU3MiwxOS45MDk1MSA0LjI5NDA0LDcuMDUyMDggNi40NDE5MywxNS43NjQwOCA2LjQ0MTkzLDI2LjEzNDU5IDAsMTYuMTc3MDIgLTUuMjAxOTYsMjguNDgyMjIgLTE1LjYwNjczLDM2LjkxNjgyIC0xMC4yMzk2LDguNDM0NyAtMjUuMDIyMDMsMTIuNjUyMyAtNDQuMzQ1MTY5LDEyLjY1MjMgLTE0LjAzODE3MSwwIC0yNS41MTUyNDcsLTEuNjU5NCAtMzQuNDMzNjE4LC00Ljk3NzcgLTguOTE4MzcsLTMuNDU2NiAtMTYuMTg1NTcyLC04LjcxMTMgLTIxLjgwMDgzOSwtMTUuNzYzMyAtNS42MTUyNzcsLTcuMDUyMSAtMTAuMDc0Nzk1LC0xNi42NjA4OCAtMTMuMzc3ODk5LC0yOC44MjgxMiBsIC0yNC43NzMxNjI2MjkzOTQ1LDAgMCw1Ni44MjYzMiBDIDMzLjg1Njc2OSwyODYuMDc2MDEgNjMuNzQ5MDQsMjg5Ljc0MjAxIDg5LjY3ODM4MywyODkuNzQyMDEgYyAxNi4wMjAwMjcsMCAzMC43MTk3ODcsLTEuMzgyNyA0NC4wOTczMzcsLTQuMTQ3OSAxMy41NDI3MiwtMi45MDQzIDI1LjEwNDEsLTcuNDY3NiAzNC42ODMwOSwtMTMuNjg5MyA5Ljc0NDEzLC02LjM1OTcgMTcuMzQwNDIsLTE0LjUxOTUgMjIuNzkwNTIsLTI0LjQ3NDggNS40NTAxLC0xMC4wOTMzMiA4LjE3NTExLC0yMi4zOTk1OSA4LjE3NTExLC0zNi45MTY4MiAwLC0xMi45OTc2NCAtMy4zMDIxLC0yNC4zMzUzOSAtOS45MDgyOSwtMzQuMDE0NiAtNi40NDEwNSwtOS44MTcyNSAtMTUuNTI1NDUsLTE4LjUyNzA3IC0yNy4yNTE0NiwtMjYuMTMxMzMgLTExLjU2MDg1LC03LjYwNDI3IC0yNy45MTA4MywtMTUuODMxNDIgLTQ5LjA1MDY2LC0yNC42ODAyMiAtMTcuNTA2NDQsLTcuMTkwMTIgLTMwLjcxOTY2OCwtMTMuNjg5NDggLTM5LjYzODAzOCwtMTkuNDk3MDEgLTguOTE4MzcxLC01LjgwNzUyIC0xOC42MDc0NzQsLTEyLjQzNDA5IC0yNC4wOTY1MjQsLTE4Ljg3NDE3IC01LjQyNjA0MywtNi4zNjYxNiAtOS42NTg4MjYsLTE1LjA3MDAzIC05LjY1ODgyNiwtMjQuODg3MjkgMCwtOS4yNjQwMSAyLjA3NTQxNCwtMTcuMjEzNDUgNi4yMjM0NTQsLTIzLjg1MDMzIDExLjA5ODI5OCwtMTQuMzk3NDggNDEuMjg2NjM4LC0xLjc5NTA3IDQ1LjA3NTYwOSwyNC4zNDc2MiA0LjgzOTM5Miw2Ljc3NDkxIDguODQ5MzUsMTYuMjQ3MjkgMTIuMDI5NTE1LDI4LjQxNTYgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTQuNDc4MjUsLTUuOTI0NDggLTkuOTU0ODgsLTEwLjYzMjIyIC0xNS45MDgzNywtMTQuMzc0MTEgMS42NDA1NSwwLjQ3OTA1IDMuMTkwMzksMS4wMjM3NiA0LjYzODY1LDEuNjQwMjQgNi40OTg2MSwyLjYyNjA3IDEyLjE2NzkzLDcuMzI3NDcgMTcuMDA3MywxNC4xMDM0NSA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNSwxNi4yNDU2NyAxMi4wMjk1MiwyOC40MTM5NyAwLDAgOC40ODEyOCwtMC4xMjg5NCA4LjQ4OTc4LC0wLjAwMiAwLjQxNzc2LDYuNDE0OTQgLTEuNzUzMzksOS40NTI4NiAtNC4xMjM0MiwxMi41NjEwNCAtMi40MTc0LDMuMTY5NzggLTUuMTQ0ODYsNi43ODk3MyAtNC4wMDI3OCwxMy4wMDI5IDEuNTA3ODYsOC4yMDMxOCAxMC4xODM1NCwxMC41OTY0MiAxNC42MjE5NCw5LjMxMTU0IC0zLjMxODQyLC0wLjQ5OTExIC01LjMxODU1LC0xLjc0OTQ4IC01LjMxODU1LC0xLjc0OTQ4IDAsMCAxLjg3NjQ2LDAuOTk4NjggNS42NTExNywtMS4zNTk4MSAtMy4yNzY5NSwwLjk1NTcxIC0xMC43MDUyOSwtMC43OTczOCAtMTEuODAxMjUsLTYuNzYzMTMgLTAuOTU3NTIsLTUuMjA4NjEgMC45NDY1NCwtNy4yOTUxNCAzLjQwMTEzLC0xMC41MTQ4MiAyLjQ1NDYyLC0zLjIxOTY4IDUuMjg0MjYsLTYuOTU4MzEgNC42ODQzLC0xNC40ODgyNCBsIDAuMDAzLDAuMDAyIDguOTI2NzYsMCAwLC01NS45OTk2NyBjIC0xNS4wNzEyNSwtMy44NzE2OCAtMjcuNjUzMTQsLTYuMzYwNDIgLTM3Ljc0NjcxLC03LjQ2NTg2IC05Ljk1NTMxLC0xLjEwNzU1IC0yMC4xODgyMywtMS42NTk4MSAtMzAuNjk2NjEzLC0xLjY1OTgxIHogbSA3MC4zMjE2MDMsMTcuMzA4OTMgMC4yMzgwNSw0MC4zMDQ5IGMgMS4zMTgwOCwxLjIyNjY2IDIuNDM5NjUsMi4yNzgxNSAzLjM0MDgxLDMuMTA2MDIgNC44MzkzOSw2Ljc3NDkxIDguODQ5MzQsMTYuMjQ1NjYgMTIuMDI5NTEsMjguNDEzOTcgbCAyMC41MzIzNCwwIDAsLTU1Ljk5OTY3IGMgLTYuNjc3MzEsLTQuNTkzODEgLTE5LjgzNjQzLC0xMC40NzMwOSAtMzYuMTQwNzEsLTE1LjgyNTIyIHogbSAtMjguMTIwNDksNS42MDU1MSA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM3LC02LjQ2Njk3IC0xMy44NDY3OCwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NzA1LDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiBtIDE1LjIyMTk1LDI0LjAwODQ4IDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzgsLTYuNDY2OTcgLTEzLjg0Njc5LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDQsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gLTk5LjExMzg0LDIuMjA3NjQgOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzODIsLTYuNDY2OTcgLTEzLjg0Njc4MiwtOS43MTcyNiAtOC41NjQ3OSwtMTcuNzE2NTUgeiBtIDIyLjc5NTQyLDAgYyAyLjc3MTUsNy45OTkyOSAxLjc4NzQxLDExLjI0OTU4IC00LjQ5MzU0LDE3LjcxNjU1IGwgNC40OTM1NCwtMTcuNzE2NTUgeiIgLz4KPC9zdmc+CjwhLS0gVGhpcyB3b3JrIGlzIGxpY2Vuc2VkIHVuZGVyIGEgQ3JlYXRpdmUgQ29tbW9ucyBBdHRyaWJ1dGlvbi1TaGFyZUFsaWtlIDQuMCBJbnRlcm5hdGlvbmFsIExpY2Vuc2UuIC0tPgo8IS0tIGh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL2xpY2Vuc2VzL2J5LXNhLzQuMC8gLS0+Cg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"}
\ No newline at end of file
+@charset "utf-8";body,html{box-sizing:border-box;height:100%;margin:0}html{overflow:hidden;cursor:default}body{overflow:auto;font-family:Verdana,Geneva,sans-serif;font-size:12px;color:#fff;background-color:#2a2a2a;background-image:linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}*,:after,:before{box-sizing:inherit}h1,h2,h3,h4{display:inline-block;margin:0;padding:6px 0}h1{font-size:18px}h2{font-size:16px}h3{font-size:14px}h4{font-size:12px}body.clockwork{background:linear-gradient(180deg,#b18b25 0,#5f380e);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ffb18b25",endColorstr="#ff5f380e",GradientType=0)}body.clockwork .normal{color:#b18b25}body.clockwork .good{color:#cfba47}body.clockwork .average{color:#896b19}body.clockwork .bad{color:#5f380e}body.clockwork .highlight{color:#b18b25}body.clockwork main{display:block;margin-top:32px;padding:2px 6px 0}body.clockwork hr{height:2px;background-color:#b18b25;border:none}body.clockwork .hidden{display:none}body.clockwork .bar .barText,body.clockwork span.button{color:#b18b25;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.clockwork .bold{font-weight:700}body.clockwork .italic{font-style:italic}body.clockwork [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.clockwork div[data-tooltip],body.clockwork span[data-tooltip]{position:relative}body.clockwork div[data-tooltip]:after,body.clockwork span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #170800;background-color:#2d1400}body.clockwork div[data-tooltip]:hover:after,body.clockwork span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.clockwork div[data-tooltip].tooltip-top:after,body.clockwork span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-top:hover:after,body.clockwork span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:after,body.clockwork span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.clockwork div[data-tooltip].tooltip-bottom:hover:after,body.clockwork span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.clockwork div[data-tooltip].tooltip-left:after,body.clockwork span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-left:hover:after,body.clockwork span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:after,body.clockwork span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.clockwork div[data-tooltip].tooltip-right:hover:after,body.clockwork span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.clockwork .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #170800;background:#2d1400}body.clockwork .bar .barText{position:absolute;top:0;right:3px}body.clockwork .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#b18b25}body.clockwork .bar .barFill.good{background-color:#cfba47}body.clockwork .bar .barFill.average{background-color:#896b19}body.clockwork .bar .barFill.bad{background-color:#5f380e}body.clockwork span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #170800}body.clockwork span.button .fa{padding-right:2px}body.clockwork span.button.normal{transition:background-color .5s;background-color:#5f380e}body.clockwork span.button.normal.active:focus,body.clockwork span.button.normal.active:hover{transition:background-color .25s;background-color:#704211;outline:0}body.clockwork span.button.disabled{transition:background-color .5s;background-color:#2d1400}body.clockwork span.button.disabled.active:focus,body.clockwork span.button.disabled.active:hover{transition:background-color .25s;background-color:#441e00;outline:0}body.clockwork span.button.selected{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.selected.active:focus,body.clockwork span.button.selected.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.toggle{transition:background-color .5s;background-color:#cfba47}body.clockwork span.button.toggle.active:focus,body.clockwork span.button.toggle.active:hover{transition:background-color .25s;background-color:#d1bd50;outline:0}body.clockwork span.button.caution{transition:background-color .5s;background-color:#be6209}body.clockwork span.button.caution.active:focus,body.clockwork span.button.caution.active:hover{transition:background-color .25s;background-color:#cd6a0a;outline:0}body.clockwork span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.clockwork span.button.danger.active:focus,body.clockwork span.button.danger.active:hover{transition:background-color .25s;background-color:#abaf00;outline:0}body.clockwork span.button.gridable{width:125px;margin:2px 0}body.clockwork span.button.gridable.center{text-align:center;width:75px}body.clockwork span.button+span:not(.button),body.clockwork span:not(.button)+span.button{margin-left:5px}body.clockwork div.display{width:100%;padding:4px;margin:6px 0;background-color:#2d1400;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#e62d1400,endColorStr=#e62d1400);background-color:rgba(45,20,0,.9);box-shadow:inset 0 0 5px rgba(0,0,0,.3)}body.clockwork div.display.tabular{padding:0;margin:0}body.clockwork div.display header,body.clockwork div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#cfba47;border-bottom:2px solid #b18b25}body.clockwork div.display header .buttonRight,body.clockwork div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.clockwork div.display article,body.clockwork div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.clockwork input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#b18b25;background-color:#cfba47;border:1px solid #272727}body.clockwork input.number{width:35px}body.clockwork input:-ms-input-placeholder{color:#999}body.clockwork input::placeholder{color:#999}body.clockwork input::-ms-clear{display:none}body.clockwork svg.linegraph{overflow:hidden}body.clockwork div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#2d1400;font-weight:700;font-style:italic;background-color:#000;background-image:repeating-linear-gradient(-45deg,#000,#000 10px,#170800 0,#170800 20px)}body.clockwork div.notice .label{color:#2d1400}body.clockwork div.notice .content:only-of-type{padding:0}body.clockwork div.notice hr{background-color:#896b19}body.clockwork div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #5f380e;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.clockwork section .cell,body.clockwork section .content,body.clockwork section .label,body.clockwork section .line,body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.clockwork section{display:table-row;width:100%}body.clockwork section:not(:first-child){padding-top:4px}body.clockwork section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.clockwork section .label{width:1%;padding-right:32px;white-space:nowrap;color:#b18b25}body.clockwork section .content:not(:last-child){padding-right:16px}body.clockwork section .line{width:100%}body.clockwork section .cell:not(:first-child){text-align:center;padding-top:0}body.clockwork section .cell span.button{width:75px}body.clockwork section:not(:last-child){padding-right:4px}body.clockwork div.subdisplay{width:100%;margin:0}body.clockwork header.titlebar .close,body.clockwork header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#cfba47}body.clockwork header.titlebar .close:hover,body.clockwork header.titlebar .minimize:hover{color:#d1bd50}body.clockwork header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#5f380e;border-bottom:1px solid #170800;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.clockwork header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.clockwork header.titlebar .title{position:absolute;top:6px;left:46px;color:#cfba47;font-size:16px;white-space:nowrap}body.clockwork header.titlebar .minimize{position:absolute;top:6px;right:46px}body.clockwork header.titlebar .close{position:absolute;top:4px;right:12px}body.nanotrasen{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgNDI1IDIwMCIgb3BhY2l0eT0iLjMzIj4NCiAgPHBhdGggZD0ibSAxNzguMDAzOTksMC4wMzg2OSAtNzEuMjAzOTMsMCBhIDYuNzYxMzQyMiw2LjAyNTU0OTUgMCAwIDAgLTYuNzYxMzQsNi4wMjU1NSBsIDAsMTg3Ljg3MTQ3IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCA2Ljc2MTM0LDYuMDI1NTQgbCA1My4xMDcyLDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xMDEuNTQ0MDE4IDcyLjIxNjI4LDEwNC42OTkzOTggYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDUuNzYwMTUsMi44NzAxNiBsIDczLjU1NDg3LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIDYuNzYxMzUsLTYuMDI1NTQgbCAwLC0xODcuODcxNDcgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTM1LC02LjAyNTU1IGwgLTU0LjcxNjQ0LDAgYSA2Ljc2MTM0MjIsNi4wMjU1NDk1IDAgMCAwIC02Ljc2MTMzLDYuMDI1NTUgbCAwLDEwMi42MTkzNSBMIDE4My43NjQxMywyLjkwODg2IGEgNi43NjEzNDIyLDYuMDI1NTQ5NSAwIDAgMCAtNS43NjAxNCwtMi44NzAxNyB6IiAvPg0KICA8cGF0aCBkPSJNIDQuODQ0NjMzMywyMi4xMDg3NSBBIDEzLjQxMjAzOSwxMi41MDE4NDIgMCAwIDEgMTMuNDc3NTg4LDAuMDM5MjQgbCA2Ni4xMTgzMTUsMCBhIDUuMzY0ODE1OCw1LjAwMDczNyAwIDAgMSA1LjM2NDgyMyw1LjAwMDczIGwgMCw3OS44NzkzMSB6IiAvPg0KICA8cGF0aCBkPSJtIDQyMC4xNTUzNSwxNzcuODkxMTkgYSAxMy40MTIwMzgsMTIuNTAxODQyIDAgMCAxIC04LjYzMjk1LDIyLjA2OTUxIGwgLTY2LjExODMyLDAgYSA1LjM2NDgxNTIsNS4wMDA3MzcgMCAwIDEgLTUuMzY0ODIsLTUuMDAwNzQgbCAwLC03OS44NzkzMSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#2a2a2a 0,#202020);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff2a2a2a",endColorstr="#ff202020",GradientType=0)}body.nanotrasen .normal{color:#40628a}body.nanotrasen .good{color:#537d29}body.nanotrasen .average{color:#be6209}body.nanotrasen .bad{color:#b00e0e}body.nanotrasen .highlight{color:#8ba5c4}body.nanotrasen main{display:block;margin-top:32px;padding:2px 6px 0}body.nanotrasen hr{height:2px;background-color:#40628a;border:none}body.nanotrasen .hidden{display:none}body.nanotrasen .bar .barText,body.nanotrasen span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.nanotrasen .bold{font-weight:700}body.nanotrasen .italic{font-style:italic}body.nanotrasen [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.nanotrasen div[data-tooltip],body.nanotrasen span[data-tooltip]{position:relative}body.nanotrasen div[data-tooltip]:after,body.nanotrasen span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.nanotrasen div[data-tooltip]:hover:after,body.nanotrasen span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.nanotrasen div[data-tooltip].tooltip-top:after,body.nanotrasen span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-top:hover:after,body.nanotrasen span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:after,body.nanotrasen span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.nanotrasen div[data-tooltip].tooltip-bottom:hover:after,body.nanotrasen span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.nanotrasen div[data-tooltip].tooltip-left:after,body.nanotrasen span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-left:hover:after,body.nanotrasen span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:after,body.nanotrasen span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.nanotrasen div[data-tooltip].tooltip-right:hover:after,body.nanotrasen span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.nanotrasen .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #40628a;background:#272727}body.nanotrasen .bar .barText{position:absolute;top:0;right:3px}body.nanotrasen .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#40628a}body.nanotrasen .bar .barFill.good{background-color:#537d29}body.nanotrasen .bar .barFill.average{background-color:#be6209}body.nanotrasen .bar .barFill.bad{background-color:#b00e0e}body.nanotrasen span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.nanotrasen span.button .fa{padding-right:2px}body.nanotrasen span.button.normal{transition:background-color .5s;background-color:#40628a}body.nanotrasen span.button.normal.active:focus,body.nanotrasen span.button.normal.active:hover{transition:background-color .25s;background-color:#4f78aa;outline:0}body.nanotrasen span.button.disabled{transition:background-color .5s;background-color:#999}body.nanotrasen span.button.disabled.active:focus,body.nanotrasen span.button.disabled.active:hover{transition:background-color .25s;background-color:#a8a8a8;outline:0}body.nanotrasen span.button.selected{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.selected.active:focus,body.nanotrasen span.button.selected.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.toggle{transition:background-color .5s;background-color:#2f943c}body.nanotrasen span.button.toggle.active:focus,body.nanotrasen span.button.toggle.active:hover{transition:background-color .25s;background-color:#3ab84b;outline:0}body.nanotrasen span.button.caution{transition:background-color .5s;background-color:#9a9d00}body.nanotrasen span.button.caution.active:focus,body.nanotrasen span.button.caution.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.nanotrasen span.button.danger{transition:background-color .5s;background-color:#9d0808}body.nanotrasen span.button.danger.active:focus,body.nanotrasen span.button.danger.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.nanotrasen span.button.gridable{width:125px;margin:2px 0}body.nanotrasen span.button.gridable.center{text-align:center;width:75px}body.nanotrasen span.button+span:not(.button),body.nanotrasen span:not(.button)+span.button{margin-left:5px}body.nanotrasen div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#54000000,endColorStr=#54000000);background-color:rgba(0,0,0,.33);box-shadow:inset 0 0 5px rgba(0,0,0,.5)}body.nanotrasen div.display.tabular{padding:0;margin:0}body.nanotrasen div.display header,body.nanotrasen div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #40628a}body.nanotrasen div.display header .buttonRight,body.nanotrasen div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.nanotrasen div.display article,body.nanotrasen div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.nanotrasen input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#000;background-color:#fff;border:1px solid #272727}body.nanotrasen input.number{width:35px}body.nanotrasen input:-ms-input-placeholder{color:#999}body.nanotrasen input::placeholder{color:#999}body.nanotrasen input::-ms-clear{display:none}body.nanotrasen svg.linegraph{overflow:hidden}body.nanotrasen div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#bb9b68;background-image:repeating-linear-gradient(-45deg,#bb9b68,#bb9b68 10px,#b1905d 0,#b1905d 20px)}body.nanotrasen div.notice .label{color:#000}body.nanotrasen div.notice .content:only-of-type{padding:0}body.nanotrasen div.notice hr{background-color:#272727}body.nanotrasen div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.nanotrasen section .cell,body.nanotrasen section .content,body.nanotrasen section .label,body.nanotrasen section .line,body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.nanotrasen section{display:table-row;width:100%}body.nanotrasen section:not(:first-child){padding-top:4px}body.nanotrasen section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.nanotrasen section .label{width:1%;padding-right:32px;white-space:nowrap;color:#8ba5c4}body.nanotrasen section .content:not(:last-child){padding-right:16px}body.nanotrasen section .line{width:100%}body.nanotrasen section .cell:not(:first-child){text-align:center;padding-top:0}body.nanotrasen section .cell span.button{width:75px}body.nanotrasen section:not(:last-child){padding-right:4px}body.nanotrasen div.subdisplay{width:100%;margin:0}body.nanotrasen header.titlebar .close,body.nanotrasen header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#8ba5c4}body.nanotrasen header.titlebar .close:hover,body.nanotrasen header.titlebar .minimize:hover{color:#9cb2cd}body.nanotrasen header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.nanotrasen header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.nanotrasen header.titlebar .title{position:absolute;top:6px;left:46px;color:#8ba5c4;font-size:16px;white-space:nowrap}body.nanotrasen header.titlebar .minimize{position:absolute;top:6px;right:46px}body.nanotrasen header.titlebar .close{position:absolute;top:4px;right:12px}body.syndicate{background:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+DQo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4wIiB2aWV3Qm94PSIwIDAgMjAwIDI4OS43NDIiIG9wYWNpdHk9Ii4zMyI+DQogIDxwYXRoIGQ9Im0gOTMuNTM3Njc3LDAgYyAtMTguMTEzMTI1LDAgLTM0LjIyMDEzMywzLjExMTY0IC00OC4zMjM0ODQsOS4zMzQzNyAtMTMuOTY1MDkyLDYuMjIxNjcgLTI0LjYxMjQ0MiwxNS4wNzExNCAtMzEuOTQwNjUxLDI2LjU0NzEgLTcuMTg5OTM5OCwxMS4zMzc4OSAtMTAuMzAxMjI2NiwyNC43NDkxMSAtMTAuMzAxMjI2Niw0MC4yMzQ3OCAwLDEwLjY0NjYyIDIuNzI1MDAyNiwyMC40NjQ2NSA4LjE3NTExMTYsMjkuNDUyNTggNS42MTUyNzcsOC45ODY4NiAxNC4wMzgyNzcsMTcuMzUyMDQgMjUuMjY4ODIxLDI1LjA5NDM2IDExLjIzMDU0NCw3LjYwNTMxIDI2LjUwNzQyMSwxNS40MTgzNSA0NS44MzA1MTQsMjMuNDM3ODIgMTkuOTgzNzQ4LDguMjk1NTcgMzQuODQ4ODQ4LDE1LjU1NDcxIDQ0LjU5Mjk5OCwyMS43NzYzOCA5Ljc0NDE0LDYuMjIyNzMgMTYuNzYxNywxMi44NTg1IDIxLjA1NTcyLDE5LjkwOTUxIDQuMjk0MDQsNy4wNTIwOCA2LjQ0MTkzLDE1Ljc2NDA4IDYuNDQxOTMsMjYuMTM0NTkgMCwxNi4xNzcwMiAtNS4yMDE5NiwyOC40ODIyMiAtMTUuNjA2NzMsMzYuOTE2ODIgLTEwLjIzOTYsOC40MzQ3IC0yNS4wMjIwMywxMi42NTIzIC00NC4zNDUxNjksMTIuNjUyMyAtMTQuMDM4MTcxLDAgLTI1LjUxNTI0NywtMS42NTk0IC0zNC40MzM2MTgsLTQuOTc3NyAtOC45MTgzNywtMy40NTY2IC0xNi4xODU1NzIsLTguNzExMyAtMjEuODAwODM5LC0xNS43NjMzIC01LjYxNTI3NywtNy4wNTIxIC0xMC4wNzQ3OTUsLTE2LjY2MDg4IC0xMy4zNzc4OTksLTI4LjgyODEyIGwgLTI0Ljc3MzE2MjYyOTM5NDUsMCAwLDU2LjgyNjMyIEMgMzMuODU2NzY5LDI4Ni4wNzYwMSA2My43NDkwNCwyODkuNzQyMDEgODkuNjc4MzgzLDI4OS43NDIwMSBjIDE2LjAyMDAyNywwIDMwLjcxOTc4NywtMS4zODI3IDQ0LjA5NzMzNywtNC4xNDc5IDEzLjU0MjcyLC0yLjkwNDMgMjUuMTA0MSwtNy40Njc2IDM0LjY4MzA5LC0xMy42ODkzIDkuNzQ0MTMsLTYuMzU5NyAxNy4zNDA0MiwtMTQuNTE5NSAyMi43OTA1MiwtMjQuNDc0OCA1LjQ1MDEsLTEwLjA5MzMyIDguMTc1MTEsLTIyLjM5OTU5IDguMTc1MTEsLTM2LjkxNjgyIDAsLTEyLjk5NzY0IC0zLjMwMjEsLTI0LjMzNTM5IC05LjkwODI5LC0zNC4wMTQ2IC02LjQ0MTA1LC05LjgxNzI1IC0xNS41MjU0NSwtMTguNTI3MDcgLTI3LjI1MTQ2LC0yNi4xMzEzMyAtMTEuNTYwODUsLTcuNjA0MjcgLTI3LjkxMDgzLC0xNS44MzE0MiAtNDkuMDUwNjYsLTI0LjY4MDIyIC0xNy41MDY0NCwtNy4xOTAxMiAtMzAuNzE5NjY4LC0xMy42ODk0OCAtMzkuNjM4MDM4LC0xOS40OTcwMSAtOC45MTgzNzEsLTUuODA3NTIgLTE4LjYwNzQ3NCwtMTIuNDM0MDkgLTI0LjA5NjUyNCwtMTguODc0MTcgLTUuNDI2MDQzLC02LjM2NjE2IC05LjY1ODgyNiwtMTUuMDcwMDMgLTkuNjU4ODI2LC0yNC44ODcyOSAwLC05LjI2NDAxIDIuMDc1NDE0LC0xNy4yMTM0NSA2LjIyMzQ1NCwtMjMuODUwMzMgMTEuMDk4Mjk4LC0xNC4zOTc0OCA0MS4yODY2MzgsLTEuNzk1MDcgNDUuMDc1NjA5LDI0LjM0NzYyIDQuODM5MzkyLDYuNzc0OTEgOC44NDkzNSwxNi4yNDcyOSAxMi4wMjk1MTUsMjguNDE1NiBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNC40NzgyNSwtNS45MjQ0OCAtOS45NTQ4OCwtMTAuNjMyMjIgLTE1LjkwODM3LC0xNC4zNzQxMSAxLjY0MDU1LDAuNDc5MDUgMy4xOTAzOSwxLjAyMzc2IDQuNjM4NjUsMS42NDAyNCA2LjQ5ODYxLDIuNjI2MDcgMTIuMTY3OTMsNy4zMjc0NyAxNy4wMDczLDE0LjEwMzQ1IDQuODM5MzksNi43NzQ5MSA4Ljg0OTM1LDE2LjI0NTY3IDEyLjAyOTUyLDI4LjQxMzk3IDAsMCA4LjQ4MTI4LC0wLjEyODk0IDguNDg5NzgsLTAuMDAyIDAuNDE3NzYsNi40MTQ5NCAtMS43NTMzOSw5LjQ1Mjg2IC00LjEyMzQyLDEyLjU2MTA0IC0yLjQxNzQsMy4xNjk3OCAtNS4xNDQ4Niw2Ljc4OTczIC00LjAwMjc4LDEzLjAwMjkgMS41MDc4Niw4LjIwMzE4IDEwLjE4MzU0LDEwLjU5NjQyIDE0LjYyMTk0LDkuMzExNTQgLTMuMzE4NDIsLTAuNDk5MTEgLTUuMzE4NTUsLTEuNzQ5NDggLTUuMzE4NTUsLTEuNzQ5NDggMCwwIDEuODc2NDYsMC45OTg2OCA1LjY1MTE3LC0xLjM1OTgxIC0zLjI3Njk1LDAuOTU1NzEgLTEwLjcwNTI5LC0wLjc5NzM4IC0xMS44MDEyNSwtNi43NjMxMyAtMC45NTc1MiwtNS4yMDg2MSAwLjk0NjU0LC03LjI5NTE0IDMuNDAxMTMsLTEwLjUxNDgyIDIuNDU0NjIsLTMuMjE5NjggNS4yODQyNiwtNi45NTgzMSA0LjY4NDMsLTE0LjQ4ODI0IGwgMC4wMDMsMC4wMDIgOC45MjY3NiwwIDAsLTU1Ljk5OTY3IGMgLTE1LjA3MTI1LC0zLjg3MTY4IC0yNy42NTMxNCwtNi4zNjA0MiAtMzcuNzQ2NzEsLTcuNDY1ODYgLTkuOTU1MzEsLTEuMTA3NTUgLTIwLjE4ODIzLC0xLjY1OTgxIC0zMC42OTY2MTMsLTEuNjU5ODEgeiBtIDcwLjMyMTYwMywxNy4zMDg5MyAwLjIzODA1LDQwLjMwNDkgYyAxLjMxODA4LDEuMjI2NjYgMi40Mzk2NSwyLjI3ODE1IDMuMzQwODEsMy4xMDYwMiA0LjgzOTM5LDYuNzc0OTEgOC44NDkzNCwxNi4yNDU2NiAxMi4wMjk1MSwyOC40MTM5NyBsIDIwLjUzMjM0LDAgMCwtNTUuOTk5NjcgYyAtNi42NzczMSwtNC41OTM4MSAtMTkuODM2NDMsLTEwLjQ3MzA5IC0zNi4xNDA3MSwtMTUuODI1MjIgeiBtIC0yOC4xMjA0OSw1LjYwNTUxIDguNTY0NzksMTcuNzE2NTUgYyAtMTEuOTcwMzcsLTYuNDY2OTcgLTEzLjg0Njc4LC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk3MDUsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IG0gMTUuMjIxOTUsMjQuMDA4NDggOC41NjQ3OSwxNy43MTY1NSBjIC0xMS45NzAzOCwtNi40NjY5NyAtMTMuODQ2NzksLTkuNzE3MjYgLTguNTY0NzksLTE3LjcxNjU1IHogbSAyMi43OTcwNCwwIGMgMi43NzE1LDcuOTk5MjkgMS43ODc0MSwxMS4yNDk1OCAtNC40OTM1NCwxNy43MTY1NSBsIDQuNDkzNTQsLTE3LjcxNjU1IHogbSAtOTkuMTEzODQsMi4yMDc2NCA4LjU2NDc5LDE3LjcxNjU1IGMgLTExLjk3MDM4MiwtNi40NjY5NyAtMTMuODQ2NzgyLC05LjcxNzI2IC04LjU2NDc5LC0xNy43MTY1NSB6IG0gMjIuNzk1NDIsMCBjIDIuNzcxNSw3Ljk5OTI5IDEuNzg3NDEsMTEuMjQ5NTggLTQuNDkzNTQsMTcuNzE2NTUgbCA0LjQ5MzU0LC0xNy43MTY1NSB6IiAvPg0KPC9zdmc+DQo8IS0tIFRoaXMgd29yayBpcyBsaWNlbnNlZCB1bmRlciBhIENyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24tU2hhcmVBbGlrZSA0LjAgSW50ZXJuYXRpb25hbCBMaWNlbnNlLiAtLT4NCjwhLS0gaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbGljZW5zZXMvYnktc2EvNC4wLyAtLT4NCg==") no-repeat fixed 50%/70% 70%,linear-gradient(180deg,#750000 0,#340404);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#ff750000",endColorstr="#ff340404",GradientType=0)}body.syndicate .normal{color:#40628a}body.syndicate .good{color:#73e573}body.syndicate .average{color:#be6209}body.syndicate .bad{color:#b00e0e}body.syndicate .highlight{color:#000}body.syndicate main{display:block;margin-top:32px;padding:2px 6px 0}body.syndicate hr{height:2px;background-color:#272727;border:none}body.syndicate .hidden{display:none}body.syndicate .bar .barText,body.syndicate span.button{color:#fff;font-size:12px;font-weight:400;font-style:normal;text-decoration:none}body.syndicate .bold{font-weight:700}body.syndicate .italic{font-style:italic}body.syndicate [unselectable=on]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}body.syndicate div[data-tooltip],body.syndicate span[data-tooltip]{position:relative}body.syndicate div[data-tooltip]:after,body.syndicate span[data-tooltip]:after{position:absolute;display:block;z-index:2;width:250px;padding:10px;-ms-transform:translateX(-50%);transform:translateX(-50%);visibility:hidden;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";white-space:normal;text-align:left;content:attr(data-tooltip);transition:all .5s;border:1px solid #272727;background-color:#363636}body.syndicate div[data-tooltip]:hover:after,body.syndicate span[data-tooltip]:hover:after{visibility:visible;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"}body.syndicate div[data-tooltip].tooltip-top:after,body.syndicate span[data-tooltip].tooltip-top:after{bottom:100%;left:50%;-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-top:hover:after,body.syndicate span[data-tooltip].tooltip-top:hover:after{-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:after,body.syndicate span[data-tooltip].tooltip-bottom:after{top:100%;left:50%;-ms-transform:translateX(-50%) translateY(-8px);transform:translateX(-50%) translateY(-8px)}body.syndicate div[data-tooltip].tooltip-bottom:hover:after,body.syndicate span[data-tooltip].tooltip-bottom:hover:after{-ms-transform:translateX(-50%) translateY(8px);transform:translateX(-50%) translateY(8px)}body.syndicate div[data-tooltip].tooltip-left:after,body.syndicate span[data-tooltip].tooltip-left:after{top:50%;right:100%;-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-left:hover:after,body.syndicate span[data-tooltip].tooltip-left:hover:after{-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:after,body.syndicate span[data-tooltip].tooltip-right:after{top:50%;left:100%;-ms-transform:translateX(-8px) translateY(-50%);transform:translateX(-8px) translateY(-50%)}body.syndicate div[data-tooltip].tooltip-right:hover:after,body.syndicate span[data-tooltip].tooltip-right:hover:after{-ms-transform:translateX(8px) translateY(-50%);transform:translateX(8px) translateY(-50%)}body.syndicate .bar{display:inline-block;position:relative;vertical-align:middle;width:100%;height:20px;line-height:17px;padding:1px;border:1px solid #000;background:#272727}body.syndicate .bar .barText{position:absolute;top:0;right:3px}body.syndicate .bar .barFill{display:block;height:100%;transition:background-color 1s;background-color:#000}body.syndicate .bar .barFill.good{background-color:#73e573}body.syndicate .bar .barFill.average{background-color:#be6209}body.syndicate .bar .barFill.bad{background-color:#b00e0e}body.syndicate span.button{display:inline-block;vertical-align:middle;min-height:20px;line-height:17px;padding:0 5px;white-space:nowrap;border:1px solid #272727}body.syndicate span.button .fa{padding-right:2px}body.syndicate span.button.normal{transition:background-color .5s;background-color:#397439}body.syndicate span.button.normal.active:focus,body.syndicate span.button.normal.active:hover{transition:background-color .25s;background-color:#4a964a;outline:0}body.syndicate span.button.disabled{transition:background-color .5s;background-color:#363636}body.syndicate span.button.disabled.active:focus,body.syndicate span.button.disabled.active:hover{transition:background-color .25s;background-color:#545454;outline:0}body.syndicate span.button.selected{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.selected.active:focus,body.syndicate span.button.selected.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.toggle{transition:background-color .5s;background-color:#9d0808}body.syndicate span.button.toggle.active:focus,body.syndicate span.button.toggle.active:hover{transition:background-color .25s;background-color:#ce0b0b;outline:0}body.syndicate span.button.caution{transition:background-color .5s;background-color:#be6209}body.syndicate span.button.caution.active:focus,body.syndicate span.button.caution.active:hover{transition:background-color .25s;background-color:#eb790b;outline:0}body.syndicate span.button.danger{transition:background-color .5s;background-color:#9a9d00}body.syndicate span.button.danger.active:focus,body.syndicate span.button.danger.active:hover{transition:background-color .25s;background-color:#ced200;outline:0}body.syndicate span.button.gridable{width:125px;margin:2px 0}body.syndicate span.button.gridable.center{text-align:center;width:75px}body.syndicate span.button+span:not(.button),body.syndicate span:not(.button)+span.button{margin-left:5px}body.syndicate div.display{width:100%;padding:4px;margin:6px 0;background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#80000000,endColorStr=#80000000);background-color:rgba(0,0,0,.5);box-shadow:inset 0 0 5px rgba(0,0,0,.75)}body.syndicate div.display.tabular{padding:0;margin:0}body.syndicate div.display header,body.syndicate div.subdisplay header{display:block;position:relative;width:100%;padding:0 4px;margin-bottom:6px;color:#fff;border-bottom:2px solid #272727}body.syndicate div.display header .buttonRight,body.syndicate div.subdisplay header .buttonRight{position:absolute;bottom:6px;right:4px}body.syndicate div.display article,body.syndicate div.subdisplay article{display:table;width:100%;border-collapse:collapse}body.syndicate input{display:inline-block;vertical-align:middle;height:20px;line-height:17px;padding:0 5px;white-space:nowrap;color:#fff;background-color:#9d0808;border:1px solid #272727}body.syndicate input.number{width:35px}body.syndicate input:-ms-input-placeholder{color:#999}body.syndicate input::placeholder{color:#999}body.syndicate input::-ms-clear{display:none}body.syndicate svg.linegraph{overflow:hidden}body.syndicate div.notice{margin:8px 0;padding:4px;box-shadow:none;color:#000;font-weight:700;font-style:italic;background-color:#750000;background-image:repeating-linear-gradient(-45deg,#750000,#750000 10px,#910101 0,#910101 20px)}body.syndicate div.notice .label{color:#000}body.syndicate div.notice .content:only-of-type{padding:0}body.syndicate div.notice hr{background-color:#272727}body.syndicate div.resize{position:fixed;bottom:0;right:0;width:0;height:0;border-style:solid;border-width:0 0 45px 45px;border-color:transparent transparent #363636;-ms-transform:rotate(1turn);transform:rotate(1turn)}body.syndicate section .cell,body.syndicate section .content,body.syndicate section .label,body.syndicate section .line{display:table-cell;margin:0;text-align:left;vertical-align:middle;padding:3px 2px}body.syndicate section{display:table-row;width:100%}body.syndicate section:not(:first-child){padding-top:4px}body.syndicate section.candystripe:nth-child(2n){background-color:#000;-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000)";filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#33000000,endColorStr=#33000000);background-color:rgba(0,0,0,.2)}body.syndicate section .label{width:1%;padding-right:32px;white-space:nowrap;color:#fff}body.syndicate section .content:not(:last-child){padding-right:16px}body.syndicate section .line{width:100%}body.syndicate section .cell:not(:first-child){text-align:center;padding-top:0}body.syndicate section .cell span.button{width:75px}body.syndicate section:not(:last-child){padding-right:4px}body.syndicate div.subdisplay{width:100%;margin:0}body.syndicate header.titlebar .close,body.syndicate header.titlebar .minimize{display:inline-block;position:relative;padding:7px;margin:-7px;color:#e74242}body.syndicate header.titlebar .close:hover,body.syndicate header.titlebar .minimize:hover{color:#eb5e5e}body.syndicate header.titlebar{position:fixed;z-index:1;top:0;left:0;width:100%;height:32px;background-color:#363636;border-bottom:1px solid #161616;box-shadow:0 3px 3px rgba(0,0,0,.1)}body.syndicate header.titlebar .statusicon{position:absolute;top:4px;left:12px;transition:color .5s}body.syndicate header.titlebar .title{position:absolute;top:6px;left:46px;color:#e74242;font-size:16px;white-space:nowrap}body.syndicate header.titlebar .minimize{position:absolute;top:6px;right:46px}body.syndicate header.titlebar .close{position:absolute;top:4px;right:12px}.no-icons header.titlebar .statusicon{font-size:20px}.no-icons header.titlebar .statusicon:after{content:"O"}.no-icons header.titlebar .minimize{top:-2px;font-size:20px}.no-icons header.titlebar .minimize:after{content:"—"}.no-icons header.titlebar .close{font-size:20px}.no-icons header.titlebar .close:after{content:"X"}
\ No newline at end of file
diff --git a/tgui/assets/tgui.js b/tgui/assets/tgui.js
index 02e6e9aa58..e80e39528f 100644
--- a/tgui/assets/tgui.js
+++ b/tgui/assets/tgui.js
@@ -6,16 +6,16 @@ try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n},_=function(t)
return t.docFrag.appendChild(e.render())}),this.renderedFragments=this.fragments.slice(),this.fragmentsToRender=[],this.rendered=!0,this.docFrag}function Ze(t){var e,n,a=this;this.updating||(this.updating=!0,this.keypath&&(e=this.root.viewmodel.wrapped[this.keypath.str])&&(t=e.get()),this.fragmentsToCreate.length?(n={template:this.template.f||[],root:this.root,pElement:this.pElement,owner:this},this.fragmentsToCreate.forEach(function(t){var e;n.context=a.keypath.join(t),n.index=t,e=new rg(n),a.fragmentsToRender.push(a.fragments[t]=e)}),this.fragmentsToCreate.length=0):en(this,t)&&(this.bubble(),this.rendered&&bs.addView(this)),this.value=t,this.updating=!1)}function tn(t,e,n){if(e===Bu&&t.indexRefs&&t.indexRefs[0]){var a=t.indexRefs[0];(n&&"i"===a.t||!n&&"k"===a.t)&&(n||(t.length=0,t.fragmentsToUnrender=t.fragments.slice(0),t.fragmentsToUnrender.forEach(function(t){return t.unbind()}))),a.t=n?"k":"i"}t.currentSubtype=e}function en(t,e){var n={template:t.template.f||[],root:t.root,pElement:t.parentFragment.pElement,owner:t};if(t.hasContext=!0,t.subtype)switch(t.subtype){case Fu:return t.hasContext=!1,sn(t,e,!1,n);case Iu:return t.hasContext=!1,sn(t,e,!0,n);case Vu:return on(t,n);case qu:return rn(t,e,n);case Bu:if(u(e))return tn(t,t.subtype,!0),an(t,e,n)}return t.ordered=!!o(e),t.ordered?(tn(t,Bu,!1),nn(t,e,n)):u(e)||"function"==typeof e?t.template.i?(tn(t,Bu,!0),an(t,e,n)):(tn(t,Vu,!1),on(t,n)):(tn(t,Fu,!1),t.hasContext=!1,sn(t,e,!1,n))}function nn(t,e,n){var a,r,i;if(r=e.length,r===t.length)return!1;if(rt.length)for(a=t.length;r>a;a+=1)n.context=t.keypath.join(a),n.index=a,i=new rg(n),t.fragmentsToRender.push(t.fragments[a]=i);return t.length=r,!0}function an(t,e,n){var a,r,i,o,s,p;for(i=t.hasKey||(t.hasKey={}),r=t.fragments.length;r--;)o=t.fragments[r],o.key in e||(s=!0,o.unbind(),t.fragmentsToUnrender.push(o),t.fragments.splice(r,1),i[o.key]=!1);for(r=t.fragments.length;r--;)o=t.fragments[r],o.index!==r&&(o.index=r,(p=o.registeredIndexRefs)&&p.forEach(cn));r=t.fragments.length;for(a in e)i[a]||(s=!0,n.context=t.keypath.join(a),n.key=a,n.index=r++,o=new rg(n),t.fragmentsToRender.push(o),t.fragments.push(o),i[a]=!0);return t.length=t.fragments.length,s}function rn(t,e,n){return e?on(t,n):pn(t)}function on(t,e){var n;return t.length?void 0:(e.context=t.keypath,e.index=0,n=new rg(e),t.fragmentsToRender.push(t.fragments[0]=n),t.length=1,!0)}function sn(t,e,n,a){var r,i,s,p,c;if(i=o(e)&&0===e.length,s=!1,!o(e)&&u(e)){s=!0;for(c in e){s=!1;break}}return r=n?i||s||!e:e&&!i&&!s,r?t.length?t.length>1?(t.fragmentsToUnrender=t.fragments.splice(1),t.fragmentsToUnrender.forEach(K),!0):void 0:(a.index=0,p=new rg(a),t.fragmentsToRender.push(t.fragments[0]=p),t.length=1,!0):pn(t)}function pn(t){return t.length?(t.fragmentsToUnrender=t.fragments.splice(0,t.fragments.length).filter(un),t.fragmentsToUnrender.forEach(K),t.length=t.fragmentsToRender.length=0,!0):void 0}function un(t){return t.rendered}function cn(t){t.rebind("","")}function ln(t){var e,n,a;for(e="",n=0,a=this.length,n=0;a>n;n+=1)e+=this.fragments[n].toString(t);return e}function dn(){var t=this;this.fragments.forEach(K),this.fragmentsToRender.forEach(function(e){return N(t.fragments,e)}),this.fragmentsToRender=[],_c.call(this),this.length=0,this.unbound=!0}function fn(t){this.fragments.forEach(t?hn:mn),this.renderedFragments=[],this.rendered=!1}function hn(t){t.unrender(!0)}function mn(t){t.unrender(!1)}function gn(){var t,e,n,a,r,i,o;for(n=this.renderedFragments;t=this.fragmentsToUnrender.pop();)t.unrender(!0),n.splice(n.indexOf(t),1);for(;t=this.fragmentsToRender.shift();)t.render();for(this.rendered&&(r=this.parentFragment.getNode()),o=this.fragments.length,i=0;o>i;i+=1)t=this.fragments[i],e=n.indexOf(t,i),e!==i?(this.docFrag.appendChild(t.detach()),-1!==e&&n.splice(e,1),n.splice(i,0,t)):this.docFrag.childNodes.length&&(a=t.firstNode(),r.insertBefore(this.docFrag,a));this.rendered&&this.docFrag.childNodes.length&&(a=this.parentFragment.findNextNode(this),r.insertBefore(this.docFrag,a)),this.renderedFragments=this.fragments.slice()}function vn(){var t,e;if(this.docFrag){for(t=this.nodes.length,e=0;t>e;e+=1)this.docFrag.appendChild(this.nodes[e]);return this.docFrag}}function bn(t){var e,n,a,r;for(n=this.nodes.length,e=0;n>e;e+=1)if(a=this.nodes[e],1===a.nodeType){if(lo(a,t))return a;if(r=a.querySelector(t))return r}return null}function yn(t,e){var n,a,r,i,o,s;for(a=this.nodes.length,n=0;a>n;n+=1)if(r=this.nodes[n],1===r.nodeType&&(lo(r,t)&&e.push(r),i=r.querySelectorAll(t)))for(o=i.length,s=0;o>s;s+=1)e.push(i[s])}function _n(){return this.rendered&&this.nodes[0]?this.nodes[0]:this.parentFragment.findNextNode(this)}function xn(t){return gl[t]||(gl[t]=co(t))}function wn(t){var e,n,a;t&&"select"===t.name&&t.binding&&(e=F(t.node.options).filter(kn),t.getAttribute("multiple")?a=e.map(function(t){return t.value}):(n=e[0])&&(a=n.value),void 0!==a&&t.binding.setValue(a),t.bubble())}function kn(t){return t.selected}function Sn(){if(this.rendered)throw Error("Attempted to render an item that was already rendered");return this.docFrag=document.createDocumentFragment(),this.nodes=vl(this.value,this.parentFragment.getNode(),this.docFrag),bl(this.pElement),this.rendered=!0,this.docFrag}function En(t){var e;(e=this.root.viewmodel.wrapped[this.keypath.str])&&(t=e.get()),t!==this.value&&(this.value=t,this.parentFragment.bubble(),this.rendered&&bs.addView(this))}function Cn(){return void 0!=this.value?we(""+this.value):""}function Pn(t){this.rendered&&t&&(this.nodes.forEach(e),this.rendered=!1)}function An(){var t,e;if(this.rendered){for(;this.nodes&&this.nodes.length;)t=this.nodes.pop(),t.parentNode.removeChild(t);e=this.parentFragment.getNode(),this.nodes=vl(this.value,e,this.docFrag),e.insertBefore(this.docFrag,this.parentFragment.findNextNode(this)),bl(this.pElement)}}function On(){var t,e=this.node;return e?((t=e.parentNode)&&t.removeChild(e),e):void 0}function Tn(){return null}function Rn(){return this.node}function Mn(t){return this.attributes&&this.attributes[t]?this.attributes[t].value:void 0}function Ln(){var t=this.useProperty||!this.rendered?this.fragment.getValue():""+this.fragment;s(t,this.value)||("id"===this.name&&this.value&&delete this.root.nodes[this.value],this.value=t,"value"===this.name&&this.node&&(this.node._ractive.value=t),this.rendered&&bs.addView(this))}function jn(t){var e=t.fragment.items;if(1===e.length)return e[0].type===Su?e[0]:void 0}function Dn(t){return this.type=Tu,this.element=t.element,this.root=t.root,zl(this,t.name),this.isBoolean=rc.test(this.name),t.value&&"string"!=typeof t.value?(this.parentFragment=this.element.parentFragment,this.fragment=new rg({template:t.value,root:this.root,owner:this}),this.value=this.fragment.getValue(),this.interpolator=Wl(this),this.isBindable=!!this.interpolator&&!this.interpolator.isStatic,void(this.ready=!0)):void(this.value=this.isBoolean?!0:t.value||"")}function Nn(t,e){this.fragment&&this.fragment.rebind(t,e)}function Fn(t){var e;this.node=t,t.namespaceURI&&t.namespaceURI!==no.html||(e=Yl[this.name]||this.name,void 0!==t[e]&&(this.propertyName=e),(this.isBoolean||this.isTwoway)&&(this.useProperty=!0),"value"===e&&(t._ractive.value=this.value)),this.rendered=!0,this.update()}function In(){var t=this,e=t.name,n=t.namespacePrefix,a=t.value,r=t.interpolator,i=t.fragment;if(("value"!==e||"select"!==this.element.name&&"textarea"!==this.element.name)&&("value"!==e||void 0===this.element.getAttribute("contenteditable"))){if("name"===e&&"input"===this.element.name&&r)return"name={{"+(r.keypath.str||r.ref)+"}}";if(this.isBoolean)return a?e:"";if(i){if(1===i.items.length&&null==i.items[0].value)return"";a=""+i}return n&&(e=n+":"+e),a?e+'="'+Bn(a)+'"':e}}function Bn(t){return t.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'")}function Vn(){this.fragment&&this.fragment.unbind(),"id"===this.name&&delete this.root.nodes[this.value]}function qn(){var t,e,n,a,r=this.value;if(!this.locked)for(this.node._ractive.value=r,t=this.node.options,a=t.length;a--;)if(e=t[a],n=e._ractive?e._ractive.value:e.value,n==r){e.selected=!0;break}}function Un(){var t,e,n,a,r=this.value;for(i(r)||(r=[r]),t=this.node.options,e=t.length;e--;)n=t[e],a=n._ractive?n._ractive.value:n.value,n.selected=M(r,a)}function Gn(){var t=this,e=t.node,n=t.value;e.checked=n==e._ractive.value}function zn(){var t,e,n,a,r=this.node;if(t=r.checked,r.value=this.element.getAttribute("value"),r.checked=this.element.getAttribute("value")===this.element.getAttribute("name"),t&&!r.checked&&this.element.binding&&(n=this.element.binding.siblings,a=n.length)){for(;a--;){if(e=n[a],!e.element.node)return;if(e.element.node.checked)return bs.addRactive(e.root),e.handleChange()}this.root.viewmodel.set(e.keypath,void 0)}}function Wn(){var t,e,n=this,a=n.element,r=n.node,o=n.value,s=a.binding;if(t=a.getAttribute("value"),i(o)){for(e=o.length;e--;)if(t==o[e])return void(s.isChecked=r.checked=!0);s.isChecked=r.checked=!1}else s.isChecked=r.checked=o==t}function Hn(){this.node.className=n(this.value)}function Kn(){var t=this,e=t.node,n=t.value;this.root.nodes[n]=e,e.id=n}function Qn(){var t,e;t=this.node,e=this.value,void 0===e&&(e=""),t.style.setAttribute("cssText",e)}function Yn(){var t=this.value;void 0===t&&(t=""),this.locked||(this.node.innerHTML=t)}function $n(){var t=this,e=t.node,n=t.value;e._ractive.value=n,this.locked||(e.value=void 0==n?"":n)}function Jn(){this.locked||(this.node[this.propertyName]=this.value)}function Xn(){var t=this,e=t.node,n=t.namespace,a=t.name,r=t.value,i=t.fragment;n?e.setAttributeNS(n,a,""+(i||r)):this.isBoolean?r?e.setAttribute(a,""):e.removeAttribute(a):null==r?e.removeAttribute(a):e.setAttribute(a,""+(i||r))}function Zn(){var t,e,n=this,a=n.name,r=n.element,i=n.node;"id"===a?e=rd:"value"===a?"select"===r.name&&"value"===a?e=r.getAttribute("multiple")?Zl:Xl:"textarea"===r.name?e=sd:null!=r.getAttribute("contenteditable")?e=od:"input"===r.name&&(t=r.getAttribute("type"),e="file"===t?ko:"radio"===t&&r.binding&&"name"===r.binding.name?ed:sd):this.isTwoway&&"name"===a?"radio"===i.type?e=td:"checkbox"===i.type&&(e=nd):"style"===a&&i.style.setAttribute?e=id:"class"!==a||i.namespaceURI&&i.namespaceURI!==no.html?this.useProperty&&(e=pd):e=ad,e||(e=ud),this.update=e,this.update()}function ta(t,e){var n=e?"svg":"div";return dd.innerHTML="<"+n+" "+t+">"+n+">",F(dd.childNodes[0].attributes)}function ea(t,e){for(var n=t.length;n--;)if(t[n].name===e.name)return!1;return!0}function na(t){for(;t=t.parent;)if("form"===t.name)return t}function aa(){this._ractive.binding.handleChange()}function ra(){var t;xd.call(this),t=this._ractive.root.viewmodel.get(this._ractive.binding.keypath),this.value=void 0==t?"":t}function ia(){var t=this._ractive.binding,e=this;t._timeout&&clearTimeout(t._timeout),t._timeout=setTimeout(function(){t.rendered&&xd.call(e),t._timeout=void 0},t.element.lazy)}function oa(t,e,n){var a=t+e+n;return Cd[a]||(Cd[a]=[])}function sa(t){return t.isChecked}function pa(t){return t.element.getAttribute("value")}function ua(t){var e,n,a,r,i,o=t.attributes;return t.binding&&(t.binding.teardown(),t.binding=null),(t.getAttribute("contenteditable")||o.contenteditable&&ca(o.contenteditable))&&ca(o.value)?n=Sd:"input"===t.name?(e=t.getAttribute("type"),"radio"===e||"checkbox"===e?(a=ca(o.name),r=ca(o.checked),a&&r&&m("A radio input can have two-way binding on its name attribute, or its checked attribute - not both",{ractive:t.root}),a?n="radio"===e?Td:Md:r&&(n="radio"===e?Ad:jd)):"file"===e&&ca(o.value)?n=Vd:ca(o.value)&&(n="number"===e||"range"===e?qd:wd)):"select"===t.name&&ca(o.value)?n=t.getAttribute("multiple")?Id:Nd:"textarea"===t.name&&ca(o.value)&&(n=wd),n&&(i=new n(t))&&i.keypath?i:void 0}function ca(t){return t&&t.isBindable}function la(){var t=this.getAction();t&&!this.hasListener?this.listen():!t&&this.hasListener&&this.unrender()}function da(t){zs(this.root,this.getAction(),{event:t})}function fa(){return(""+this.action).trim()}function ha(t,e,n){var a,r,i,o=this;this.element=t,this.root=t.root,this.parentFragment=t.parentFragment,this.name=e,-1!==e.indexOf("*")&&(l('Only component proxy-events may contain "*" wildcards, <%s on-%s="..."/> is not valid',t.name,e),this.invalid=!0),n.m?(r=n.a.r,this.method=n.m,this.keypaths=[],this.fn=Mc(n.a.s,r.length),this.parentFragment=t.parentFragment,i=this.root,this.refResolvers=[],r.forEach(function(t,e){var n=void 0;(n=Kd.exec(t))?o.keypaths[e]={eventObject:!0,refinements:n[1]?n[1].split("."):[]}:o.refResolvers.push(Rc(o,t,function(t){return o.resolve(e,t)}))}),this.fire=ma):(a=n.n||n,"string"!=typeof a&&(a=new rg({template:a,root:this.root,owner:this})),this.action=a,n.d?(this.dynamicParams=new rg({template:n.d,root:this.root,owner:this.element}),this.fire=va):n.a&&(this.params=n.a,this.fire=ga))}function ma(t){var e,n,a;if(e=this.root,"function"!=typeof e[this.method])throw Error('Attempted to call a non-existent method ("'+this.method+'")');n=this.keypaths.map(function(n){var a,r,i;if(void 0!==n){if(n.eventObject){if(a=t,r=n.refinements.length)for(i=0;r>i;i+=1)a=a[n.refinements[i]]}else a=e.viewmodel.get(n);return a}}),Gs.enqueue(e,t),a=this.fn.apply(null,n),e[this.method].apply(e,a),Gs.dequeue(e)}function ga(t){zs(this.root,this.getAction(),{event:t,args:this.params})}function va(t){var e=this.dynamicParams.getArgsList();"string"==typeof e&&(e=e.substr(1,e.length-2)),zs(this.root,this.getAction(),{event:t,args:e})}function ba(t){var e,n,a,r={};e=this._ractive,n=e.events[t.type],(a=Oc(n.element.parentFragment))&&(r=Oc.resolve(a)),n.fire({node:this,original:t,index:r,keypath:e.keypath.str,context:e.root.viewmodel.get(e.keypath)})}function ya(){var t,e=this.name;if(!this.invalid){if(t=v("events",this.root,e))this.custom=t(this.node,_a(e));else{if(!("on"+e in this.node||window&&"on"+e in window||Zi))return void(Jd[e]||g(Io(e,"event"),{node:this.node}));this.node.addEventListener(e,Qd,!1)}this.hasListener=!0}}function _a(t){return $d[t]||($d[t]=function(e){var n=e.node._ractive;e.index=n.index,e.keypath=n.keypath.str,e.context=n.root.viewmodel.get(n.keypath),n.events[t].fire(e)}),$d[t]}function xa(t,e){function n(n){n&&n.rebind(t,e)}var a;return this.method?(a=this.element.parentFragment,void this.refResolvers.forEach(n)):("string"!=typeof this.action&&n(this.action),void(this.dynamicParams&&n(this.dynamicParams)))}function wa(){this.node=this.element.node,this.node._ractive.events[this.name]=this,(this.method||this.getAction())&&this.listen()}function ka(t,e){this.keypaths[t]=e}function Sa(){return this.method?void this.refResolvers.forEach(K):("string"!=typeof this.action&&this.action.unbind(),void(this.dynamicParams&&this.dynamicParams.unbind()))}function Ea(){this.custom?this.custom.teardown():this.node.removeEventListener(this.name,Qd,!1),this.hasListener=!1}function Ca(){var t=this;this.dirty||(this.dirty=!0,bs.scheduleTask(function(){Pa(t),t.dirty=!1})),this.parentFragment.bubble()}function Pa(t){var e,n,a,r,i;e=t.node,e&&(r=F(e.options),n=t.getAttribute("value"),a=t.getAttribute("multiple"),void 0!==n?(r.forEach(function(t){var e,r;e=t._ractive?t._ractive.value:t.value,r=a?Aa(n,e):n==e,r&&(i=!0),t.selected=r}),i||(r[0]&&(r[0].selected=!0),t.binding&&t.binding.forceUpdate())):t.binding&&t.binding.forceUpdate())}function Aa(t,e){for(var n=t.length;n--;)if(t[n]==e)return!0}function Oa(t,e){t.select=Ra(t.parent),t.select&&(t.select.options.push(t),e.a||(e.a={}),void 0!==e.a.value||e.a.hasOwnProperty("disabled")||(e.a.value=e.f),"selected"in e.a&&void 0!==t.select.getAttribute("value")&&delete e.a.selected)}function Ta(t){t.select&&N(t.select.options,t)}function Ra(t){if(t)do if("select"===t.name)return t;while(t=t.parent)}function Ma(t){var e,n,a,r,i,o,s;this.type=Pu,e=this.parentFragment=t.parentFragment,n=this.template=t.template,this.parent=t.pElement||e.pElement,this.root=a=e.root,this.index=t.index,this.key=t.key,this.name=Gl(n.e),"option"===this.name&&Oa(this,n),"select"===this.name&&(this.options=[],this.bubble=Ca),"form"===this.name&&(this.formBindings=[]),s=ql(this,n),this.attributes=hd(this,n.a),this.conditionalAttributes=vd(this,n.m),n.f&&(this.fragment=new rg({template:n.f,root:a,owner:this,pElement:this,cssIds:null})),o=a.twoway,s.twoway===!1?o=!1:s.twoway===!0&&(o=!0),this.twoway=o,this.lazy=s.lazy,o&&(r=Ud(this,n.a))&&(this.binding=r,i=this.root._twowayBindings[r.keypath.str]||(this.root._twowayBindings[r.keypath.str]=[]),i.push(r)),n.v&&(this.eventHandlers=of(this,n.v)),n.o&&(this.decorator=new lf(this,n.o)),this.intro=n.t0||n.t1,this.outro=n.t0||n.t2}function La(t,e){function n(n){n.rebind(t,e)}var a,r,i,o;if(this.attributes&&this.attributes.forEach(n),this.conditionalAttributes&&this.conditionalAttributes.forEach(n),this.eventHandlers&&this.eventHandlers.forEach(n),this.decorator&&n(this.decorator),this.fragment&&n(this.fragment),i=this.liveQueries)for(o=this.root,a=i.length;a--;)i[a]._makeDirty();this.node&&(r=this.node._ractive)&&w(r,"keypath",t,e)}function ja(t){var e;(t.attributes.width||t.attributes.height)&&t.node.addEventListener("load",e=function(){var n=t.getAttribute("width"),a=t.getAttribute("height");void 0!==n&&t.node.setAttribute("width",n),void 0!==a&&t.node.setAttribute("height",a),t.node.removeEventListener("load",e,!1)},!1)}function Da(t){t.node.addEventListener("reset",Fa,!1)}function Na(t){t.node.removeEventListener("reset",Fa,!1)}function Fa(){var t=this._ractive.proxy;bs.start(),t.formBindings.forEach(Ia),bs.end()}function Ia(t){t.root.viewmodel.set(t.keypath,t.resetValue)}function Ba(t,e,n){var a,r,i;this.element=t,this.root=a=t.root,this.isIntro=n,r=e.n||e,("string"==typeof r||(i=new rg({template:r,root:a,owner:t}),r=""+i,i.unbind(),""!==r))&&(this.name=r,e.a?this.params=e.a:e.d&&(i=new rg({template:e.d,root:a,owner:t}),this.params=i.getArgsList(),i.unbind()),this._fn=v("transitions",a,r),this._fn||g(Io(r,"transition"),{ractive:this.root}))}function Va(t){return t}function qa(){qf.hidden=document[Ff]}function Ua(){qf.hidden=!0}function Ga(){qf.hidden=!1}function za(){var t,e,n,a=this;return t=this.node=this.element.node,e=t.getAttribute("style"),this.complete=function(r){n||(!r&&a.isIntro&&Wa(t,e),t._ractive.transition=null,a._manager.remove(a),n=!0)},this._fn?void this._fn.apply(this.root,[this].concat(this.params)):void this.complete()}function Wa(t,e){e?t.setAttribute("style",e):(t.getAttribute("style"),t.removeAttribute("style"))}function Ha(){var t,e,n,a=this,r=this.root;return t=Ka(this),e=this.node=co(this.name,t),this.parentFragment.cssIds&&this.node.setAttribute("data-ractive-css",this.parentFragment.cssIds.map(function(t){return"{"+t+"}"}).join(" ")),Eo(this.node,"_ractive",{value:{proxy:this,keypath:cs(this.parentFragment),events:So(null),root:r}}),this.attributes.forEach(function(t){return t.render(e)}),this.conditionalAttributes.forEach(function(t){return t.render(e)}),this.fragment&&("script"===this.name?(this.bubble=Xf,this.node.text=this.fragment.toString(!1),this.fragment.unrender=ko):"style"===this.name?(this.bubble=Jf,this.bubble(),this.fragment.unrender=ko):this.binding&&this.getAttribute("contenteditable")?this.fragment.unrender=ko:this.node.appendChild(this.fragment.render())),this.binding&&(this.binding.render(),this.node._ractive.binding=this.binding),this.eventHandlers&&this.eventHandlers.forEach(function(t){return t.render()}),"option"===this.name&&Qa(this),"img"===this.name?ja(this):"form"===this.name?Da(this):"input"===this.name||"textarea"===this.name?this.node.defaultValue=this.node.value:"option"===this.name&&(this.node.defaultSelected=this.node.selected),this.decorator&&this.decorator.fn&&bs.scheduleTask(function(){a.decorator.torndown||a.decorator.init()},!0),r.transitionsEnabled&&this.intro&&(n=new Zf(this,this.intro,!0),bs.registerTransition(n),bs.scheduleTask(function(){return n.start()},!0),this.transition=n),this.node.autofocus&&bs.scheduleTask(function(){return a.node.focus()},!0),Ya(this),this.node}function Ka(t){var e,n,a;return e=(n=t.getAttribute("xmlns"))?n:"svg"===t.name?no.svg:(a=t.parent)?"foreignObject"===a.name?no.html:a.node.namespaceURI:t.root.el.namespaceURI}function Qa(t){var e,n,a;if(t.select&&(n=t.select.getAttribute("value"),void 0!==n))if(e=t.getAttribute("value"),t.select.node.multiple&&i(n)){for(a=n.length;a--;)if(e==n[a]){t.node.selected=!0;break}}else t.node.selected=e==n}function Ya(t){var e,n,a,r,i;e=t.root;do for(n=e._liveQueries,a=n.length;a--;)r=n[a],i=n["_"+r],i._test(t)&&(t.liveQueries||(t.liveQueries=[])).push(i);while(e=e.parent)}function $a(t){var e,n,a;if(e=t.getAttribute("value"),void 0===e||!t.select)return!1;if(n=t.select.getAttribute("value"),n==e)return!0;if(t.select.getAttribute("multiple")&&i(n))for(a=n.length;a--;)if(n[a]==e)return!0}function Ja(t){var e,n,a,r;return e=t.attributes,n=e.type,a=e.value,r=e.name,n&&"radio"===n.value&&a&&r.interpolator&&a.value===r.interpolator.value?!0:void 0}function Xa(t){var e=""+t;return e?" "+e:""}function Za(){this.fragment&&this.fragment.unbind(),this.binding&&this.binding.unbind(),this.eventHandlers&&this.eventHandlers.forEach(K),"option"===this.name&&Ta(this),this.attributes.forEach(K),this.conditionalAttributes.forEach(K)}function tr(t){var e,n,a;(a=this.transition)&&a.complete(),"option"===this.name?this.detach():t&&bs.detachWhenReady(this),this.fragment&&this.fragment.unrender(!1),(e=this.binding)&&(this.binding.unrender(),this.node._ractive.binding=null,n=this.root._twowayBindings[e.keypath.str],n.splice(n.indexOf(e),1)),this.eventHandlers&&this.eventHandlers.forEach(Q),this.decorator&&bs.registerDecorator(this.decorator),this.root.transitionsEnabled&&this.outro&&(a=new Zf(this,this.outro,!1),bs.registerTransition(a),bs.scheduleTask(function(){return a.start()})),this.liveQueries&&er(this),"form"===this.name&&Na(this)}function er(t){var e,n,a;for(a=t.liveQueries.length;a--;)e=t.liveQueries[a],n=e.selector,e._remove(t.node)}function nr(t,e){var n=sh.exec(e)[0];return null===t||n.length%s}}) cannot contain nested inline partials",e,{ractive:t});var s=a?i:ir(i,e);s.partials[e]=r=o.t}return a&&(r._fn=a),r.v?r.t:r}}function ir(t,e){return t.partials.hasOwnProperty(e)?t:or(t.constructor,e)}function or(t,e){return t?t.partials.hasOwnProperty(e)?t:or(t._Parent,e):void 0}function sr(t,e){if(e){if(e.template&&e.template.p&&e.template.p[t])return e.template.p[t];if(e.parentFragment&&e.parentFragment.owner)return sr(t,e.parentFragment.owner)}}function pr(t,e){var n,a=b("components",t,e);if(a&&(n=a.components[e],!n._Parent)){var r=n.bind(a);if(r.isOwner=a.components.hasOwnProperty(e),n=r(),!n)return void m(Fo,e,"component","component",{ractive:t});"string"==typeof n&&(n=pr(t,n)),n._fn=r,a.components[e]=n}return n}function ur(){var t=this.instance.fragment.detach();return yh.fire(this.instance),t}function cr(t){return this.instance.fragment.find(t)}function lr(t,e){return this.instance.fragment.findAll(t,e)}function dr(t,e){e._test(this,!0),this.instance.fragment&&this.instance.fragment.findAllComponents(t,e)}function fr(t){return t&&t!==this.name?this.instance.fragment?this.instance.fragment.findComponent(t):null:this.instance}function hr(){return this.parentFragment.findNextNode(this)}function mr(){return this.rendered?this.instance.fragment.firstNode():null}function gr(t,e,n){function a(t){var n,a;t.value=e,t.updating||(a=t.ractive,n=t.keypath,t.updating=!0,bs.start(a),a.viewmodel.mark(n),bs.end(),t.updating=!1)}var r,i,o,s,p,u;if(r=t.obj,i=t.prop,n&&!n.configurable){if("length"===i)return;throw Error('Cannot use magic mode with property "'+i+'" - object is not configurable')}n&&(o=n.get,s=n.set),p=o||function(){return e},u=function(t){s&&s(t),e=o?o():t,u._ractiveWrappers.forEach(a)},u._ractiveWrappers=[t],Object.defineProperty(r,i,{get:p,set:u,enumerable:!0,configurable:!0})}function vr(t,e){var n,a,r,i;if(this.adaptors)for(n=this.adaptors.length,a=0;n>a;a+=1)if(r=this.adaptors[a],r.filter(e,t,this.ractive))return i=this.wrapped[t]=r.wrap(this.ractive,e,t,yr(t)),void(i.value=e)}function br(t,e){var n,a={};if(!e)return t;e+=".";for(n in t)t.hasOwnProperty(n)&&(a[e+n]=t[n]);return a}function yr(t){var e;return Gh[t]||(e=t?t+".":"",Gh[t]=function(n,a){var r;return"string"==typeof n?(r={},r[e+n]=a,r):"object"==typeof n?e?br(n,t):n:void 0}),Gh[t]}function _r(t){var e,n,a=[$o];for(e=t.length;e--;)for(n=t[e].parent;n&&!n.isRoot;)-1===t.indexOf(n)&&R(a,n),n=n.parent;return a}function xr(t,e,n){var a;kr(t,e),n||(a=e.wildcardMatches(),a.forEach(function(n){wr(t,n,e)}))}function wr(t,e,n){var a,r,i;e=e.str||e,a=t.depsMap.patternObservers,r=a&&a[e],r&&r.forEach(function(e){i=n.join(e.lastKey),kr(t,i),wr(t,e,i)})}function kr(t,e){t.patternObservers.forEach(function(t){t.regex.test(e.str)&&t.update(e)})}function Sr(){function t(t){var a=t.key;t.viewmodel===o?(o.clearCache(a.str),t.invalidate(),n.push(a),e(a)):t.viewmodel.mark(a)}function e(n){var a,r;o.noCascade.hasOwnProperty(n.str)||((r=o.deps.computed[n.str])&&r.forEach(t),(a=o.depsMap.computed[n.str])&&a.forEach(e))}var n,a,r,i=this,o=this,s={};return n=this.changes,n.length?(n.slice().forEach(e),a=zh(n),a.forEach(function(e){var a;-1===n.indexOf(e)&&(a=o.deps.computed[e.str])&&a.forEach(t)}),this.changes=[],this.patternObservers.length&&(a.forEach(function(t){return Wh(i,t,!0)}),n.forEach(function(t){return Wh(i,t)})),this.deps.observers&&(a.forEach(function(t){return Er(i,null,t,"observers")}),Pr(this,n,"observers")),this.deps["default"]&&(r=[],a.forEach(function(t){return Er(i,r,t,"default")}),r.length&&Cr(this,r,n),Pr(this,n,"default")),n.forEach(function(t){s[t.str]=i.get(t)}),this.implicitChanges={},this.noCascade={},s):void 0}function Er(t,e,n,a){var r,i;(r=Ar(t,n,a))&&(i=t.get(n),r.forEach(function(t){e&&t.refineValue?e.push(t):t.setValue(i)}))}function Cr(t,e,n){e.forEach(function(e){for(var a=!1,r=0,i=n.length,o=[];i>r;){var s=n[r];if(s===e.keypath){a=!0;break}s.slice(0,e.keypath.length)===e.keypath&&o.push(s),r++}a&&e.setValue(t.get(e.keypath)),o.length&&e.refineValue(o)})}function Pr(t,e,n){function a(t){t.forEach(r),t.forEach(i)}function r(e){var a=Ar(t,e,n);a&&s.push({keypath:e,deps:a})}function i(e){var r;(r=t.depsMap[n][e.str])&&a(r)}function o(e){var n=t.get(e.keypath);e.deps.forEach(function(t){return t.setValue(n)})}var s=[];a(e),s.forEach(o)}function Ar(t,e,n){var a=t.deps[n];return a?a[e.str]:null}function Or(){this.captureGroups.push([])}function Tr(t,e){var n,a;if(e||(a=this.wrapped[t])&&a.teardown()!==!1&&(this.wrapped[t]=null),this.cache[t]=void 0,n=this.cacheMap[t])for(;n.length;)this.clearCache(n.pop())}function Rr(t,e){var n=e.firstKey;return!(n in t.data||n in t.computations||n in t.mappings)}function Mr(t,e){var n=new Xh(t,e);return this.ready&&n.init(this),this.computations[t.str]=n}function Lr(t,e){var n,a,r,i,o,s=this.cache,p=t.str;if(e=e||nm,e.capture&&(i=D(this.captureGroups))&&(~i.indexOf(t)||i.push(t)),Mo.call(this.mappings,t.firstKey))return this.mappings[t.firstKey].get(t,e);if(t.isSpecial)return t.value;if(void 0===s[p]?((a=this.computations[p])&&!a.bypass?(n=a.get(),this.adapt(p,n)):(r=this.wrapped[p])?n=r.value:t.isRoot?(this.adapt("",this.data),n=this.data):n=jr(this,t),s[p]=n):n=s[p],!e.noUnwrap&&(r=this.wrapped[p])&&(n=r.get()),t.isRoot&&e.fullRootGet)for(o in this.mappings)n[o]=this.mappings[o].getValue();return n===tm?void 0:n}function jr(t,e){var n,a,r,i;return n=t.get(e.parent),(i=t.wrapped[e.parent.str])&&(n=i.get()),null!==n&&void 0!==n?((a=t.cacheMap[e.parent.str])?-1===a.indexOf(e.str)&&a.push(e.str):t.cacheMap[e.parent.str]=[e.str],"object"!=typeof n||e.lastKey in n?(r=n[e.lastKey],t.adapt(e.str,r,!1),t.cache[e.str]=r,r):t.cache[e.str]=tm):void 0}function Dr(){var t;for(t in this.computations)this.computations[t].init(this)}function Nr(t,e){var n=this.mappings[t.str]=new im(t,e);return n.initViewmodel(this),n}function Fr(t,e){var n,a=t.str;e&&(e.implicit&&(this.implicitChanges[a]=!0),e.noCascade&&(this.noCascade[a]=!0)),(n=this.computations[a])&&n.invalidate(),-1===this.changes.indexOf(t)&&this.changes.push(t);var r=e?e.keepExistingWrapper:!1;this.clearCache(a,r),this.ready&&this.onchange()}function Ir(t,e,n,a){var r,i,o,s;if(this.mark(t),a&&a.compare){o=Vr(a.compare);try{r=e.map(o),i=n.map(o)}catch(p){m('merge(): "%s" comparison failed. Falling back to identity checking',t),r=e,i=n}}else r=e,i=n;s=sm(r,i),this.smartUpdate(t,n,s,e.length!==n.length)}function Br(t){return JSON.stringify(t)}function Vr(t){if(t===!0)return Br;if("string"==typeof t)return um[t]||(um[t]=function(e){return e[t]}),um[t];if("function"==typeof t)return t;throw Error("The `compare` option must be a function, or a string representing an identifying field (or `true` to use JSON.stringify)")}function qr(t,e){var n,a,r,i=void 0===arguments[2]?"default":arguments[2];e.isStatic||((n=this.mappings[t.firstKey])?n.register(t,e,i):(a=this.deps[i]||(this.deps[i]={}),r=a[t.str]||(a[t.str]=[]),r.push(e),this.depsMap[i]||(this.depsMap[i]={}),t.isRoot||Ur(this,t,i)))}function Ur(t,e,n){for(var a,r,i;!e.isRoot;)a=t.depsMap[n],r=a[e.parent.str]||(a[e.parent.str]=[]),i=e.str,void 0===r["_"+i]&&(r["_"+i]=0,r.push(e)),r["_"+i]+=1,e=e.parent}function Gr(){return this.captureGroups.pop()}function zr(t){this.data=t,this.clearCache("")}function Wr(t,e){var n,a,r,i,o=void 0===arguments[2]?{}:arguments[2];if(!o.noMapping&&(n=this.mappings[t.firstKey]))return n.set(t,e);if(a=this.computations[t.str]){if(a.setting)return;a.set(e),e=a.get()}s(this.cache[t.str],e)||(r=this.wrapped[t.str],r&&r.reset&&(i=r.reset(e)!==!1,i&&(e=r.get())),a||i||Hr(this,t,e),o.silent?this.clearCache(t.str):this.mark(t))}function Hr(t,e,n){var a,r,i,o;i=function(){a.set?a.set(e.lastKey,n):(r=a.get(),o())},o=function(){r||(r=Fh(e.lastKey),t.set(e.parent,r,{silent:!0})),r[e.lastKey]=n},a=t.wrapped[e.parent.str],a?i():(r=t.get(e.parent),(a=t.wrapped[e.parent.str])?i():o())}function Kr(t,e,n){var a,r,i,o=this;if(r=n.length,n.forEach(function(e,n){-1===e&&o.mark(t.join(n),gm)}),this.set(t,e,{silent:!0}),(a=this.deps["default"][t.str])&&a.filter(Qr).forEach(function(t){return t.shuffle(n,e)}),r!==e.length){for(this.mark(t.join("length"),mm),i=n.touchedFrom;ii;i+=1)this.mark(t.join(i),gm)}}function Qr(t){return"function"==typeof t.shuffle}function Yr(){var t,e=this;for(Object.keys(this.cache).forEach(function(t){return e.clearCache(t)});t=this.unresolvedImplicitDependencies.pop();)t.teardown()}function $r(t,e){var n,a,r,i=void 0===arguments[2]?"default":arguments[2];if(!e.isStatic){if(n=this.mappings[t.firstKey])return n.unregister(t,e,i);if(a=this.deps[i][t.str],r=a.indexOf(e),-1===r)throw Error("Attempted to remove a dependant that was no longer registered! This should not happen. If you are seeing this bug in development please raise an issue at https://github.com/RactiveJS/Ractive/issues - thanks");a.splice(r,1),t.isRoot||Jr(this,t,i)}}function Jr(t,e,n){for(var a,r;!e.isRoot;)a=t.depsMap[n],r=a[e.parent.str],r["_"+e.str]-=1,r["_"+e.str]||(N(r,e),r["_"+e.str]=void 0),e=e.parent}function Xr(t){this.hook=new is(t),this.inProcess={},this.queue={}}function Zr(t,e){return t[e._guid]||(t[e._guid]=[])}function ti(t,e){var n=Zr(t.queue,e);for(t.hook.fire(e);n.length;)ti(t,n.shift());delete t.queue[e._guid]}function ei(t,e){var n,a={};for(n in e)a[n]=ni(t,n,e[n]);return a}function ni(t,e,n){var a,r;return"function"==typeof n&&(a=ri(n,t)),"string"==typeof n&&(a=ai(t,n)),"object"==typeof n&&("string"==typeof n.get?a=ai(t,n.get):"function"==typeof n.get?a=ri(n.get,t):l("`%s` computation must have a `get()` method",e),
"function"==typeof n.set&&(r=ri(n.set,t))),{getter:a,setter:r}}function ai(t,e){var n,a,r;return n="return ("+e.replace(km,function(t,e){return a=!0,'__ractive.get("'+e+'")'})+");",a&&(n="var __ractive = this; "+n),r=Function(n),a?r.bind(t):r}function ri(t,e){return/this/.test(""+t)?t.bind(e):t}function ii(e){var n,r,i=void 0===arguments[1]?{}:arguments[1],o=void 0===arguments[2]?{}:arguments[2];if(Mg.DEBUG&&Ro(),pi(e,o),Eo(e,"data",{get:ui}),Sm.fire(e,i),Am.forEach(function(t){e[t]=a(So(e.constructor[t]||null),i[t])}),r=new _m({adapt:oi(e,e.adapt,i),data:Wp.init(e.constructor,e,i),computed:wm(e,a(So(e.constructor.prototype.computed),i.computed)),mappings:o.mappings,ractive:e,onchange:function(){return bs.addRactive(e)}}),e.viewmodel=r,r.init(),uu.init(e.constructor,e,i),Em.fire(e),Cm.begin(e),e.template){var s=void 0;(o.cssIds||e.cssId)&&(s=o.cssIds?o.cssIds.slice():[],e.cssId&&s.push(e.cssId)),e.fragment=new rg({template:e.template,root:e,owner:e,cssIds:s})}if(Cm.end(e),n=t(e.el)){var p=e.render(n,e.append);Mg.DEBUG_PROMISES&&p["catch"](function(t){throw g("Promise debugging is enabled, to help solve errors that happen asynchronously. Some browsers will log unhandled promise rejections, in which case you can safely disable promise debugging:\n Ractive.DEBUG_PROMISES = false;"),m("An error happened during rendering",{ractive:e}),t.stack&&d(t.stack),t})}}function oi(t,e,n){function a(e){return"string"==typeof e&&(e=v("adaptors",t,e),e||l(Io(e,"adaptor"))),e}var r,i,o;if(e=e.map(a),r=j(n.adapt).map(a),r=si(e,r),i="magic"in n?n.magic:t.magic,o="modifyArrays"in n?n.modifyArrays:t.modifyArrays,i){if(!eo)throw Error("Getters and setters (magic mode) are not supported in this browser");o&&r.push(qh),r.push(Vh)}return o&&r.push(Dh),r}function si(t,e){for(var n=t.slice(),a=e.length;a--;)~n.indexOf(e[a])||n.push(e[a]);return n}function pi(t,e){t._guid="r-"+Pm++,t._subs=So(null),t._config={},t._twowayBindings=So(null),t._animations=[],t.nodes={},t._liveQueries=[],t._liveComponentQueries=[],t._boundFunctions=[],t._observers=[],e.component?(t.parent=e.parent,t.container=e.container||null,t.root=t.parent.root,t.component=e.component,e.component.instance=t,t._inlinePartials=e.inlinePartials):(t.root=t,t.parent=t.container=null)}function ui(){throw Error("Using `ractive.data` is no longer supported - you must use the `ractive.get()` API instead")}function ci(t,e,n){this.parentFragment=t.parentFragment,this.callback=n,this.fragment=new rg({template:e,root:t.root,owner:this}),this.update()}function li(t,e,n){var a;return e.r?a=Rc(t,e.r,n):e.x?a=new Dc(t,t.parentFragment,e.x,n):e.rx&&(a=new Bc(t,e.rx,n)),a}function di(t){return 1===t.length&&t[0].t===Su}function fi(t,e){var n;for(n in e)e.hasOwnProperty(n)&&hi(t.instance,t.root,n,e[n])}function hi(t,e,n,a){"string"!=typeof a&&l("Components currently only support simple events - you cannot include arguments. Sorry!"),t.on(n,function(){var t,n;return arguments.length&&arguments[0]&&arguments[0].node&&(t=Array.prototype.shift.call(arguments)),n=Array.prototype.slice.call(arguments),zs(e,a,{event:t,args:n}),!1})}function mi(t,e){var n,a;if(!e)throw Error('Component "'+this.name+'" not found');n=this.parentFragment=t.parentFragment,a=n.root,this.root=a,this.type=Ru,this.name=t.template.e,this.index=t.index,this.indexRefBindings={},this.yielders={},this.resolvers=[],Rm(this,e,t.template.a,t.template.f,t.template.p),Mm(this,t.template.v),(t.template.t0||t.template.t1||t.template.t2||t.template.o)&&m('The "intro", "outro" and "decorator" directives have no effect on components',{ractive:this.instance}),Lm(this)}function gi(t,e){function n(n){n.rebind(t,e)}var a;this.resolvers.forEach(n);for(var r in this.yielders)this.yielders[r][0]&&n(this.yielders[r][0]);(a=this.root._liveComponentQueries["_"+this.name])&&a._makeDirty()}function vi(){var t=this.instance;return t.render(this.parentFragment.getNode()),this.rendered=!0,t.fragment.detach()}function bi(){return""+this.instance.fragment}function yi(){var t=this.instance;this.resolvers.forEach(K),_i(this),t._observers.forEach(Y),t.fragment.unbind(),t.viewmodel.teardown(),t.fragment.rendered&&t.el.__ractive_instances__&&N(t.el.__ractive_instances__,t),Bm.fire(t)}function _i(t){var e,n;e=t.root;do(n=e._liveComponentQueries["_"+t.name])&&n._remove(t);while(e=e.parent)}function xi(t){this.shouldDestroy=t,this.instance.unrender()}function wi(t){var e=this;this.owner=t.owner,this.parent=this.owner.parentFragment,this.root=t.root,this.pElement=t.pElement,this.context=t.context,this.index=t.index,this.key=t.key,this.registeredIndexRefs=[],this.cssIds="cssIds"in t?t.cssIds:this.parent?this.parent.cssIds:null,this.items=t.template.map(function(n,a){return ki({parentFragment:e,pElement:t.pElement,template:n,index:a})}),this.value=this.argsList=null,this.dirtyArgs=this.dirtyValue=!0,this.bound=!0}function ki(t){if("string"==typeof t.template)return new yc(t);switch(t.template.t){case Mu:return new Hm(t);case Su:return new Wc(t);case Cu:return new ll(t);case Eu:return new Ol(t);case Pu:var e=void 0;return(e=vh(t.parentFragment.root,t.template.e))?new Um(t,e):new ih(t);case Au:return new gh(t);case Ou:return new zm(t);case Lu:return new Qm(t);default:throw Error("Something very strange happened. Please file an issue at https://github.com/ractivejs/ractive/issues. Thanks!")}}function Si(t,e){(!this.owner||this.owner.hasContext)&&w(this,"context",t,e),this.items.forEach(function(n){n.rebind&&n.rebind(t,e)})}function Ei(){var t;return 1===this.items.length?t=this.items[0].render():(t=document.createDocumentFragment(),this.items.forEach(function(e){t.appendChild(e.render())})),this.rendered=!0,t}function Ci(t){return this.items?this.items.map(t?Ai:Pi).join(""):""}function Pi(t){return""+t}function Ai(t){return t.toString(!0)}function Oi(){this.bound&&(this.items.forEach(Ti),this.bound=!1)}function Ti(t){t.unbind&&t.unbind()}function Ri(t){if(!this.rendered)throw Error("Attempted to unrender a fragment that was not rendered");this.items.forEach(function(e){return e.unrender(t)}),this.rendered=!1}function Mi(t){var e,n,a,r,i;if(t=t||{},"object"!=typeof t)throw Error("The reset method takes either no arguments, or an object containing new data");for((n=this.viewmodel.wrapped[""])&&n.reset?n.reset(t)===!1&&this.viewmodel.reset(t):this.viewmodel.reset(t),a=uu.reset(this),r=a.length;r--;)if(og.indexOf(a[r])>-1){i=!0;break}if(i){var o=void 0;this.viewmodel.mark($o),(o=this.component)&&(o.shouldDestroy=!0),this.unrender(),o&&(o.shouldDestroy=!1),this.fragment.template!==this.template&&(this.fragment.unbind(),this.fragment=new rg({template:this.template,root:this,owner:this})),e=this.render(this.el,this.anchor)}else e=bs.start(this,!0),this.viewmodel.mark($o),bs.end();return sg.fire(this,t),e}function Li(t){var e,n;Jp.init(null,this,{template:t}),e=this.transitionsEnabled,this.transitionsEnabled=!1,(n=this.component)&&(n.shouldDestroy=!0),this.unrender(),n&&(n.shouldDestroy=!1),this.fragment.unbind(),this.fragment=new rg({template:this.template,root:this,owner:this}),this.render(this.el,this.anchor),this.transitionsEnabled=e}function ji(t,e){var n,a;if(a=bs.start(this,!0),u(t)){n=t;for(t in n)n.hasOwnProperty(t)&&(e=n[t],Di(this,t,e))}else Di(this,t,e);return bs.end(),a}function Di(t,e,n){e=S(P(e)),e.isPattern?E(t,e).forEach(function(e){t.viewmodel.set(e,n)}):t.viewmodel.set(e,n)}function Ni(t,e){return Jo(this,t,void 0===e?-1:-e)}function Fi(){var t;return this.fragment.unbind(),this.viewmodel.teardown(),this._observers.forEach(Y),this.fragment.rendered&&this.el.__ractive_instances__&&N(this.el.__ractive_instances__,this),this.shouldDestroy=!0,t=this.fragment.rendered?this.unrender():us.resolve(),vg.fire(this),this._boundFunctions.forEach(Ii),t}function Ii(t){delete t.fn[t.prop]}function Bi(t){var e=this;if("string"!=typeof t)throw new TypeError(No);var n=void 0;return/\*/.test(t)?(n={},E(this,S(P(t))).forEach(function(t){n[t.str]=!e.viewmodel.get(t)}),this.set(n)):this.set(t,!this.get(t))}function Vi(){return this.fragment.toString(!0)}function qi(){var t,e;if(!this.fragment.rendered)return m("ractive.unrender() was called on a Ractive instance that was not rendered"),us.resolve();for(t=bs.start(this,!0),e=!this.component||this.component.shouldDestroy||this.shouldDestroy;this._animations[0];)this._animations[0].stop();return this.fragment.unrender(e),N(this.el.__ractive_instances__,this),xg.fire(this),bs.end(),t}function Ui(t){var e;return t=S(t)||$o,e=bs.start(this,!0),this.viewmodel.mark(t),bs.end(),Sg.fire(this,t),e}function Gi(t,e){var n,a,r;if("string"!=typeof t||e){r=[];for(a in this._twowayBindings)(!t||S(a).equalsOrStartsWith(t))&&r.push.apply(r,this._twowayBindings[a])}else r=this._twowayBindings[t];return n=zi(this,r),this.set(n)}function zi(t,e){var n={},a=[];return e.forEach(function(t){var e,r;if(!t.radioName||t.element.node.checked){if(t.checkboxName)return void(a[t.keypath.str]||t.changed()||(a.push(t.keypath),a[t.keypath.str]=t));e=t.attribute.value,r=t.getValue(),L(e,r)||s(e,r)||(n[t.keypath.str]=r)}}),a.length&&a.forEach(function(t){var e,r,i;e=a[t.str],r=e.attribute.value,i=e.getValue(),L(r,i)||(n[t.str]=i)}),n}function Wi(t,e){return"function"==typeof e&&/_super/.test(t)}function Hi(t){for(var e={};t;)Ki(t,e),Yi(t,e),t=t._Parent!==Mg?t._Parent:!1;return e}function Ki(t,e){ru.forEach(function(n){Qi(n.useDefaults?t.prototype:t,e,n.name)})}function Qi(t,e,n){var a,r=Object.keys(t[n]);r.length&&((a=e[n])||(a=e[n]={}),r.filter(function(t){return!(t in a)}).forEach(function(e){return a[e]=t[n][e]}))}function Yi(t,e){Object.keys(t.prototype).forEach(function(n){if("computed"!==n){var a=t.prototype[n];if(n in e){if("function"==typeof e[n]&&"function"==typeof a&&e[n]._method){var r=void 0,i=a._method;i&&(a=a._method),r=Pg(e[n]._method,a),i&&(r._method=r),e[n]=r}}else e[n]=a._method?a._method:a}})}function $i(){for(var t=arguments.length,e=Array(t),n=0;t>n;n++)e[n]=arguments[n];return e.length?e.reduce(Ji,this):Ji(this)}function Ji(t){var e,n,r=void 0===arguments[1]?{}:arguments[1];return r.prototype instanceof Mg&&(r=Ag(r)),e=function(t){return this instanceof e?void Om(this,t):new e(t)},n=So(t.prototype),n.constructor=e,Co(e,{defaults:{value:n},extend:{value:$i,writable:!0,configurable:!0},_Parent:{value:t}}),uu.extend(t,n,r),Wp.extend(t,n,r),r.computed&&(n.computed=a(So(t.prototype.computed),r.computed)),e.prototype=n,e}var Xi,Zi,to,eo,no,ao,ro,io=3,oo={el:void 0,append:!1,template:{v:io,t:[]},preserveWhitespace:!1,sanitize:!1,stripComments:!0,delimiters:["{{","}}"],tripleDelimiters:["{{{","}}}"],interpolate:!1,data:{},computed:{},magic:!1,modifyArrays:!0,adapt:[],isolated:!1,twoway:!0,lazy:!1,noIntro:!1,transitionsEnabled:!0,complete:void 0,css:null,noCssTransform:!1},so=oo,po={linear:function(t){return t},easeIn:function(t){return Math.pow(t,3)},easeOut:function(t){return Math.pow(t-1,3)+1},easeInOut:function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)}};Xi="object"==typeof document,Zi="undefined"!=typeof navigator&&/jsDom/.test(navigator.appName),to="undefined"!=typeof console&&"function"==typeof console.warn&&"function"==typeof console.warn.apply;try{Object.defineProperty({},"test",{value:0}),eo=!0}catch(uo){eo=!1}no={html:"http://www.w3.org/1999/xhtml",mathml:"http://www.w3.org/1998/Math/MathML",svg:"http://www.w3.org/2000/svg",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},ao="undefined"==typeof document?!1:document&&document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1"),ro=["o","ms","moz","webkit"];var co,lo,fo,ho,mo,go,vo,bo,yo;if(co=ao?function(t,e){return e&&e!==no.html?document.createElementNS(e,t):document.createElement(t)}:function(t,e){if(e&&e!==no.html)throw"This browser does not support namespaces other than http://www.w3.org/1999/xhtml. The most likely cause of this error is that you're trying to render SVG in an older browser. See http://docs.ractivejs.org/latest/svg-and-older-browsers for more information";return document.createElement(t)},Xi){for(fo=co("div"),ho=["matches","matchesSelector"],yo=function(t){return function(e,n){return e[t](n)}},vo=ho.length;vo--&&!lo;)if(mo=ho[vo],fo[mo])lo=yo(mo);else for(bo=ro.length;bo--;)if(go=ro[vo]+mo.substr(0,1).toUpperCase()+mo.substring(1),fo[go]){lo=yo(go);break}lo||(lo=function(t,e){var n,a,r;for(a=t.parentNode,a||(fo.innerHTML="",a=fo,t=t.cloneNode(),fo.appendChild(t)),n=a.querySelectorAll(e),r=n.length;r--;)if(n[r]===t)return!0;return!1})}else lo=null;var _o,xo,wo,ko=function(){};"undefined"==typeof window?wo=null:(_o=window,xo=_o.document,wo={},xo||(wo=null),Date.now||(Date.now=function(){return+new Date}),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+/,"").replace(/\s+$/,"")}),Object.keys||(Object.keys=function(){var t=Object.prototype.hasOwnProperty,e=!{toString:null}.propertyIsEnumerable("toString"),n=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],a=n.length;return function(r){if("object"!=typeof r&&"function"!=typeof r||null===r)throw new TypeError("Object.keys called on non-object");var i=[];for(var o in r)t.call(r,o)&&i.push(o);if(e)for(var s=0;a>s;s++)t.call(r,n[s])&&i.push(n[s]);return i}}()),Array.prototype.indexOf||(Array.prototype.indexOf=function(t,e){var n;for(void 0===e&&(e=0),0>e&&(e+=this.length),0>e&&(e=0),n=this.length;n>e;e++)if(this.hasOwnProperty(e)&&this[e]===t)return e;return-1}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){var n,a;for(n=0,a=this.length;a>n;n+=1)this.hasOwnProperty(n)&&t.call(e,this[n],n,this)}),Array.prototype.map||(Array.prototype.map=function(t,e){var n,a,r,i=this,o=[];for(i instanceof String&&(i=""+i,r=!0),n=0,a=i.length;a>n;n+=1)(i.hasOwnProperty(n)||r)&&(o[n]=t.call(e,i[n],n,i));return o}),"function"!=typeof Array.prototype.reduce&&(Array.prototype.reduce=function(t,e){var n,a,r,i;if("function"!=typeof t)throw new TypeError(t+" is not a function");for(r=this.length,i=!1,arguments.length>1&&(a=e,i=!0),n=0;r>n;n+=1)this.hasOwnProperty(n)?i&&(a=t(a,this[n],n,this)):(a=this[n],i=!0);if(!i)throw new TypeError("Reduce of empty array with no initial value");return a}),Array.prototype.filter||(Array.prototype.filter=function(t,e){var n,a,r=[];for(n=0,a=this.length;a>n;n+=1)this.hasOwnProperty(n)&&t.call(e,this[n],n,this)&&(r[r.length]=this[n]);return r}),Array.prototype.every||(Array.prototype.every=function(t,e){var n,a,r;if(null==this)throw new TypeError;if(n=Object(this),a=n.length>>>0,"function"!=typeof t)throw new TypeError;for(r=0;a>r;r+=1)if(r in n&&!t.call(e,n[r],r,n))return!1;return!0}),"function"!=typeof Function.prototype.bind&&(Function.prototype.bind=function(t){var e,n,a,r,i=[].slice;if("function"!=typeof this)throw new TypeError("Function.prototype.bind called on non-function");return e=i.call(arguments,1),n=this,a=function(){},r=function(){var r=this instanceof a&&t?this:t;return n.apply(r,e.concat(i.call(arguments)))},a.prototype=this.prototype,r.prototype=new a,r}),_o.addEventListener||!function(t,e){var n,a,r,i,o,s;t.appearsToBeIELessEqual8=!0,n=function(t,e){var n,a=this;for(n in t)a[n]=t[n];a.currentTarget=e,a.target=t.srcElement||e,a.timeStamp=+new Date,a.preventDefault=function(){t.returnValue=!1},a.stopPropagation=function(){t.cancelBubble=!0}},a=function(t,e){var a,r,i=this;a=i.listeners||(i.listeners=[]),r=a.length,a[r]=[e,function(t){e.call(i,new n(t,i))}],i.attachEvent("on"+t,a[r][1])},r=function(t,e){var n,a,r=this;if(r.listeners)for(n=r.listeners,a=n.length;a--;)n[a][0]===e&&r.detachEvent("on"+t,n[a][1])},t.addEventListener=e.addEventListener=a,t.removeEventListener=e.removeEventListener=r,"Element"in t?(t.Element.prototype.addEventListener=a,t.Element.prototype.removeEventListener=r):(s=e.createElement,e.createElement=function(t){var e=s(t);return e.addEventListener=a,e.removeEventListener=r,e},i=e.getElementsByTagName("head")[0],o=e.createElement("style"),i.insertBefore(o,i.firstChild))}(_o,xo),_o.getComputedStyle||(wo.getComputedStyle=function(){function t(n,a,r,i){var o,s=a[r],p=parseFloat(s),u=s.split(/\d/)[0];return isNaN(p)&&/^thin|medium|thick$/.test(s)&&(p=e(s),u=""),i=null!=i?i:/%|em/.test(u)&&n.parentElement?t(n.parentElement,n.parentElement.currentStyle,"fontSize",null):16,o="fontSize"==r?i:/width/i.test(r)?n.clientWidth:n.clientHeight,"em"==u?p*i:"in"==u?96*p:"pt"==u?96*p/72:"%"==u?p/100*o:p}function e(t){var e,n;return i[t]||(e=document.createElement("div"),e.style.display="block",e.style.position="fixed",e.style.width=e.style.height="0",e.style.borderRight=t+" solid black",document.getElementsByTagName("body")[0].appendChild(e),n=e.getBoundingClientRect(),i[t]=n.right-n.left),i[t]}function n(t,e){var n="border"==e?"Width":"",a=e+"Top"+n,r=e+"Right"+n,i=e+"Bottom"+n,o=e+"Left"+n;t[e]=(t[a]==t[r]==t[i]==t[o]?[t[a]]:t[a]==t[i]&&t[o]==t[r]?[t[a],t[r]]:t[o]==t[r]?[t[a],t[r],t[i]]:[t[a],t[r],t[i],t[o]]).join(" ")}function a(e){var a,r,i,s;a=e.currentStyle,r=this,i=t(e,a,"fontSize",null);for(s in a)"normal"===a[s]&&o.hasOwnProperty(s)?r[s]=o[s]:/width|height|margin.|padding.|border.+W/.test(s)?"auto"===a[s]?/^width|height/.test(s)?r[s]=("width"===s?e.clientWidth:e.clientHeight)+"px":/(?:padding)?Top|Bottom$/.test(s)&&(r[s]="0px"):r[s]=t(e,a,s,i)+"px":"styleFloat"===s?r["float"]=a[s]:r[s]=a[s];return n(r,"margin"),n(r,"padding"),n(r,"border"),r.fontSize=i+"px",r}function r(t){return new a(t)}var i={},o={fontWeight:400,lineHeight:1.2,letterSpacing:0};return a.prototype={constructor:a,getPropertyPriority:ko,getPropertyValue:function(t){return this[t]||""},item:ko,removeProperty:ko,setProperty:ko,getPropertyCSSValue:ko},r}()));var So,Eo,Co,Po=wo;try{Object.defineProperty({},"test",{value:0}),Xi&&Object.defineProperty(document.createElement("div"),"test",{value:0}),Eo=Object.defineProperty}catch(Ao){Eo=function(t,e,n){t[e]=n.value}}try{try{Object.defineProperties({},{test:{value:0}})}catch(Ao){throw Ao}Xi&&Object.defineProperties(co("div"),{test:{value:0}}),Co=Object.defineProperties}catch(Ao){Co=function(t,e){var n;for(n in e)e.hasOwnProperty(n)&&Eo(t,n,e[n])}}try{Object.create(null),So=Object.create}catch(Ao){So=function(){var t=function(){};return function(e,n){var a;return null===e?{}:(t.prototype=e,a=new t,n&&Object.defineProperties(a,n),a)}}()}var Oo,To,Ro,Mo=Object.prototype.hasOwnProperty,Lo=Object.prototype.toString,jo=/^\[object (?:Array|FileList)\]$/,Do={};to?!function(){var t=["%cRactive.js %c0.7.3 %cin debug mode, %cmore...","color: rgb(114, 157, 52); font-weight: normal;","color: rgb(85, 85, 85); font-weight: normal;","color: rgb(85, 85, 85); font-weight: normal;","color: rgb(82, 140, 224); font-weight: normal; text-decoration: underline;"],e="You're running Ractive 0.7.3 in debug mode - messages will be printed to the console to help you fix problems and optimise your application.\n\nTo disable debug mode, add this line at the start of your app:\n Ractive.DEBUG = false;\n\nTo disable debug mode when your app is minified, add this snippet:\n Ractive.DEBUG = /unminified/.test(function(){/*unminified*/});\n\nGet help and support:\n http://docs.ractivejs.org\n http://stackoverflow.com/questions/tagged/ractivejs\n http://groups.google.com/forum/#!forum/ractive-js\n http://twitter.com/ractivejs\n\nFound a bug? Raise an issue:\n https://github.com/ractivejs/ractive/issues\n\n";Ro=function(){var n=!!console.groupCollapsed;console[n?"groupCollapsed":"log"].apply(console,t),console.log(e),n&&console.groupEnd(t),Ro=ko},To=function(t,e){if(Ro(),"object"==typeof e[e.length-1]){var n=e.pop(),a=n?n.ractive:null;if(a){var r=void 0;a.component&&(r=a.component.name)&&(t="<"+r+"> "+t);var i=void 0;(i=n.node||a.fragment&&a.fragment.rendered&&a.find("*"))&&e.push(i)}}console.warn.apply(console,["%cRactive.js: %c"+t,"color: rgb(114, 157, 52);","color: rgb(85, 85, 85);"].concat(e))},Oo=function(){console.log.apply(console,arguments)}}():To=Oo=Ro=ko;var No="Bad arguments",Fo='A function was specified for "%s" %s, but no %s was returned',Io=function(t,e){return'Missing "'+t+'" '+e+" plugin. You may need to download a plugin via http://docs.ractivejs.org/latest/plugins#"+e+"s"},Bo=function(t,e,n,a){if(t===e)return y(e);if(a){var r=v("interpolators",n,a);if(r)return r(t,e)||y(e);l(Io(a,"interpolator"))}return Uo.number(t,e)||Uo.array(t,e)||Uo.object(t,e)||y(e)},Vo=Bo,qo={number:function(t,e){var n;return p(t)&&p(e)?(t=+t,e=+e,n=e-t,n?function(e){return t+e*n}:function(){return t}):null},array:function(t,e){var n,a,r,o;if(!i(t)||!i(e))return null;for(n=[],a=[],o=r=Math.min(t.length,e.length);o--;)a[o]=Vo(t[o],e[o]);for(o=r;o=this.duration?(null!==i&&(bs.start(this.root),this.root.viewmodel.set(i,this.to),bs.end()),this.step&&this.step(1,this.to),this.complete(this.to),r=this.root._animations.indexOf(this),-1===r&&m("Animation was not found"),this.root._animations.splice(r,1),this.running=!1,!1):(e=this.easing?this.easing(t/this.duration):t/this.duration,null!==i&&(n=this.interpolator(e),bs.start(this.root),this.root.viewmodel.set(i,n),bs.end()),this.step&&this.step(e,n),!0)):!1},stop:function(){var t;this.running=!1,t=this.root._animations.indexOf(this),-1===t&&m("Animation was not found"),this.root._animations.splice(t,1)}};var ks=ws,Ss=nt,Es={stop:ko},Cs=rt,Ps=new is("detach"),As=it,Os=ot,Ts=function(){var t,e,n;t=this._root[this._isComponentQuery?"liveComponentQueries":"liveQueries"],e=this.selector,n=t.indexOf(e),-1!==n&&(t.splice(n,1),t[e]=null)},Rs=function(t,e){var n,a,r,i,o,s,p,u,c,l;for(n=pt(t.component||t._ractive.proxy),a=pt(e.component||e._ractive.proxy),r=D(n),i=D(a);r&&r===i;)n.pop(),a.pop(),o=r,r=D(n),i=D(a);if(r=r.component||r,i=i.component||i,c=r.parentFragment,l=i.parentFragment,c===l)return s=c.items.indexOf(r),p=l.items.indexOf(i),s-p||n.length-a.length;if(u=o.fragments)return s=u.indexOf(c),p=u.indexOf(l),s-p||n.length-a.length;throw Error("An unexpected condition was met while comparing the position of two components. Please file an issue at https://github.com/RactiveJS/Ractive/issues - thanks!")},Ms=function(t,e){var n;return t.compareDocumentPosition?(n=t.compareDocumentPosition(e),2&n?1:-1):Rs(t,e)},Ls=function(){this.sort(this._isComponentQuery?Rs:Ms),this._dirty=!1},js=function(){var t=this;this._dirty||(this._dirty=!0,bs.scheduleTask(function(){t._sort()}))},Ds=function(t){var e=this.indexOf(this._isComponentQuery?t.instance:t);-1!==e&&this.splice(e,1)},Ns=ut,Fs=ct,Is=lt,Bs=dt,Vs=ft,qs=ht,Us={enqueue:function(t,e){t.event&&(t._eventQueue=t._eventQueue||[],t._eventQueue.push(t.event)),t.event=e},dequeue:function(t){t._eventQueue&&t._eventQueue.length?t.event=t._eventQueue.pop():delete t.event}},Gs=Us,zs=mt,Ws=bt,Hs=yt,Ks={capture:!0,noUnwrap:!0,fullRootGet:!0},Qs=_t,Ys=new is("insert"),$s=wt,Js=function(t,e,n,a){this.root=t,this.keypath=e,this.callback=n,this.defer=a.defer,this.context=a&&a.context?a.context:t};Js.prototype={init:function(t){this.value=this.root.get(this.keypath.str),t!==!1?this.update():this.oldValue=this.value},setValue:function(t){var e=this;s(t,this.value)||(this.value=t,this.defer&&this.ready?bs.scheduleTask(function(){return e.update()}):this.update())},update:function(){this.updating||(this.updating=!0,this.callback.call(this.context,this.value,this.oldValue,this.keypath.str),this.oldValue=this.value,this.updating=!1)}};var Xs,Zs=Js,tp=kt,ep=Array.prototype.slice;Xs=function(t,e,n,a){this.root=t,this.callback=n,this.defer=a.defer,this.keypath=e,this.regex=RegExp("^"+e.str.replace(/\./g,"\\.").replace(/\*/g,"([^\\.]+)")+"$"),this.values={},this.defer&&(this.proxies=[]),this.context=a&&a.context?a.context:t},Xs.prototype={init:function(t){var e,n;if(e=tp(this.root,this.keypath),t!==!1)for(n in e)e.hasOwnProperty(n)&&this.update(S(n));else this.values=e},update:function(t){var e,n=this;if(t.isPattern){e=tp(this.root,t);for(t in e)e.hasOwnProperty(t)&&this.update(S(t))}else if(!this.root.viewmodel.implicitChanges[t.str])return this.defer&&this.ready?void bs.scheduleTask(function(){return n.getProxy(t).update()}):void this.reallyUpdate(t)},reallyUpdate:function(t){var e,n,a,r;return e=t.str,n=this.root.viewmodel.get(t),this.updating?void(this.values[e]=n):(this.updating=!0,s(n,this.values[e])&&this.ready||(a=ep.call(this.regex.exec(e),1),r=[n,this.values[e],e].concat(a),this.values[e]=n,this.callback.apply(this.context,r)),void(this.updating=!1))},getProxy:function(t){var e=this;return this.proxies[t.str]||(this.proxies[t.str]={update:function(){return e.reallyUpdate(t)}}),this.proxies[t.str]}};var np,ap,rp,ip,op,sp,pp=Xs,up=St,cp={},lp=Et,dp=Ct,fp=function(t){return t.trim()},hp=function(t){return""!==t},mp=Pt,gp=At,vp=Ot,bp=Tt,yp=Array.prototype,_p=function(t){return function(e){for(var n=arguments.length,a=Array(n>1?n-1:0),r=1;n>r;r++)a[r-1]=arguments[r];var o,s,p,u,c=[];if(e=S(P(e)),o=this.viewmodel.get(e),s=o.length,!i(o))throw Error("Called ractive."+t+"('"+e.str+"'), but '"+e.str+"' does not refer to an array");return c=bp(o,t,a),u=yp[t].apply(o,a),p=bs.start(this,!0).then(function(){return u}),c?this.viewmodel.smartUpdate(e,o,c):this.viewmodel.mark(e),bs.end(),p}},xp=_p("pop"),wp=_p("push"),kp="/* Ractive.js component styles */\n",Sp=[],Ep=!1;Xi?(rp=document.createElement("style"),rp.type="text/css",ip=document.getElementsByTagName("head")[0],sp=!1,op=rp.styleSheet,ap=function(){var t=kp+Sp.map(function(t){return"\n/* {"+t.id+"} */\n"+t.styles}).join("\n");op?op.cssText=t:rp.innerHTML=t,sp||(ip.appendChild(rp),sp=!0)},np={add:function(t){Sp.push(t),Ep=!0},apply:function(){Ep&&(ap(),Ep=!1)}}):np={add:ko,apply:ko};var Cp,Pp,Ap,Op=np,Tp=Mt,Rp=new is("render"),Mp=new is("complete"),Lp={extend:function(t,e,n){e.adapt=jt(e.adapt,j(n.adapt))},init:function(){}},jp=Lp,Dp=Dt,Np=/(?:^|\})?\s*([^\{\}]+)\s*\{/g,Fp=/\/\*.*?\*\//g,Ip=/((?:(?:\[[^\]+]\])|(?:[^\s\+\>\~:]))+)((?::[^\s\+\>\~\(]+(?:\([^\)]+\))?)?\s*[\s\+\>\~]?)\s*/g,Bp=/^@media/,Vp=/\[data-ractive-css~="\{[a-z0-9-]+\}"]/g,qp=1,Up={
name:"css",extend:function(t,e,n){if(n.css){var a=qp++,r=n.noCssTransform?n.css:Dp(n.css,a);e.cssId=a,Op.add({id:a,styles:r})}},init:function(){}},Gp=Up,zp={name:"data",extend:function(t,e,n){var a=void 0,r=void 0;if(n.data&&u(n.data))for(a in n.data)r=n.data[a],r&&"object"==typeof r&&(u(r)||i(r))&&m("Passing a `data` option with object and array properties to Ractive.extend() is discouraged, as mutating them is likely to cause bugs. Consider using a data function instead:\n\n // this...\n data: function () {\n return {\n myObject: {}\n };\n })\n\n // instead of this:\n data: {\n myObject: {}\n }");e.data=Bt(e.data,n.data)},init:function(t,e,n){var a=Bt(t.prototype.data,n.data);return"function"==typeof a&&(a=a.call(e)),a||{}},reset:function(t){var e=this.init(t.constructor,t,t.viewmodel);return t.viewmodel.reset(e),!0}},Wp=zp,Hp=null,Kp=["preserveWhitespace","sanitize","stripComments","delimiters","tripleDelimiters","interpolate"],Qp={fromId:zt,isHashedId:Wt,isParsed:Ht,getParseOptions:Kt,createHelper:Ut,parse:Gt},Yp=Qp,$p={name:"template",extend:function(t,e,n){var a;"template"in n&&(a=n.template,"function"==typeof a?e.template=a:e.template=Jt(a,e))},init:function(t,e,n){var a,r;a="template"in n?n.template:t.prototype.template,"function"==typeof a&&(r=a,a=Yt(e,r),e._config.template={fn:r,result:a}),a=Jt(a,e),e.template=a.t,a.p&&Xt(e.partials,a.p)},reset:function(t){var e,n=Qt(t);return n?(e=Jt(n,t),t.template=e.t,Xt(t.partials,e.p,!0),!0):void 0}},Jp=$p;Cp=["adaptors","components","computed","decorators","easing","events","interpolators","partials","transitions"],Pp=function(t,e){this.name=t,this.useDefaults=e},Pp.prototype={constructor:Pp,extend:function(t,e,n){this.configure(this.useDefaults?t.defaults:t,this.useDefaults?e:e.constructor,n)},init:function(){},configure:function(t,e,n){var a,r=this.name,i=n[r];a=So(t[r]);for(var o in i)a[o]=i[o];e[r]=a},reset:function(t){var e=t[this.name],n=!1;return Object.keys(e).forEach(function(t){var a=e[t];a._fn&&(a._fn.isOwner?e[t]=a._fn:delete e[t],n=!0)}),n}},Ap=Cp.map(function(t){return new Pp(t,"computed"===t)});var Xp,Zp,tu,eu,nu,au,ru=Ap,iu=Zt,ou=ae;eu={adapt:jp,css:Gp,data:Wp,template:Jp},tu=Object.keys(so),au=oe(tu.filter(function(t){return!eu[t]})),nu=oe(tu.concat(ru.map(function(t){return t.name}))),Zp=[].concat(tu.filter(function(t){return!ru[t]&&!eu[t]}),ru,eu.data,eu.template,eu.css),Xp={extend:function(t,e,n){return re("extend",t,e,n)},init:function(t,e,n){return re("init",t,e,n)},reset:function(t){return Zp.filter(function(e){return e.reset&&e.reset(t)}).map(function(t){return t.name})},order:Zp};var su,pu,uu=Xp,cu=se,lu=pe,du=ue,fu=ce,hu=le,mu=de,gu=fe,vu=he,bu=/^\s+/;pu=function(t){this.name="ParseError",this.message=t;try{throw Error(t)}catch(e){this.stack=e.stack}},pu.prototype=Error.prototype,su=function(t,e){var n,a,r=0;for(this.str=t,this.options=e||{},this.pos=0,this.lines=this.str.split("\n"),this.lineEnds=this.lines.map(function(t){var e=r+t.length+1;return r=e,e},0),this.init&&this.init(t,e),n=[];this.posn;n+=1)if(this.pos=e,r=t[n](this))return r;return null},getLinePos:function(t){for(var e,n=0,a=0;t>=this.lineEnds[n];)a=this.lineEnds[n],n+=1;return e=t-a,[n+1,e+1,t]},error:function(t){var e=this.getLinePos(this.pos),n=e[0],a=e[1],r=this.lines[e[0]-1],i=0,o=r.replace(/\t/g,function(t,n){return n /g,lc=/&/g;var vc=function(){return e(this.node)},bc=function(t){this.type=ku,this.text=t.template};bc.prototype={detach:vc,firstNode:function(){return this.node},render:function(){return this.node||(this.node=document.createTextNode(this.text)),this.node},toString:function(t){return t?Se(this.text):this.text},unrender:function(t){return t?this.detach():void 0}};var yc=bc,_c=Ee,xc=Ce,wc=function(t,e,n){var a;this.ref=e,this.resolved=!1,this.root=t.root,this.parentFragment=t.parentFragment,this.callback=n,a=ls(t.root,e,t.parentFragment),void 0!=a?this.resolve(a):bs.addUnresolved(this)};wc.prototype={resolve:function(t){this.keypath&&!t&&bs.addUnresolved(this),this.resolved=!0,this.keypath=t,this.callback(t)},forceResolution:function(){this.resolve(S(this.ref))},rebind:function(t,e){var n;void 0!=this.keypath&&(n=this.keypath.replace(t,e),void 0!==n&&this.resolve(n))},unbind:function(){this.resolved||bs.removeUnresolved(this)}};var kc=wc,Sc=function(t,e,n){this.parentFragment=t.parentFragment,this.ref=e,this.callback=n,this.rebind()},Ec={"@keypath":{prefix:"c",prop:["context"]},"@index":{prefix:"i",prop:["index"]},"@key":{prefix:"k",prop:["key","index"]}};Sc.prototype={rebind:function(){var t,e=this.ref,n=this.parentFragment,a=Ec[e];if(!a)throw Error('Unknown special reference "'+e+'" - valid references are @index, @key and @keypath');if(this.cached)return this.callback(S("@"+a.prefix+Pe(this.cached,a)));if(-1!==a.prop.indexOf("index")||-1!==a.prop.indexOf("key"))for(;n;){if(n.owner.currentSubtype===Bu&&void 0!==(t=Pe(n,a)))return this.cached=n,n.registerIndexRef(this),this.callback(S("@"+a.prefix+t));n=!n.parent&&n.owner&&n.owner.component&&n.owner.component.parentFragment&&!n.owner.component.instance.isolated?n.owner.component.parentFragment:n.parent}else for(;n;){if(void 0!==(t=Pe(n,a)))return this.callback(S("@"+a.prefix+t.str));n=n.parent}},unbind:function(){this.cached&&this.cached.unregisterIndexRef(this)}};var Cc=Sc,Pc=function(t,e,n){this.parentFragment=t.parentFragment,this.ref=e,this.callback=n,e.ref.fragment.registerIndexRef(this),this.rebind()};Pc.prototype={rebind:function(){var t,e=this.ref.ref;t="k"===e.ref.t?"k"+e.fragment.key:"i"+e.fragment.index,void 0!==t&&this.callback(S("@"+t))},unbind:function(){this.ref.ref.fragment.unregisterIndexRef(this)}};var Ac=Pc,Oc=Ae;Ae.resolve=function(t){var e,n,a={};for(e in t.refs)n=t.refs[e],a[n.ref.n]="k"===n.ref.t?n.fragment.key:n.fragment.index;return a};var Tc,Rc=Oe,Mc=Te,Lc={},jc=Function.prototype.bind;Tc=function(t,e,n,a){var r,i=this;r=t.root,this.root=r,this.parentFragment=e,this.callback=a,this.owner=t,this.str=n.s,this.keypaths=[],this.pending=n.r.length,this.refResolvers=n.r.map(function(t,e){return Rc(i,t,function(t){i.resolve(e,t)})}),this.ready=!0,this.bubble()},Tc.prototype={bubble:function(){this.ready&&(this.uniqueString=Me(this.str,this.keypaths),this.keypath=Le(this.uniqueString),this.createEvaluator(),this.callback(this.keypath))},unbind:function(){for(var t;t=this.refResolvers.pop();)t.unbind()},resolve:function(t,e){this.keypaths[t]=e,this.bubble()},createEvaluator:function(){var t,e,n,a,r,i=this;a=this.keypath,t=this.root.viewmodel.computations[a.str],t?this.root.viewmodel.mark(a):(r=Mc(this.str,this.refResolvers.length),e=this.keypaths.map(function(t){var e;return"undefined"===t?function(){}:t.isSpecial?(e=t.value,function(){return e}):function(){var e=i.root.viewmodel.get(t,{noUnwrap:!0,fullRootGet:!0});return"function"==typeof e&&(e=De(e,i.root)),e}}),n={deps:this.keypaths.filter(je),getter:function(){var t=e.map(Re);return r.apply(null,t)}},t=this.root.viewmodel.compute(a,n))},rebind:function(t,e){this.refResolvers.forEach(function(n){return n.rebind(t,e)})}};var Dc=Tc,Nc=function(t,e,n){var a=this;this.resolver=e,this.root=e.root,this.parentFragment=n,this.viewmodel=e.root.viewmodel,"string"==typeof t?this.value=t:t.t===Nu?this.refResolver=Rc(this,t.n,function(t){a.resolve(t)}):new Dc(e,n,t,function(t){a.resolve(t)})};Nc.prototype={resolve:function(t){this.keypath&&this.viewmodel.unregister(this.keypath,this),this.keypath=t,this.value=this.viewmodel.get(t),this.bind(),this.resolver.bubble()},bind:function(){this.viewmodel.register(this.keypath,this)},rebind:function(t,e){this.refResolver&&this.refResolver.rebind(t,e)},setValue:function(t){this.value=t,this.resolver.bubble()},unbind:function(){this.keypath&&this.viewmodel.unregister(this.keypath,this),this.refResolver&&this.refResolver.unbind()},forceResolution:function(){this.refResolver&&this.refResolver.forceResolution()}};var Fc=Nc,Ic=function(t,e,n){var a,r,i,o,s=this;this.parentFragment=o=t.parentFragment,this.root=a=t.root,this.mustache=t,this.ref=r=e.r,this.callback=n,this.unresolved=[],(i=ls(a,r,o))?this.base=i:this.baseResolver=new kc(this,r,function(t){s.base=t,s.baseResolver=null,s.bubble()}),this.members=e.m.map(function(t){return new Fc(t,s,o)}),this.ready=!0,this.bubble()};Ic.prototype={getKeypath:function(){var t=this.members.map(Ne);return!t.every(Fe)||this.baseResolver?null:this.base.join(t.join("."))},bubble:function(){this.ready&&!this.baseResolver&&this.callback(this.getKeypath())},unbind:function(){this.members.forEach(K)},rebind:function(t,e){var n;if(this.base){var a=this.base.replace(t,e);a&&a!==this.base&&(this.base=a,n=!0)}this.members.forEach(function(a){a.rebind(t,e)&&(n=!0)}),n&&this.bubble()},forceResolution:function(){this.baseResolver&&(this.base=S(this.ref),this.baseResolver.unbind(),this.baseResolver=null),this.members.forEach(Ie),this.bubble()}};var Bc=Ic,Vc=Be,qc=Ve,Uc=qe,Gc={getValue:xc,init:Vc,resolve:qc,rebind:Uc},zc=function(t){this.type=Su,Gc.init(this,t)};zc.prototype={update:function(){this.node.data=void 0==this.value?"":this.value},resolve:Gc.resolve,rebind:Gc.rebind,detach:vc,unbind:_c,render:function(){return this.node||(this.node=document.createTextNode(n(this.value))),this.node},unrender:function(t){t&&e(this.node)},getValue:Gc.getValue,setValue:function(t){var e;this.keypath&&(e=this.root.viewmodel.wrapped[this.keypath.str])&&(t=e.get()),s(t,this.value)||(this.value=t,this.parentFragment.bubble(),this.node&&bs.addView(this))},firstNode:function(){return this.node},toString:function(t){var e=""+n(this.value);return t?Se(e):e}};var Wc=zc,Hc=Ue,Kc=Ge,Qc=ze,Yc=We,$c=He,Jc=Ke,Xc=Qe,Zc=Ye,tl=$e,el=function(t,e){Gc.rebind.call(this,t,e)},nl=Xe,al=Ze,rl=ln,il=dn,ol=fn,sl=gn,pl=function(t){this.type=Cu,this.subtype=this.currentSubtype=t.template.n,this.inverted=this.subtype===Iu,this.pElement=t.pElement,this.fragments=[],this.fragmentsToCreate=[],this.fragmentsToRender=[],this.fragmentsToUnrender=[],t.template.i&&(this.indexRefs=t.template.i.split(",").map(function(t,e){return{n:t,t:0===e?"k":"i"}})),this.renderedFragments=[],this.length=0,Gc.init(this,t)};pl.prototype={bubble:Hc,detach:Kc,find:Qc,findAll:Yc,findAllComponents:$c,findComponent:Jc,findNextNode:Xc,firstNode:Zc,getIndexRef:function(t){if(this.indexRefs)for(var e=this.indexRefs.length;e--;){var n=this.indexRefs[e];if(n.n===t)return n}},getValue:Gc.getValue,shuffle:tl,rebind:el,render:nl,resolve:Gc.resolve,setValue:al,toString:rl,unbind:il,unrender:ol,update:sl};var ul,cl,ll=pl,dl=vn,fl=bn,hl=yn,ml=_n,gl={};try{co("table").innerHTML="foo"}catch(Ao){ul=!0,cl={TABLE:['"],THEAD:['"],TBODY:['"],TR:['"],SELECT:[''," "]}}var vl=function(t,e,n){var a,r,i,o,s,p=[];if(null!=t&&""!==t){for(ul&&(r=cl[e.tagName])?(a=xn("DIV"),a.innerHTML=r[0]+t+r[1],a=a.querySelector(".x"),"SELECT"===a.tagName&&(i=a.options[a.selectedIndex])):e.namespaceURI===no.svg?(a=xn("DIV"),a.innerHTML=''+t+" ",a=a.querySelector(".x")):(a=xn(e.tagName),a.innerHTML=t,"SELECT"===a.tagName&&(i=a.options[a.selectedIndex]));o=a.firstChild;)p.push(o),n.appendChild(o);if("SELECT"===e.tagName)for(s=p.length;s--;)p[s]!==i&&(p[s].selected=!1)}return p},bl=wn,yl=Sn,_l=En,xl=Cn,wl=Pn,kl=An,Sl=function(t){this.type=Eu,Gc.init(this,t)};Sl.prototype={detach:dl,find:fl,findAll:hl,firstNode:ml,getValue:Gc.getValue,rebind:Gc.rebind,render:yl,resolve:Gc.resolve,setValue:_l,toString:xl,unbind:_c,unrender:wl,update:kl};var El,Cl,Pl,Al,Ol=Sl,Tl=function(){this.parentFragment.bubble()},Rl=On,Ml=function(t){return this.node?lo(this.node,t)?this.node:this.fragment&&this.fragment.find?this.fragment.find(t):void 0:null},Ll=function(t,e){e._test(this,!0)&&e.live&&(this.liveQueries||(this.liveQueries=[])).push(e),this.fragment&&this.fragment.findAll(t,e)},jl=function(t,e){this.fragment&&this.fragment.findAllComponents(t,e)},Dl=function(t){return this.fragment?this.fragment.findComponent(t):void 0},Nl=Tn,Fl=Rn,Il=Mn,Bl=/^true|on|yes|1$/i,Vl=/^[0-9]+$/,ql=function(t,e){var n,a,r;return r=e.a||{},a={},n=r.twoway,void 0!==n&&(a.twoway=0===n||Bl.test(n)),n=r.lazy,void 0!==n&&(0!==n&&Vl.test(n)?a.lazy=parseInt(n):a.lazy=0===n||Bl.test(n)),a},Ul=Ln;El="altGlyph altGlyphDef altGlyphItem animateColor animateMotion animateTransform clipPath feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDistantLight feFlood feFuncA feFuncB feFuncG feFuncR feGaussianBlur feImage feMerge feMergeNode feMorphology feOffset fePointLight feSpecularLighting feSpotLight feTile feTurbulence foreignObject glyphRef linearGradient radialGradient textPath vkern".split(" "),Cl="attributeName attributeType baseFrequency baseProfile calcMode clipPathUnits contentScriptType contentStyleType diffuseConstant edgeMode externalResourcesRequired filterRes filterUnits glyphRef gradientTransform gradientUnits kernelMatrix kernelUnitLength keyPoints keySplines keyTimes lengthAdjust limitingConeAngle markerHeight markerUnits markerWidth maskContentUnits maskUnits numOctaves pathLength patternContentUnits patternTransform patternUnits pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits refX refY repeatCount repeatDur requiredExtensions requiredFeatures specularConstant specularExponent spreadMethod startOffset stdDeviation stitchTiles surfaceScale systemLanguage tableValues targetX targetY textLength viewBox viewTarget xChannelSelector yChannelSelector zoomAndPan".split(" "),Pl=function(t){for(var e={},n=t.length;n--;)e[t[n].toLowerCase()]=t[n];return e},Al=Pl(El.concat(Cl));var Gl=function(t){var e=t.toLowerCase();return Al[e]||e},zl=function(t,e){var n,a;if(n=e.indexOf(":"),-1===n||(a=e.substr(0,n),"xmlns"===a))t.name=t.element.namespace!==no.html?Gl(e):e;else if(e=e.substring(n+1),t.name=Gl(e),t.namespace=no[a.toLowerCase()],t.namespacePrefix=a,!t.namespace)throw'Unknown namespace ("'+a+'")'},Wl=jn,Hl=Dn,Kl=Nn,Ql=Fn,Yl={"accept-charset":"acceptCharset",accesskey:"accessKey",bgcolor:"bgColor","class":"className",codebase:"codeBase",colspan:"colSpan",contenteditable:"contentEditable",datetime:"dateTime",dirname:"dirName","for":"htmlFor","http-equiv":"httpEquiv",ismap:"isMap",maxlength:"maxLength",novalidate:"noValidate",pubdate:"pubDate",readonly:"readOnly",rowspan:"rowSpan",tabindex:"tabIndex",usemap:"useMap"},$l=In,Jl=Vn,Xl=qn,Zl=Un,td=Gn,ed=zn,nd=Wn,ad=Hn,rd=Kn,id=Qn,od=Yn,sd=$n,pd=Jn,ud=Xn,cd=Zn,ld=function(t){this.init(t)};ld.prototype={bubble:Ul,init:Hl,rebind:Kl,render:Ql,toString:$l,unbind:Jl,update:cd};var dd,fd=ld,hd=function(t,e){var n,a,r=[];for(n in e)"twoway"!==n&&"lazy"!==n&&e.hasOwnProperty(n)&&(a=new fd({element:t,name:n,value:e[n],root:t.root}),r[n]=a,"value"!==n&&r.push(a));return(a=r.value)&&r.push(a),r};"undefined"!=typeof document&&(dd=co("div"));var md=function(t,e){this.element=t,this.root=t.root,this.parentFragment=t.parentFragment,this.attributes=[],this.fragment=new rg({root:t.root,owner:this,template:[e]})};md.prototype={bubble:function(){this.node&&this.update(),this.element.bubble()},rebind:function(t,e){this.fragment.rebind(t,e)},render:function(t){this.node=t,this.isSvg=t.namespaceURI===no.svg,this.update()},unbind:function(){this.fragment.unbind()},update:function(){var t,e,n=this;t=""+this.fragment,e=ta(t,this.isSvg),this.attributes.filter(function(t){return ea(e,t)}).forEach(function(t){n.node.removeAttribute(t.name)}),e.forEach(function(t){n.node.setAttribute(t.name,t.value)}),this.attributes=e},toString:function(){return""+this.fragment}};var gd=md,vd=function(t,e){return e?e.map(function(e){return new gd(t,e)}):[]},bd=function(t){var e,n,a,r;if(this.element=t,this.root=t.root,this.attribute=t.attributes[this.name||"value"],e=this.attribute.interpolator,e.twowayBinding=this,n=e.keypath){if("}"===n.str.slice(-1))return g("Two-way binding does not work with expressions (`%s` on <%s>)",e.resolver.uniqueString,t.name,{ractive:this.root}),!1;if(n.isSpecial)return g("Two-way binding does not work with %s",e.resolver.ref,{ractive:this.root}),!1}else{var i=e.template.r?"'"+e.template.r+"' reference":"expression";m("The %s being used for two-way binding is ambiguous, and may cause unexpected results. Consider initialising your data to eliminate the ambiguity",i,{ractive:this.root}),e.resolver.forceResolution(),n=e.keypath}this.attribute.isTwoway=!0,this.keypath=n,a=this.root.viewmodel.get(n),void 0===a&&this.getInitialValue&&(a=this.getInitialValue(),void 0!==a&&this.root.viewmodel.set(n,a)),(r=na(t))&&(this.resetValue=a,r.formBindings.push(this))};bd.prototype={handleChange:function(){var t=this;bs.start(this.root),this.attribute.locked=!0,this.root.viewmodel.set(this.keypath,this.getValue()),bs.scheduleTask(function(){return t.attribute.locked=!1}),bs.end()},rebound:function(){var t,e,n;e=this.keypath,n=this.attribute.interpolator.keypath,e!==n&&(N(this.root._twowayBindings[e.str],this),this.keypath=n,t=this.root._twowayBindings[n.str]||(this.root._twowayBindings[n.str]=[]),t.push(this))},unbind:function(){}},bd.extend=function(t){var e,n=this;return e=function(t){bd.call(this,t),this.init&&this.init()},e.prototype=So(n.prototype),a(e.prototype,t),e.extend=bd.extend,e};var yd,_d=bd,xd=aa;yd=_d.extend({getInitialValue:function(){return""},getValue:function(){return this.element.node.value},render:function(){var t,e=this.element.node,n=!1;this.rendered=!0,t=this.root.lazy,this.element.lazy===!0?t=!0:this.element.lazy===!1?t=!1:p(this.element.lazy)?(t=!1,n=+this.element.lazy):p(t||"")&&(n=+t,t=!1,this.element.lazy=n),this.handler=n?ia:xd,e.addEventListener("change",xd,!1),t||(e.addEventListener("input",this.handler,!1),e.attachEvent&&e.addEventListener("keyup",this.handler,!1)),e.addEventListener("blur",ra,!1)},unrender:function(){var t=this.element.node;this.rendered=!1,t.removeEventListener("change",xd,!1),t.removeEventListener("input",this.handler,!1),t.removeEventListener("keyup",this.handler,!1),t.removeEventListener("blur",ra,!1)}});var wd=yd,kd=wd.extend({getInitialValue:function(){return this.element.fragment?""+this.element.fragment:""},getValue:function(){return this.element.node.innerHTML}}),Sd=kd,Ed=oa,Cd={},Pd=_d.extend({name:"checked",init:function(){this.siblings=Ed(this.root._guid,"radio",this.element.getAttribute("name")),this.siblings.push(this)},render:function(){var t=this.element.node;t.addEventListener("change",xd,!1),t.attachEvent&&t.addEventListener("click",xd,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",xd,!1),t.removeEventListener("click",xd,!1)},handleChange:function(){bs.start(this.root),this.siblings.forEach(function(t){t.root.viewmodel.set(t.keypath,t.getValue())}),bs.end()},getValue:function(){return this.element.node.checked},unbind:function(){N(this.siblings,this)}}),Ad=Pd,Od=_d.extend({name:"name",init:function(){this.siblings=Ed(this.root._guid,"radioname",this.keypath.str),this.siblings.push(this),this.radioName=!0},getInitialValue:function(){return this.element.getAttribute("checked")?this.element.getAttribute("value"):void 0},render:function(){var t=this.element.node;t.name="{{"+this.keypath.str+"}}",t.checked=this.root.viewmodel.get(this.keypath)==this.element.getAttribute("value"),t.addEventListener("change",xd,!1),t.attachEvent&&t.addEventListener("click",xd,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",xd,!1),t.removeEventListener("click",xd,!1)},getValue:function(){var t=this.element.node;return t._ractive?t._ractive.value:t.value},handleChange:function(){this.element.node.checked&&_d.prototype.handleChange.call(this)},rebound:function(t,e){var n;_d.prototype.rebound.call(this,t,e),(n=this.element.node)&&(n.name="{{"+this.keypath.str+"}}")},unbind:function(){N(this.siblings,this)}}),Td=Od,Rd=_d.extend({name:"name",getInitialValue:function(){return this.noInitialValue=!0,[]},init:function(){var t,e;this.checkboxName=!0,this.siblings=Ed(this.root._guid,"checkboxes",this.keypath.str),this.siblings.push(this),this.noInitialValue&&(this.siblings.noInitialValue=!0),this.siblings.noInitialValue&&this.element.getAttribute("checked")&&(t=this.root.viewmodel.get(this.keypath),e=this.element.getAttribute("value"),t.push(e))},unbind:function(){N(this.siblings,this)},render:function(){var t,e,n=this.element.node;t=this.root.viewmodel.get(this.keypath),e=this.element.getAttribute("value"),i(t)?this.isChecked=M(t,e):this.isChecked=t==e,n.name="{{"+this.keypath.str+"}}",n.checked=this.isChecked,n.addEventListener("change",xd,!1),n.attachEvent&&n.addEventListener("click",xd,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",xd,!1),t.removeEventListener("click",xd,!1)},changed:function(){var t=!!this.isChecked;return this.isChecked=this.element.node.checked,this.isChecked===t},handleChange:function(){this.isChecked=this.element.node.checked,_d.prototype.handleChange.call(this)},getValue:function(){return this.siblings.filter(sa).map(pa)}}),Md=Rd,Ld=_d.extend({name:"checked",render:function(){var t=this.element.node;t.addEventListener("change",xd,!1),t.attachEvent&&t.addEventListener("click",xd,!1)},unrender:function(){var t=this.element.node;t.removeEventListener("change",xd,!1),t.removeEventListener("click",xd,!1)},getValue:function(){return this.element.node.checked}}),jd=Ld,Dd=_d.extend({getInitialValue:function(){var t,e,n,a,r=this.element.options;if(void 0===this.element.getAttribute("value")&&(e=t=r.length,t)){for(;e--;)if(r[e].getAttribute("selected")){n=r[e].getAttribute("value"),a=!0;break}if(!a)for(;++ee;e+=1)if(a=t[e],t[e].selected)return r=a._ractive?a._ractive.value:a.value},forceUpdate:function(){var t=this,e=this.getValue();void 0!==e&&(this.attribute.locked=!0,bs.scheduleTask(function(){return t.attribute.locked=!1}),this.root.viewmodel.set(this.keypath,e))}}),Nd=Dd,Fd=Nd.extend({getInitialValue:function(){return this.element.options.filter(function(t){return t.getAttribute("selected")}).map(function(t){return t.getAttribute("value")})},render:function(){var t;this.element.node.addEventListener("change",xd,!1),t=this.root.viewmodel.get(this.keypath),void 0===t&&this.handleChange()},unrender:function(){this.element.node.removeEventListener("change",xd,!1)},setValue:function(){throw Error("TODO not implemented yet")},getValue:function(){var t,e,n,a,r,i;for(t=[],e=this.element.node.options,a=e.length,n=0;a>n;n+=1)r=e[n],r.selected&&(i=r._ractive?r._ractive.value:r.value,t.push(i));return t},handleChange:function(){var t,e,n;return t=this.attribute,e=t.value,n=this.getValue(),void 0!==e&&L(n,e)||Nd.prototype.handleChange.call(this),this},forceUpdate:function(){var t=this,e=this.getValue();void 0!==e&&(this.attribute.locked=!0,bs.scheduleTask(function(){return t.attribute.locked=!1}),this.root.viewmodel.set(this.keypath,e))},updateModel:function(){void 0!==this.attribute.value&&this.attribute.value.length||this.root.viewmodel.set(this.keypath,this.initialValue)}}),Id=Fd,Bd=_d.extend({render:function(){this.element.node.addEventListener("change",xd,!1)},unrender:function(){this.element.node.removeEventListener("change",xd,!1)},getValue:function(){return this.element.node.files}}),Vd=Bd,qd=wd.extend({getInitialValue:function(){},getValue:function(){var t=parseFloat(this.element.node.value);return isNaN(t)?void 0:t}}),Ud=ua,Gd=la,zd=da,Wd=fa,Hd=ha,Kd=/^event(?:\.(.+))?/,Qd=ba,Yd=ya,$d={},Jd={touchstart:!0,touchmove:!0,touchend:!0,touchcancel:!0,touchleave:!0},Xd=xa,Zd=wa,tf=ka,ef=Sa,nf=Ea,af=function(t,e,n){this.init(t,e,n)};af.prototype={bubble:Gd,fire:zd,getAction:Wd,init:Hd,listen:Yd,rebind:Xd,render:Zd,resolve:tf,unbind:ef,unrender:nf};var rf=af,of=function(t,e){var n,a,r,i,o=[];for(a in e)if(e.hasOwnProperty(a))for(r=a.split("-"),n=r.length;n--;)i=new rf(t,r[n],e[a]),o.push(i);return o},sf=function(t,e){var n,a,r,i=this;this.element=t,this.root=n=t.root,a=e.n||e,("string"==typeof a||(r=new rg({template:a,root:n,owner:t}),a=""+r,r.unbind(),""!==a))&&(e.a?this.params=e.a:e.d&&(this.fragment=new rg({template:e.d,root:n,owner:t}),this.params=this.fragment.getArgsList(),this.fragment.bubble=function(){this.dirtyArgs=this.dirtyValue=!0,i.params=this.getArgsList(),i.ready&&i.update()}),this.fn=v("decorators",n,a),this.fn||l(Io(a,"decorator")))};sf.prototype={init:function(){var t,e,n;if(t=this.element.node,this.params?(n=[t].concat(this.params),e=this.fn.apply(this.root,n)):e=this.fn.call(this.root,t),!e||!e.teardown)throw Error("Decorator definition must return an object with a teardown method");this.actual=e,this.ready=!0},update:function(){this.actual.update?this.actual.update.apply(this.root,this.params):(this.actual.teardown(!0),this.init())},rebind:function(t,e){this.fragment&&this.fragment.rebind(t,e)},teardown:function(t){this.torndown=!0,this.ready&&this.actual.teardown(),!t&&this.fragment&&this.fragment.unbind()}};var pf,uf,cf,lf=sf,df=Ma,ff=La,hf=Ba,mf=function(t){
-return t.replace(/-([a-zA-Z])/g,function(t,e){return e.toUpperCase()})};Xi?(uf={},cf=co("div").style,pf=function(t){var e,n,a;if(t=mf(t),!uf[t])if(void 0!==cf[t])uf[t]=t;else for(a=t.charAt(0).toUpperCase()+t.substring(1),e=ro.length;e--;)if(n=ro[e],void 0!==cf[n+a]){uf[t]=n+a;break}return uf[t]}):pf=null;var gf,vf,bf=pf;Xi?(vf=window.getComputedStyle||Po.getComputedStyle,gf=function(t){var e,n,a,r,o;if(e=vf(this.node),"string"==typeof t)return o=e[bf(t)],"0px"===o&&(o=0),o;if(!i(t))throw Error("Transition$getStyle must be passed a string, or an array of strings representing CSS properties");for(n={},a=t.length;a--;)r=t[a],o=e[bf(r)],"0px"===o&&(o=0),n[r]=o;return n}):gf=null;var yf=gf,_f=function(t,e){var n;if("string"==typeof t)this.node.style[bf(t)]=e;else for(n in t)t.hasOwnProperty(n)&&(this.node.style[bf(n)]=t[n]);return this},xf=function(t){var e;this.duration=t.duration,this.step=t.step,this.complete=t.complete,"string"==typeof t.easing?(e=t.root.easing[t.easing],e||(g(Io(t.easing,"easing")),e=Va)):e="function"==typeof t.easing?t.easing:Va,this.easing=e,this.start=ns(),this.end=this.start+this.duration,this.running=!0,xs.add(this)};xf.prototype={tick:function(t){var e,n;return this.running?t>this.end?(this.step&&this.step(1),this.complete&&this.complete(1),!1):(e=t-this.start,n=this.easing(e/this.duration),this.step&&this.step(n),!0):!1},stop:function(){this.abort&&this.abort(),this.running=!1}};var wf,kf,Sf,Ef,Cf,Pf,Af,Of,Tf=xf,Rf=RegExp("^-(?:"+ro.join("|")+")-"),Mf=function(t){return t.replace(Rf,"")},Lf=RegExp("^(?:"+ro.join("|")+")([A-Z])"),jf=function(t){var e;return t?(Lf.test(t)&&(t="-"+t),e=t.replace(/[A-Z]/g,function(t){return"-"+t.toLowerCase()})):""},Df={},Nf={};Xi?(kf=co("div").style,function(){void 0!==kf.transition?(Sf="transition",Ef="transitionend",Cf=!0):void 0!==kf.webkitTransition?(Sf="webkitTransition",Ef="webkitTransitionEnd",Cf=!0):Cf=!1}(),Sf&&(Pf=Sf+"Duration",Af=Sf+"Property",Of=Sf+"TimingFunction"),wf=function(t,e,n,a,r){setTimeout(function(){var i,o,s,p,u;p=function(){o&&s&&(t.root.fire(t.name+":end",t.node,t.isIntro),r())},i=(t.node.namespaceURI||"")+t.node.tagName,t.node.style[Af]=a.map(bf).map(jf).join(","),t.node.style[Of]=jf(n.easing||"linear"),t.node.style[Pf]=n.duration/1e3+"s",u=function(e){var n;n=a.indexOf(mf(Mf(e.propertyName))),-1!==n&&a.splice(n,1),a.length||(t.node.removeEventListener(Ef,u,!1),s=!0,p())},t.node.addEventListener(Ef,u,!1),setTimeout(function(){for(var r,c,l,d,f,h=a.length,g=[];h--;)d=a[h],r=i+d,Cf&&!Nf[r]&&(t.node.style[bf(d)]=e[d],Df[r]||(c=t.getStyle(d),Df[r]=t.getStyle(d)!=e[d],Nf[r]=!Df[r],Nf[r]&&(t.node.style[bf(d)]=c))),(!Cf||Nf[r])&&(void 0===c&&(c=t.getStyle(d)),l=a.indexOf(d),-1===l?m("Something very strange happened with transitions. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!",{node:t.node}):a.splice(l,1),f=/[^\d]*$/.exec(e[d])[0],g.push({name:bf(d),interpolator:Vo(parseFloat(c),parseFloat(e[d])),suffix:f}));g.length?new Tf({root:t.root,duration:n.duration,easing:mf(n.easing||""),step:function(e){var n,a;for(a=g.length;a--;)n=g[a],t.node.style[n.name]=n.interpolator(e)+n.suffix},complete:function(){o=!0,p()}}):o=!0,a.length||(t.node.removeEventListener(Ef,u,!1),s=!0,p())},0)},n.delay||0)}):wf=null;var Ff,If,Bf,Vf,qf,Uf=wf;if("undefined"!=typeof document){if(Ff="hidden",qf={},Ff in document)Bf="";else for(Vf=ro.length;Vf--;)If=ro[Vf],Ff=If+"Hidden",Ff in document&&(Bf=If);void 0!==Bf?(document.addEventListener(Bf+"visibilitychange",qa),qa()):("onfocusout"in document?(document.addEventListener("focusout",Ua),document.addEventListener("focusin",Ga)):(window.addEventListener("pagehide",Ua),window.addEventListener("blur",Ua),window.addEventListener("pageshow",Ga),window.addEventListener("focus",Ga)),qf.hidden=!1)}var Gf,zf,Wf,Hf=qf;Xi?(zf=window.getComputedStyle||Po.getComputedStyle,Gf=function(t,e,n){var a,r=this;if(4===arguments.length)throw Error("t.animateStyle() returns a promise - use .then() instead of passing a callback");if(Hf.hidden)return this.setStyle(t,e),Wf||(Wf=us.resolve());"string"==typeof t?(a={},a[t]=e):(a=t,n=e),n||(g('The "%s" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340',this.name),n=this);var i=new us(function(t){var e,i,o,s,p,u,c;if(!n.duration)return r.setStyle(a),void t();for(e=Object.keys(a),i=[],o=zf(r.node),p={},u=e.length;u--;)c=e[u],s=o[bf(c)],"0px"===s&&(s=0),s!=a[c]&&(i.push(c),r.node.style[bf(c)]=s);return i.length?void Uf(r,a,n,i,t):void t()});return i}):Gf=null;var Kf=Gf,Qf=function(t,e){return"number"==typeof t?t={duration:t}:"string"==typeof t?t="slow"===t?{duration:600}:"fast"===t?{duration:200}:{duration:400}:t||(t={}),r({},t,e)},Yf=za,$f=function(t,e,n){this.init(t,e,n)};$f.prototype={init:hf,start:Yf,getStyle:yf,setStyle:_f,animateStyle:Kf,processParams:Qf};var Jf,Xf,Zf=$f,th=Ha;Jf=function(){var t=this.node,e=this.fragment.toString(!1);if(window&&window.appearsToBeIELessEqual8&&(t.type="text/css"),t.styleSheet)t.styleSheet.cssText=e;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}},Xf=function(){this.node.type&&"text/javascript"!==this.node.type||m("Script tag was updated. This does not cause the code to be re-evaluated!",{ractive:this.root}),this.node.text=this.fragment.toString(!1)};var eh=function(){var t,e;return this.template.y?"":(t="<"+this.template.e,t+=this.attributes.map(Xa).join("")+this.conditionalAttributes.map(Xa).join(""),"option"===this.name&&$a(this)&&(t+=" selected"),"input"===this.name&&Ja(this)&&(t+=" checked"),t+=">","textarea"===this.name&&void 0!==this.getAttribute("value")?t+=Se(this.getAttribute("value")):void 0!==this.getAttribute("contenteditable")&&(t+=this.getAttribute("value")||""),this.fragment&&(e="script"!==this.name&&"style"!==this.name,t+=this.fragment.toString(e)),ic.test(this.template.e)||(t+=""+this.template.e+">"),t)},nh=Za,ah=tr,rh=function(t){this.init(t)};rh.prototype={bubble:Tl,detach:Rl,find:Ml,findAll:Ll,findAllComponents:jl,findComponent:Dl,findNextNode:Nl,firstNode:Fl,getAttribute:Il,init:df,rebind:ff,render:th,toString:eh,unbind:nh,unrender:ah};var ih=rh,oh=/^\s*$/,sh=/^\s*/,ph=function(t){var e,n,a,r;return e=t.split("\n"),n=e[0],void 0!==n&&oh.test(n)&&e.shift(),a=D(e),void 0!==a&&oh.test(a)&&e.pop(),r=e.reduce(nr,null),r&&(t=e.map(function(t){return t.replace(r,"")}).join("\n")),t},uh=ar,ch=function(t,e){var n;return e?n=t.split("\n").map(function(t,n){return n?e+t:t}).join("\n"):t},lh='Could not find template for partial "%s"',dh=function(t){var e,n;e=this.parentFragment=t.parentFragment,this.root=e.root,this.type=Au,this.index=t.index,this.name=t.template.r,this.rendered=!1,this.fragment=this.fragmentToRender=this.fragmentToUnrender=null,Gc.init(this,t),this.keypath||((n=uh(this.root,this.name,e))?(_c.call(this),this.isNamed=!0,this.setTemplate(n)):g(lh,this.name))};dh.prototype={bubble:function(){this.parentFragment.bubble()},detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},getPartialName:function(){return this.isNamed&&this.name?this.name:void 0===this.value?this.name:this.value},getValue:function(){return this.fragment.getValue()},rebind:function(t,e){this.isNamed||Uc.call(this,t,e),this.fragment&&this.fragment.rebind(t,e)},render:function(){return this.docFrag=document.createDocumentFragment(),this.update(),this.rendered=!0,this.docFrag},resolve:Gc.resolve,setValue:function(t){var e;(void 0===t||t!==this.value)&&(void 0!==t&&(e=uh(this.root,""+t,this.parentFragment)),!e&&this.name&&(e=uh(this.root,this.name,this.parentFragment))&&(_c.call(this),this.isNamed=!0),e||g(lh,this.name,{ractive:this.root}),this.value=t,this.setTemplate(e||[]),this.bubble(),this.rendered&&bs.addView(this))},setTemplate:function(t){this.fragment&&(this.fragment.unbind(),this.rendered&&(this.fragmentToUnrender=this.fragment)),this.fragment=new rg({template:t,root:this.root,owner:this,pElement:this.parentFragment.pElement}),this.fragmentToRender=this.fragment},toString:function(t){var e,n,a,r;return e=this.fragment.toString(t),n=this.parentFragment.items[this.index-1],n&&n.type===ku?(a=n.text.split("\n").pop(),(r=/^\s+$/.exec(a))?ch(e,r[0]):e):e},unbind:function(){this.isNamed||_c.call(this),this.fragment&&this.fragment.unbind()},unrender:function(t){this.rendered&&(this.fragment&&this.fragment.unrender(t),this.rendered=!1)},update:function(){var t,e;this.fragmentToUnrender&&(this.fragmentToUnrender.unrender(!0),this.fragmentToUnrender=null),this.fragmentToRender&&(this.docFrag.appendChild(this.fragmentToRender.render()),this.fragmentToRender=null),this.rendered&&(t=this.parentFragment.getNode(),e=this.parentFragment.findNextNode(this),t.insertBefore(this.docFrag,e))}};var fh,hh,mh,gh=dh,vh=pr,bh=ur,yh=new is("detach"),_h=cr,xh=lr,wh=dr,kh=fr,Sh=hr,Eh=mr,Ch=function(t,e,n,a){var r=t.root,i=t.keypath;a?r.viewmodel.smartUpdate(i,e,a):r.viewmodel.mark(i)},Ph=[],Ah=["pop","push","reverse","shift","sort","splice","unshift"];Ah.forEach(function(t){var e=function(){for(var e=arguments.length,n=Array(e),a=0;e>a;a++)n[a]=arguments[a];var r,i,o,s;for(r=bp(this,t,n),i=Array.prototype[t].apply(this,arguments),bs.start(),this._ractive.setting=!0,s=this._ractive.wrappers.length;s--;)o=this._ractive.wrappers[s],bs.addRactive(o.root),Ch(o,this,t,r);return bs.end(),this._ractive.setting=!1,i};Eo(Ph,t,{value:e})}),fh={},fh.__proto__?(hh=function(t){t.__proto__=Ph},mh=function(t){t.__proto__=Array.prototype}):(hh=function(t){var e,n;for(e=Ah.length;e--;)n=Ah[e],Eo(t,n,{value:Ph[n],configurable:!0})},mh=function(t){var e;for(e=Ah.length;e--;)delete t[Ah[e]]}),hh.unpatch=mh;var Oh,Th,Rh,Mh=hh;Oh={filter:function(t){return i(t)&&(!t._ractive||!t._ractive.setting)},wrap:function(t,e,n){return new Th(t,e,n)}},Th=function(t,e,n){this.root=t,this.value=e,this.keypath=S(n),e._ractive||(Eo(e,"_ractive",{value:{wrappers:[],instances:[],setting:!1},configurable:!0}),Mh(e)),e._ractive.instances[t._guid]||(e._ractive.instances[t._guid]=0,e._ractive.instances.push(t)),e._ractive.instances[t._guid]+=1,e._ractive.wrappers.push(this)},Th.prototype={get:function(){return this.value},teardown:function(){var t,e,n,a,r;if(t=this.value,e=t._ractive,n=e.wrappers,a=e.instances,e.setting)return!1;if(r=n.indexOf(this),-1===r)throw Error(Rh);if(n.splice(r,1),n.length){if(a[this.root._guid]-=1,!a[this.root._guid]){if(r=a.indexOf(this.root),-1===r)throw Error(Rh);a.splice(r,1)}}else delete t._ractive,Mh.unpatch(this.value)}},Rh="Something went wrong in a rather interesting way";var Lh,jh,Dh=Oh,Nh=/^\s*[0-9]+\s*$/,Fh=function(t){return Nh.test(t)?[]:{}};try{Object.defineProperty({},"test",{value:0}),Lh={filter:function(t,e,n){var a,r;return e?(e=S(e),(a=n.viewmodel.wrapped[e.parent.str])&&!a.magic?!1:(r=n.viewmodel.get(e.parent),i(r)&&/^[0-9]+$/.test(e.lastKey)?!1:r&&("object"==typeof r||"function"==typeof r))):!1},wrap:function(t,e,n){return new jh(t,e,n)}},jh=function(t,e,n){var a,r,i;return n=S(n),this.magic=!0,this.ractive=t,this.keypath=n,this.value=e,this.prop=n.lastKey,a=n.parent,this.obj=a.isRoot?t.viewmodel.data:t.viewmodel.get(a),r=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),r&&r.set&&(i=r.set._ractiveWrappers)?void(-1===i.indexOf(this)&&i.push(this)):void gr(this,e,r)},jh.prototype={get:function(){return this.value},reset:function(t){return this.updating?void 0:(this.updating=!0,this.obj[this.prop]=t,bs.addRactive(this.ractive),this.ractive.viewmodel.mark(this.keypath,{keepExistingWrapper:!0}),this.updating=!1,!0)},set:function(t,e){this.updating||(this.obj[this.prop]||(this.updating=!0,this.obj[this.prop]=Fh(t),this.updating=!1),this.obj[this.prop][t]=e)},teardown:function(){var t,e,n,a,r;return this.updating?!1:(t=Object.getOwnPropertyDescriptor(this.obj,this.prop),e=t&&t.set,void(e&&(a=e._ractiveWrappers,r=a.indexOf(this),-1!==r&&a.splice(r,1),a.length||(n=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configurable:!0}),this.obj[this.prop]=n))))}}}catch(Ao){Lh=!1}var Ih,Bh,Vh=Lh;Vh&&(Ih={filter:function(t,e,n){return Vh.filter(t,e,n)&&Dh.filter(t)},wrap:function(t,e,n){return new Bh(t,e,n)}},Bh=function(t,e,n){this.value=e,this.magic=!0,this.magicWrapper=Vh.wrap(t,e,n),this.arrayWrapper=Dh.wrap(t,e,n)},Bh.prototype={get:function(){return this.value},teardown:function(){this.arrayWrapper.teardown(),this.magicWrapper.teardown()},reset:function(t){return this.magicWrapper.reset(t)}});var qh=Ih,Uh=vr,Gh={},zh=_r,Wh=xr,Hh=Sr,Kh=Or,Qh=Tr,Yh=function(t,e){this.computation=t,this.viewmodel=t.viewmodel,this.ref=e,this.root=this.viewmodel.ractive,this.parentFragment=this.root.component&&this.root.component.parentFragment};Yh.prototype={resolve:function(t){this.computation.softDeps.push(t),this.computation.unresolvedDeps[t.str]=null,this.viewmodel.register(t,this.computation,"computed")}};var $h=Yh,Jh=function(t,e){this.key=t,this.getter=e.getter,this.setter=e.setter,this.hardDeps=e.deps||[],this.softDeps=[],this.unresolvedDeps={},this.depValues={},this._dirty=this._firstRun=!0};Jh.prototype={constructor:Jh,init:function(t){var e,n=this;this.viewmodel=t,this.bypass=!0,e=t.get(this.key),t.clearCache(this.key.str),this.bypass=!1,this.setter&&void 0!==e&&this.set(e),this.hardDeps&&this.hardDeps.forEach(function(e){return t.register(e,n,"computed")})},invalidate:function(){this._dirty=!0},get:function(){var t,e,n=this,a=!1;if(this.getting){var r="The "+this.key.str+" computation indirectly called itself. This probably indicates a bug in the computation. It is commonly caused by `array.sort(...)` - if that's the case, clone the array first with `array.slice().sort(...)`";return h(r),this.value}if(this.getting=!0,this._dirty){if(this._firstRun||!this.hardDeps.length&&!this.softDeps.length?a=!0:[this.hardDeps,this.softDeps].forEach(function(t){var e,r,i;if(!a)for(i=t.length;i--;)if(e=t[i],r=n.viewmodel.get(e),!s(r,n.depValues[e.str]))return n.depValues[e.str]=r,void(a=!0)}),a){this.viewmodel.capture();try{this.value=this.getter()}catch(i){m('Failed to compute "%s"',this.key.str),d(i.stack||i),this.value=void 0}t=this.viewmodel.release(),e=this.updateDependencies(t),e&&[this.hardDeps,this.softDeps].forEach(function(t){t.forEach(function(t){n.depValues[t.str]=n.viewmodel.get(t)})})}this._dirty=!1}return this.getting=this._firstRun=!1,this.value},set:function(t){if(this.setting)return void(this.value=t);if(!this.setter)throw Error("Computed properties without setters are read-only. (This may change in a future version of Ractive!)");this.setter(t)},updateDependencies:function(t){var e,n,a,r,i;for(n=this.softDeps,e=n.length;e--;)a=n[e],-1===t.indexOf(a)&&(r=!0,this.viewmodel.unregister(a,this,"computed"));for(e=t.length;e--;)a=t[e],-1!==n.indexOf(a)||this.hardDeps&&-1!==this.hardDeps.indexOf(a)||(r=!0,Rr(this.viewmodel,a)&&!this.unresolvedDeps[a.str]?(i=new $h(this,a.str),t.splice(e,1),this.unresolvedDeps[a.str]=i,bs.addUnresolved(i)):this.viewmodel.register(a,this,"computed"));return r&&(this.softDeps=t.slice()),r}};var Xh=Jh,Zh=Mr,tm={FAILED_LOOKUP:!0},em=Lr,nm={},am=Dr,rm=Nr,im=function(t,e){this.localKey=t,this.keypath=e.keypath,this.origin=e.origin,this.deps=[],this.unresolved=[],this.resolved=!1};im.prototype={forceResolution:function(){this.keypath=this.localKey,this.setup()},get:function(t,e){return this.resolved?this.origin.get(this.map(t),e):void 0},getValue:function(){return this.keypath?this.origin.get(this.keypath):void 0},initViewmodel:function(t){this.local=t,this.setup()},map:function(t){return void 0===typeof this.keypath?this.localKey:t.replace(this.localKey,this.keypath)},register:function(t,e,n){this.deps.push({keypath:t,dep:e,group:n}),this.resolved&&this.origin.register(this.map(t),e,n)},resolve:function(t){void 0!==this.keypath&&this.unbind(!0),this.keypath=t,this.setup()},set:function(t,e){this.resolved||this.forceResolution(),this.origin.set(this.map(t),e)},setup:function(){var t=this;void 0!==this.keypath&&(this.resolved=!0,this.deps.length&&(this.deps.forEach(function(e){var n=t.map(e.keypath);if(t.origin.register(n,e.dep,e.group),e.dep.setValue)e.dep.setValue(t.origin.get(n));else{if(!e.dep.invalidate)throw Error("An unexpected error occurred. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");e.dep.invalidate()}}),this.origin.mark(this.keypath)))},setValue:function(t){if(!this.keypath)throw Error("Mapping does not have keypath, cannot set value. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");this.origin.set(this.keypath,t)},unbind:function(t){var e=this;t||delete this.local.mappings[this.localKey],this.resolved&&(this.deps.forEach(function(t){e.origin.unregister(e.map(t.keypath),t.dep,t.group)}),this.tracker&&this.origin.unregister(this.keypath,this.tracker))},unregister:function(t,e,n){var a,r;if(this.resolved){for(a=this.deps,r=a.length;r--;)if(a[r].dep===e){a.splice(r,1);break}this.origin.unregister(this.map(t),e,n)}}};var om=Fr,sm=function(t,e){var n,a,r,i;return n={},a=0,r=t.map(function(t,r){var o,s,p;s=a,p=e.length;do{if(o=e.indexOf(t,s),-1===o)return i=!0,-1;s=o+1}while(n[o]&&p>s);return o===a&&(a+=1),o!==r&&(i=!0),n[o]=!0,o})},pm=Ir,um={},cm=qr,lm=Gr,dm=zr,fm=Wr,hm=Kr,mm={implicit:!0},gm={noCascade:!0},vm=Yr,bm=$r,ym=function(t){var e,n,a=t.adapt,r=t.data,i=t.ractive,o=t.computed,s=t.mappings;this.ractive=i,this.adaptors=a,this.onchange=t.onchange,this.cache={},this.cacheMap=So(null),this.deps={computed:So(null),"default":So(null)},this.depsMap={computed:So(null),"default":So(null)},this.patternObservers=[],this.specials=So(null),this.wrapped=So(null),this.computations=So(null),this.captureGroups=[],this.unresolvedImplicitDependencies=[],this.changes=[],this.implicitChanges={},this.noCascade={},this.data=r,this.mappings=So(null);for(e in s)this.map(S(e),s[e]);if(r)for(e in r)(n=this.mappings[e])&&void 0===n.getValue()&&n.setValue(r[e]);for(e in o)s&&e in s&&l("Cannot map to a computed property ('%s')",e),this.compute(S(e),o[e]);this.ready=!0};ym.prototype={adapt:Uh,applyChanges:Hh,capture:Kh,clearCache:Qh,compute:Zh,get:em,init:am,map:rm,mark:om,merge:pm,register:cm,release:lm,reset:dm,set:fm,smartUpdate:hm,teardown:vm,unregister:bm};var _m=ym;Xr.prototype={constructor:Xr,begin:function(t){this.inProcess[t._guid]=!0},end:function(t){var e=t.parent;e&&this.inProcess[e._guid]?Zr(this.queue,e).push(t):ti(this,t),delete this.inProcess[t._guid]}};var xm=Xr,wm=ei,km=/\$\{([^\}]+)\}/g,Sm=new is("construct"),Em=new is("config"),Cm=new xm("init"),Pm=0,Am=["adaptors","components","decorators","easing","events","interpolators","partials","transitions"],Om=ii,Tm=ci;ci.prototype={bubble:function(){this.dirty||(this.dirty=!0,bs.addView(this))},update:function(){this.callback(this.fragment.getValue()),this.dirty=!1},rebind:function(t,e){this.fragment.rebind(t,e)},unbind:function(){this.fragment.unbind()}};var Rm=function(t,e,n,r,o){var s,p,u,c,l,d,f={},h={},g={},v=[];for(p=t.parentFragment,u=t.root,o=o||{},a(f,o),o.content=r||[],f[""]=o.content,e.defaults.el&&m("The <%s/> component has a default `el` property; it has been disregarded",t.name),c=p;c;){if(c.owner.type===Mu){l=c.owner.container;break}c=c.parent}return n&&Object.keys(n).forEach(function(e){var a,r,o=n[e];if("string"==typeof o)a=dc(o),h[e]=a?a.value:o;else if(0===o)h[e]=!0;else{if(!i(o))throw Error("erm wut");di(o)?(g[e]={origin:t.root.viewmodel,keypath:void 0},r=li(t,o[0],function(t){t.isSpecial?d?s.set(e,t.value):(h[e]=t.value,delete g[e]):d?s.viewmodel.mappings[e].resolve(t):g[e].keypath=t})):r=new Tm(t,o,function(t){d?s.set(e,t):h[e]=t}),v.push(r)}}),s=So(e.prototype),Om(s,{el:null,append:!0,data:h,partials:o,magic:u.magic||e.defaults.magic,modifyArrays:u.modifyArrays,adapt:u.adapt},{parent:u,component:t,container:l,mappings:g,inlinePartials:f,cssIds:p.cssIds}),d=!0,t.resolvers=v,s},Mm=fi,Lm=function(t){var e,n;for(e=t.root;e;)(n=e._liveComponentQueries["_"+t.name])&&n.push(t.instance),e=e.parent},jm=mi,Dm=gi,Nm=vi,Fm=bi,Im=yi,Bm=new is("teardown"),Vm=xi,qm=function(t,e){this.init(t,e)};qm.prototype={detach:bh,find:_h,findAll:xh,findAllComponents:wh,findComponent:kh,findNextNode:Sh,firstNode:Eh,init:jm,rebind:Dm,render:Nm,toString:Fm,unbind:Im,unrender:Vm};var Um=qm,Gm=function(t){this.type=Ou,this.value=t.template.c};Gm.prototype={detach:vc,firstNode:function(){return this.node},render:function(){return this.node||(this.node=document.createComment(this.value)),this.node},toString:function(){return""},unrender:function(t){t&&this.node.parentNode.removeChild(this.node)}};var zm=Gm,Wm=function(t){var e,n;this.type=Mu,this.container=e=t.parentFragment.root,this.component=n=e.component,this.container=e,this.containerFragment=t.parentFragment,this.parentFragment=n.parentFragment;var a=this.name=t.template.n||"",r=e._inlinePartials[a];r||(m('Could not find template for partial "'+a+'"',{ractive:t.root}),r=[]),this.fragment=new rg({owner:this,root:e.parent,template:r,pElement:this.containerFragment.pElement}),i(n.yielders[a])?n.yielders[a].push(this):n.yielders[a]=[this],bs.scheduleTask(function(){if(n.yielders[a].length>1)throw Error("A component template can only have one {{yield"+(a?" "+a:"")+"}} declaration at a time")})};Wm.prototype={detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},findNextNode:function(){return this.containerFragment.findNextNode(this)},firstNode:function(){return this.fragment.firstNode()},getValue:function(t){return this.fragment.getValue(t)},render:function(){return this.fragment.render()},unbind:function(){this.fragment.unbind()},unrender:function(t){this.fragment.unrender(t),N(this.component.yielders[this.name],this)},rebind:function(t,e){this.fragment.rebind(t,e)},toString:function(){return""+this.fragment}};var Hm=Wm,Km=function(t){this.declaration=t.template.a};Km.prototype={init:ko,render:ko,unrender:ko,teardown:ko,toString:function(){return""}};var Qm=Km,Ym=wi,$m=Si,Jm=Ei,Xm=Ci,Zm=Oi,tg=Ri,eg=function(t){this.init(t)};eg.prototype={bubble:cu,detach:lu,find:du,findAll:fu,findAllComponents:hu,findComponent:mu,findNextNode:gu,firstNode:vu,getArgsList:hc,getNode:mc,getValue:gc,init:Ym,rebind:$m,registerIndexRef:function(t){var e=this.registeredIndexRefs;-1===e.indexOf(t)&&e.push(t)},render:Jm,toString:Xm,unbind:Zm,unregisterIndexRef:function(t){var e=this.registeredIndexRefs;e.splice(e.indexOf(t),1)},unrender:tg};var ng,ag,rg=eg,ig=Mi,og=["template","partials","components","decorators","events"],sg=new is("reset"),pg=function(t,e){function n(e,a,r){r&&r.partials[t]||e.forEach(function(e){e.type===Au&&e.getPartialName()===t&&a.push(e),e.fragment&&n(e.fragment.items,a,r),i(e.fragments)?n(e.fragments,a,r):i(e.items)?n(e.items,a,r):e.type===Ru&&e.instance&&n(e.instance.fragment.items,a,e.instance),e.type===Pu&&(i(e.attributes)&&n(e.attributes,a,r),i(e.conditionalAttributes)&&n(e.conditionalAttributes,a,r))})}var a,r=[];return n(this.fragment.items,r),this.partials[t]=e,a=bs.start(this,!0),r.forEach(function(e){e.value=void 0,e.setValue(t)}),bs.end(),a},ug=Li,cg=_p("reverse"),lg=ji,dg=_p("shift"),fg=_p("sort"),hg=_p("splice"),mg=Ni,gg=Fi,vg=new is("teardown"),bg=Bi,yg=Vi,_g=qi,xg=new is("unrender"),wg=_p("unshift"),kg=Ui,Sg=new is("update"),Eg=Gi,Cg={add:Zo,animate:Ss,detach:Cs,find:As,findAll:Fs,findAllComponents:Is,findComponent:Bs,findContainer:Vs,findParent:qs,fire:Ws,get:Hs,insert:Qs,merge:$s,observe:lp,observeOnce:dp,off:mp,on:gp,once:vp,pop:xp,push:wp,render:Tp,reset:ig,resetPartial:pg,resetTemplate:ug,reverse:cg,set:lg,shift:dg,sort:fg,splice:hg,subtract:mg,teardown:gg,toggle:bg,toHTML:yg,toHtml:yg,unrender:_g,unshift:wg,update:kg,updateModel:Eg},Pg=function(t,e,n){return n||Wi(t,e)?function(){var n,a="_super"in this,r=this._super;return this._super=e,n=t.apply(this,arguments),a&&(this._super=r),n}:t},Ag=Hi,Og=$i,Tg=function(t){var e,n,a={};return t&&(e=t._ractive)?(a.ractive=e.root,a.keypath=e.keypath.str,a.index={},(n=Oc(e.proxy.parentFragment))&&(a.index=Oc.resolve(n)),a):a};ng=function(t){return this instanceof ng?void Om(this,t):new ng(t)},ag={DEBUG:{writable:!0,value:!0},DEBUG_PROMISES:{writable:!0,value:!0},extend:{value:Og},getNodeInfo:{value:Tg},parse:{value:Hp},Promise:{value:us},svg:{value:ao},magic:{value:eo},VERSION:{value:"0.7.3"},adaptors:{writable:!0,value:{}},components:{writable:!0,value:{}},decorators:{writable:!0,value:{}},easing:{writable:!0,value:po},events:{writable:!0,value:{}},interpolators:{writable:!0,value:Uo},partials:{writable:!0,value:{}},transitions:{writable:!0,value:{}}},Co(ng,ag),ng.prototype=a(Cg,so),ng.prototype.constructor=ng,ng.defaults=ng.prototype;var Rg="function";if(typeof Date.now!==Rg||typeof String.prototype.trim!==Rg||typeof Object.keys!==Rg||typeof Array.prototype.indexOf!==Rg||typeof Array.prototype.forEach!==Rg||typeof Array.prototype.map!==Rg||typeof Array.prototype.filter!==Rg||"undefined"!=typeof window&&typeof window.addEventListener!==Rg)throw Error("It looks like you're attempting to use Ractive.js in an older browser. You'll need to use one of the 'legacy builds' in order to continue - see http://docs.ractivejs.org/latest/legacy-builds for more information.");var Mg=ng;return Mg})},{}],342:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.observe("value",function(e,n,a){var r=t.get(),i=r.min,o=r.max,s=Math.clamp(i,o,e);t.animate("percentage",Math.round((s-i)/(o-i)*100))})}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,293],t:7,e:"div",a:{"class":"bar"},f:[{p:[14,3,313],t:7,e:"div",a:{"class":["barFill ",{t:2,r:"state",p:[14,23,333]}],style:["width: ",{t:2,r:"percentage",p:[14,48,358]},"%"]}}," ",{p:[15,3,384],t:7,e:"span",a:{"class":"barText"},f:[{t:16,p:[15,25,406]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],343:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(482),a=t(481);e.exports={computed:{clickable:function(){return!this.get("enabled")||this.get("state")&&"toggle"!=this.get("state")?!1:!0},enabled:function(){return this.get("config.status")===n.UI_INTERACTIVE?!0:!1},styles:function(){var t="";if(this.get("class")&&(t+=" "+this.get("class")),this.get("tooltip-side")&&(t=" tooltip-"+this.get("tooltip-side")),this.get("grid")&&(t+=" gridable"),this.get("enabled")){var e=this.get("state"),n=this.get("style");return e?"inactive "+e+" "+t:"active normal "+n+" "+t}return"inactive disabled "+t}},oninit:function(){var t=this;this.on("press",function(e){var n=t.get(),r=n.action,i=n.params;(0,a.act)(t.get("config.ref"),r,i),e.node.blur()})},data:{iconStackToHTML:function(t){var e="",n=t.split(",");if(n.length){e+='';for(var a=n,r=Array.isArray(a),i=0,a=r?a:a[Symbol.iterator]();;){var o;if(r){if(i>=a.length)break;o=a[i++]}else{if(i=a.next(),i.done)break;o=i.value}var s=o,p=/([\w\-]+)\s*(\dx)/g,u=p.exec(s),c=u[1],l=u[2];e+=' '}}return e&&(e+=" "),e}}}}(r),r.exports.template={v:3,t:[" ",{p:[70,1,1950],t:7,e:"span",a:{"class":["button ",{t:2,r:"styles",p:[70,21,1970]}],unselectable:"on","data-tooltip":[{t:2,r:"tooltip",p:[73,17,2052]}]},m:[{t:4,f:["tabindex='0'"],r:"clickable",p:[72,3,2004]}],v:{"mouseover-mousemove":"hover",mouseleave:"unhover","click-enter":{n:[{t:4,f:["press"],r:"clickable",p:[76,19,2142]}],d:[]}},f:[{t:4,f:[{p:[78,5,2188],t:7,e:"i",a:{"class":["fa fa-",{t:2,r:"icon",p:[78,21,2204]}]}}],n:50,r:"icon",p:[77,3,2171]}," ",{t:4,f:[{t:3,x:{r:["iconStackToHTML","icon_stack"],s:"_0(_1)"},p:[81,6,2255]}],n:50,r:"icon_stack",p:[80,3,2231]}," ",{t:16,p:[83,3,2301]}]}]},e.exports=a.extend(r.exports)},{341:341,481:481,482:482}],344:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"display"},f:[{t:4,f:[{p:[3,5,42],t:7,e:"header",f:[{p:[4,7,57],t:7,e:"h3",f:[{t:2,r:"title",p:[4,11,61]}]}," ",{t:4,f:[{p:[6,9,105],t:7,e:"div",a:{"class":"buttonRight"},f:[{t:16,n:"button",p:[6,34,130]}]}],n:50,r:"button",p:[5,7,82]}]}],n:50,r:"title",p:[2,3,24]}," ",{p:[10,3,193],t:7,e:"article",f:[{t:16,p:[11,5,207]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],345:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.on("clear",function(){t.set("value",""),t.find("input").focus()})}}}(r),r.exports.template={v:3,t:[" ",{p:[12,1,159],t:7,e:"input",a:{type:"text",value:[{t:2,r:"value",p:[12,27,185]}],placeholder:[{t:2,r:"placeholder",p:[12,51,209]}]}}," ",{p:[13,1,228],t:7,e:"ui-button",a:{icon:"refresh"},v:{press:"clear"}}]},e.exports=a.extend(r.exports)},{341:341}],346:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";e.exports={data:{graph:t(338),xaccessor:function(t){return t.x},yaccessor:function(t){return t.y}},computed:{size:function(){var t=this.get("points");return t[0].length},scale:function(){var t=this.get("points");return Math.max.apply(Math,Array.map(t,function(t){return Math.max.apply(Math,Array.map(t,function(t){return t.y}))}))},xaxis:function(){var t=this.get("xinc"),e=this.get("size");return Array.from(Array(e).keys()).filter(function(e){return e&&e%t==0})},yaxis:function(){var t=this.get("yinc"),e=this.get("scale");return Array.from(Array(t).keys()).map(function(t){return Math.round(e*(++t/100)*10)})}},oninit:function(){var t=this;this.on({enter:function(t){this.set("selected",t.index.count)},exit:function(t){this.set("selected")}}),window.addEventListener("resize",function(e){t.set("width",t.el.clientWidth)})},onrender:function(){this.set("width",this.el.clientWidth)}}}(r),r.exports.template={v:3,t:[" ",{p:[47,1,1223],t:7,e:"svg",a:{"class":"linegraph",width:"100%",height:[{t:2,x:{r:["height"],s:"_0+10"},p:[47,45,1267]}]},f:[{p:[48,3,1287],t:7,e:"g",a:{transform:"translate(0, 5)"},f:[{t:4,f:[{t:4,f:[{p:[51,9,1454],t:7,e:"line",a:{x1:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,19,1464]}],x2:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,38,1483]}],y1:"0",y2:[{t:2,r:"height",p:[51,64,1509]}],stroke:"darkgray"}}," ",{t:4,f:[{p:[53,11,1583],t:7,e:"text",a:{x:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[53,20,1592]}],y:[{t:2,x:{r:["height"],s:"_0-5"},p:[53,38,1610]}],"text-anchor":"middle",fill:"white"},f:[{t:2,x:{r:["size",".","xfactor"],s:"(_0-_1)*_2"},p:[53,88,1660]}," ",{t:2,r:"xunit",p:[53,113,1685]}]}],n:50,x:{r:["@index"],s:"_0%2==0"},p:[52,9,1549]}],n:52,r:"xaxis",p:[50,7,1430]}," ",{t:4,f:[{p:[57,9,1764],t:7,e:"line",a:{x1:"0",x2:[{t:2,r:"width",p:[57,26,1781]}],y1:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,41,1796]}],y2:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,60,1815]}],stroke:"darkgray"}}," ",{p:[58,9,1858],t:7,e:"text",a:{x:"0",y:[{t:2,x:{r:["yscale","."],s:"_0(_1)-5"},p:[58,24,1873]}],"text-anchor":"begin",fill:"white"},f:[{t:2,x:{r:[".","yfactor"],s:"_0*_1"},p:[58,76,1925]}," ",{t:2,r:"yunit",p:[58,92,1941]}]}],n:52,r:"yaxis",p:[56,7,1740]}," ",{t:4,f:[{p:[61,9,2011],t:7,e:"path",a:{d:[{t:2,x:{r:["area.path"],s:"_0.print()"},p:[61,18,2020]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[61,47,2049]}],opacity:"0.1"}}],n:52,i:"curve",r:"curves",p:[60,7,1980]}," ",{t:4,f:[{p:[64,9,2137],t:7,e:"path",a:{d:[{t:2,x:{r:["line.path"],s:"_0.print()"},p:[64,18,2146]}],stroke:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[64,49,2177]}],fill:"none"}}],n:52,
-i:"curve",r:"curves",p:[63,7,2106]}," ",{t:4,f:[{t:4,f:[{p:[68,11,2308],t:7,e:"circle",a:{transform:["translate(",{t:2,r:".",p:[68,40,2337]},")"],r:[{t:2,x:{r:["selected","count"],s:"_0==_1?10:4"},p:[68,51,2348]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[68,89,2386]}]},v:{mouseenter:"enter",mouseleave:"exit"}}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[67,9,2263]}],n:52,i:"curve",r:"curves",p:[66,7,2232]}," ",{t:4,f:[{t:4,f:[{t:4,f:[{p:[74,13,2605],t:7,e:"text",a:{transform:["translate(",{t:2,r:".",p:[74,40,2632]},") ",{t:2,x:{r:["count","size"],s:'_0<=_1/2?"translate(15, 4)":"translate(-15, 4)"'},p:[74,47,2639]}],"text-anchor":[{t:2,x:{r:["count","size"],s:'_0<=_1/2?"start":"end"'},p:[74,126,2718]}],fill:"white"},f:[{t:2,x:{r:["count","item","yfactor"],s:"_1[_0].y*_2"},p:[75,15,2787]}," ",{t:2,r:"yunit",p:[75,43,2815]}," @ ",{t:2,x:{r:["size","count","item","xfactor"],s:"(_0-_2[_1].x)*_3"},p:[75,55,2827]}," ",{t:2,r:"xunit",p:[75,92,2864]}]}],n:50,x:{r:["selected","count"],s:"_0==_1"},p:[73,11,2566]}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[72,9,2521]}],n:52,i:"curve",r:"curves",p:[71,7,2490]}," ",{t:4,f:[{p:[81,9,2983],t:7,e:"g",a:{transform:["translate(",{t:2,x:{r:["width","curves.length","@index"],s:"(_0/(_1+1))*(_2+1)"},p:[81,33,3007]},", 10)"]},f:[{p:[82,11,3073],t:7,e:"circle",a:{r:"4",fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[82,31,3093]}]}}," ",{p:[83,11,3124],t:7,e:"text",a:{x:"8",y:"4",fill:"white"},f:[{t:2,rx:{r:"legend",m:[{t:30,n:"curve"}]},p:[83,42,3155]}]}]}],n:52,i:"curve",r:"curves",p:[80,7,2952]}],x:{r:["graph","points","xaccessor","yaccessor","width","height"],s:"_0({data:_1,xaccessor:_2,yaccessor:_3,width:_4,height:_5})"},p:[49,5,1323]}]}]}]},e.exports=a.extend(r.exports)},{338:338,341:341}],347:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"notice"},f:[{t:16,p:[2,3,23]}]}]},e.exports=a.extend(r.exports)},{341:341}],348:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(481),a=t(483);e.exports={oninit:function(){var t=this,e=a.resize.bind(this),r=function(){return t.set({resize:!1,x:null,y:null})};this.observe("config.fancy",function(a,i,o){(0,n.winset)(t.get("config.window"),"can-resize",!a),a?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",r)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",r))}),this.on("resize",function(){return t.toggle("resize")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[28,3,739],t:7,e:"div",a:{"class":"resize"},v:{mousedown:"resize"}}],n:50,r:"config.fancy",p:[27,1,716]}]},e.exports=a.extend(r.exports)},{341:341,481:481,483:483}],349:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"section",a:{"class":[{t:4,f:["candystripe"],r:"candystripe",p:[1,17,16]}]},f:[{t:4,f:[{p:[3,5,82],t:7,e:"span",a:{"class":"label",style:[{t:4,f:["color:",{t:2,r:"labelcolor",p:[3,53,130]}],r:"labelcolor",p:[3,32,109]}]},f:[{t:2,r:"label",p:[3,84,161]},":"]}],n:50,r:"label",p:[2,3,64]}," ",{t:4,f:[{t:16,p:[6,5,210]}],n:50,r:"nowrap",p:[5,3,191]},{t:4,n:51,f:[{p:[8,5,235],t:7,e:"div",a:{"class":"content",style:[{t:4,f:["float:right;"],r:"right",p:[8,33,263]}]},f:[{t:16,p:[9,7,304]}]}],r:"nowrap"}]}]},e.exports=a.extend(r.exports)},{341:341}],350:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"subdisplay"},f:[{t:4,f:[{p:[3,5,45],t:7,e:"header",f:[{p:[4,7,60],t:7,e:"h4",f:[{t:2,r:"title",p:[4,11,64]}]}," ",{t:4,f:[{t:16,n:"button",p:[5,21,99]}],n:50,r:"button",p:[5,7,85]}]}],n:50,r:"title",p:[2,3,27]}," ",{p:[8,3,149],t:7,e:"article",f:[{t:16,p:[9,5,163]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],351:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.set("active",this.findComponent("tab").get("name")),this.on("switch",function(e){t.set("active",e.node.textContent.trim())}),this.observe("active",function(e,n,a){for(var r=t.findAllComponents("tab"),i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;p.set("shown",p.get("name")===e)}})}}}(r),r.exports.template={v:3,t:[" "," ",{p:[20,1,505],t:7,e:"header",f:[{t:4,f:[{p:[22,5,535],t:7,e:"ui-button",a:{pane:[{t:2,r:".",p:[22,22,552]}]},v:{press:"switch"},f:[{t:2,r:".",p:[22,47,577]}]}],n:52,r:"tabs",p:[21,3,516]}]}," ",{p:[25,1,617],t:7,e:"ui-display",f:[{t:8,r:"content",p:[26,3,632]}]}]},r.exports.components=r.exports.components||{};var i={tab:t(352)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,352:352}],352:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:16,p:[2,3,16]}],n:50,r:"shown",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],353:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(482),a=t(481),r=t(483);e.exports={computed:{visualStatus:function(){switch(this.get("config.status")){case n.UI_INTERACTIVE:return"good";case n.UI_UPDATE:return"average";case n.UI_DISABLED:return"bad";default:return"bad"}}},oninit:function(){var t=this,e=r.drag.bind(this),n=function(e){return t.set({drag:!1,x:null,y:null})};this.observe("config.fancy",function(r,i,o){(0,a.winset)(t.get("config.window"),"titlebar",!r&&t.get("config.titlebar")),r?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",n)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",n))}),this.on({drag:function(){this.toggle("drag")},close:function(){(0,a.winset)(this.get("config.window"),"is-visible",!1),window.location.href=(0,a.href)({command:"uiclose "+this.get("config.ref")},"winset")},minimize:function(){(0,a.winset)(this.get("config.window"),"is-minimized",!0)}})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[50,3,1391],t:7,e:"header",a:{"class":"titlebar"},v:{mousedown:"drag"},f:[{p:[51,5,1441],t:7,e:"i",a:{"class":["statusicon fa fa-eye fa-2x ",{t:2,r:"visualStatus",p:[51,42,1478]}]}}," ",{p:[52,5,1505],t:7,e:"span",a:{"class":"title"},f:[{t:16,p:[52,25,1525]}]}," ",{t:4,f:[{p:[54,7,1573],t:7,e:"i",a:{"class":"minimize fa fa-minus fa-2x"},v:{click:"minimize"}}," ",{p:[55,7,1642],t:7,e:"i",a:{"class":"close fa fa-close fa-2x"},v:{click:"close"}}],n:50,r:"config.fancy",p:[53,5,1546]}]}],n:50,r:"config.titlebar",p:[49,1,1365]}]},e.exports=a.extend(r.exports)},{341:341,481:481,482:482,483:483}],354:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";var e=[11,10,9,8];t.exports={data:{userAgent:navigator.userAgent},computed:{ie:function(){if(document.documentMode)return document.documentMode;for(var t in e){var n=document.createElement("div");if(n.innerHTML="",n.getElementsByTagName("span").length)return t}}},oninit:function(){var t=this;this.on("debug",function(){return t.toggle("debug")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[27,3,636],t:7,e:"ui-notice",f:[{p:[28,5,652],t:7,e:"span",f:["You have an old (IE",{t:2,r:"ie",p:[28,30,677]},"), end-of-life (click 'EOL Info' for more information) version of Internet Explorer installed."]},{p:[28,137,784],t:7,e:"br"}," ",{p:[29,5,794],t:7,e:"span",f:["To upgrade, click 'Upgrade IE' to download IE11 from Microsoft."]},{p:[29,81,870],t:7,e:"br"}," ",{p:[30,5,880],t:7,e:"span",f:["If you are unable to upgrade directly, click 'IE VMs' to download a VM with IE11 or Edge from Microsoft."]},{p:[30,122,997],t:7,e:"br"}," ",{p:[31,5,1007],t:7,e:"span",f:["Otherwise, click 'No Frills' below to disable potentially incompatible features (and this message)."]}," ",{p:[32,5,1124],t:7,e:"hr"}," ",{p:[33,5,1134],t:7,e:"ui-button",a:{icon:"close",action:"tgui:nofrills"},f:["No Frills"]}," ",{p:[34,5,1207],t:7,e:"ui-button",a:{icon:"internet-explorer",action:"tgui:link",params:'{"url": "http://windows.microsoft.com/en-us/internet-explorer/download-ie"}'},f:["Upgrade IE"]}," ",{p:[36,5,1381],t:7,e:"ui-button",a:{icon:"edge",action:"tgui:link",params:'{"url": "https://dev.windows.com/en-us/microsoft-edge/tools/vms"}'},f:["IE VMs"]}," ",{p:[38,5,1528],t:7,e:"ui-button",a:{icon:"info",action:"tgui:link",params:'{"url": "https://support.microsoft.com/en-us/lifecycle#gp/Microsoft-Internet-Explorer"}'},f:["EOL Info"]}," ",{p:[40,5,1699],t:7,e:"ui-button",a:{icon:"bug"},v:{press:"debug"},f:["Debug Info"]}," ",{t:4,f:[{p:[42,7,1785],t:7,e:"hr"}," ",{p:[43,7,1797],t:7,e:"span",f:["Detected: IE",{t:2,r:"ie",p:[43,25,1815]}]},{p:[43,38,1828],t:7,e:"br"}," ",{p:[44,7,1840],t:7,e:"span",f:["User Agent: ",{t:2,r:"userAgent",p:[44,25,1858]}]}],n:50,r:"debug",p:[41,5,1765]}]}],n:50,x:{r:["config.fancy","ie"],s:"_0&&_1&&_1<11"},p:[26,1,596]}]},e.exports=a.extend(r.exports)},{341:341}],355:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},shockState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[22,1,327],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[23,2,362],t:7,e:"ui-section",a:{label:"Main"},f:[{p:[24,3,390],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.main"],s:"_0(_1)"},p:[24,16,403]}]},f:[{t:2,x:{r:["data.power.main"],s:'_0?"Online":"Offline"'},p:[24,49,436]}]}," ",{t:4,f:["[ ",{p:[26,6,542],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"},p:[25,3,488]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.main_timeleft",p:[29,7,646]}," seconds left ]"],n:50,x:{r:["data.power.main_timeleft"],s:"_0>0"},p:[28,4,603]}],x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"}}," ",{p:[32,3,713],t:7,e:"div",a:{style:"float:right"},f:[{p:[33,4,742],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-main",state:[{t:2,x:{r:["data.power.main"],s:'_0?null:"disabled"'},p:[33,63,801]}]},f:["Disrupt"]}]}]}," ",{p:[36,2,887],t:7,e:"ui-section",a:{label:"Backup"},f:[{p:[37,3,917],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.backup"],s:"_0(_1)"},p:[37,16,930]}]},f:[{t:2,x:{r:["data.power.backup"],s:'_0?"Online":"Offline"'},p:[37,51,965]}]}," ",{t:4,f:["[ ",{p:[39,6,1077],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"},p:[38,3,1019]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.backup_timeleft",p:[42,7,1183]}," seconds left ]"],n:50,x:{r:["data.power.backup_timeleft"],s:"_0>0"},p:[41,4,1138]}],x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"}}," ",{p:[45,3,1252],t:7,e:"div",a:{style:"float:right"},f:[{p:[46,4,1281],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-backup",state:[{t:2,x:{r:["data.power.backup"],s:'_0?null:"disabled"'},p:[46,65,1342]}]},f:["Disrupt"]}]}]}," ",{p:[49,2,1430],t:7,e:"ui-section",a:{label:"Electrify"},f:[{p:[50,3,1463],t:7,e:"span",a:{"class":[{t:2,x:{r:["shockState","data.shock"],s:"_0(_1)"},p:[50,16,1476]}]},f:[{t:2,x:{r:["data.shock"],s:'_0==2?"Safe":"Electrified"'},p:[50,44,1504]}]}," ",{t:4,f:["[ ",{p:[52,6,1589],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.shock"],s:"!_0"},p:[51,3,1558]},{t:4,n:51,f:[{t:4,f:["[ ",{p:[55,7,1688],t:7,e:"span",a:{"class":"bad"},f:[{t:2,r:"data.shock_timeleft",p:[55,25,1706]}," seconds left"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0>0"},p:[54,4,1650]}," ",{t:4,f:["[ ",{p:[58,7,1806],t:7,e:"span",a:{"class":"bad"},f:["Permanent"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0==-1"},p:[57,4,1766]}],x:{r:["data.wires.shock"],s:"!_0"}}," ",{p:[61,3,1866],t:7,e:"div",a:{style:"float:right"},f:[{p:[62,4,1895],t:7,e:"ui-button",a:{icon:"wrench",action:"shock-restore",state:[{t:2,x:{r:["data.wires.shock","data.shock"],s:'_0&&_1==0?null:"disabled"'},p:[62,59,1950]}]},f:["Restore"]}," ",{p:[63,4,2032],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-temp",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[63,54,2082]}]},f:["Set (Temporary)"]}," ",{p:[64,4,2136],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-perm",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[64,53,2185]}]},f:["Set (Permanent)"]}]}]}]}," ",{p:[68,1,2274],t:7,e:"ui-display",a:{title:"Access & Door Control"},f:[{p:[69,2,2318],t:7,e:"ui-section",a:{label:"ID Scan"},f:[{t:4,f:["[ ",{p:[71,6,2385],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[70,3,2349]}," ",{p:[73,3,2444],t:7,e:"div",a:{style:"float:right"},f:[{p:[74,4,2473],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[74,22,2491]}],icon:"power-off",action:"idscan-on",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"selected":""'},p:[74,93,2562]}]},f:["Enabled"]}," ",{p:[75,4,2624],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[75,22,2642]}],icon:"close",action:"idscan-off",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"":"selected"'},p:[75,90,2710]}]},f:["Disabled"]}]}]}," ",{p:[78,2,2795],t:7,e:"ui-section",a:{label:"Emergency Access"},f:[{p:[79,3,2835],t:7,e:"div",a:{style:"float:right"},f:[{p:[80,4,2864],t:7,e:"ui-button",a:{icon:"power-off",action:"emergency-on",style:[{t:2,x:{r:["data.emergency"],s:'_0?"selected":""'},p:[80,61,2921]}]},f:["Enabled"]}," ",{p:[81,4,2982],t:7,e:"ui-button",a:{icon:"close",action:"emergency-off",style:[{t:2,x:{r:["data.emergency"],s:'_0?"":"selected"'},p:[81,58,3036]}]},f:["Disabled"]}]}]}," ",{p:[84,2,3120],t:7,e:"br"}," ",{p:[85,2,3128],t:7,e:"ui-section",a:{label:"Door bolts"},f:[{t:4,f:["[ ",{p:[87,6,3193],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.bolts"],s:"!_0"},p:[86,3,3162]}," ",{p:[89,3,3252],t:7,e:"div",a:{style:"float:right"},f:[{p:[90,4,3281],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[90,22,3299]}],icon:"unlock",action:"bolt-raise",style:[{t:2,x:{r:["data.locked"],s:'_0?"":"selected"'},p:[90,85,3362]}]},f:["Raised"]}," ",{p:[91,4,3419],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[91,22,3437]}],icon:"lock",action:"bolt-drop",style:[{t:2,x:{r:["data.locked"],s:'_0?"selected":""'},p:[91,82,3497]}]},f:["Dropped"]}]}]}," ",{p:[94,2,3577],t:7,e:"ui-section",a:{label:"Door bolt lights"},f:[{t:4,f:["[ ",{p:[96,6,3649],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.lights"],s:"!_0"},p:[95,3,3617]}," ",{p:[98,3,3708],t:7,e:"div",a:{style:"float:right"},f:[{p:[99,4,3737],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[99,22,3755]}],icon:"power-off",action:"light-on",style:[{t:2,x:{r:["data.lights"],s:'_0?"selected":""'},p:[99,88,3821]}]},f:["Enabled"]}," ",{p:[100,4,3879],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[100,22,3897]}],icon:"close",action:"light-off",style:[{t:2,x:{r:["data.lights"],s:'_0?"":"selected"'},p:[100,85,3960]}]},f:["Disabled"]}]}]}," ",{p:[103,2,4041],t:7,e:"ui-section",a:{label:"Door force sensors"},f:[{t:4,f:["[ ",{p:[105,6,4113],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.safe"],s:"!_0"},p:[104,3,4083]}," ",{p:[107,3,4172],t:7,e:"div",a:{style:"float:right"},f:[{p:[108,4,4201],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[108,22,4219]}],icon:"power-off",action:"safe-on",style:[{t:2,x:{r:["data.safe"],s:'_0?"selected":""'},p:[108,85,4282]}]},f:["Enabled"]}," ",{p:[109,4,4338],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[109,22,4356]}],icon:"close",action:"safe-off",style:[{t:2,x:{r:["data.safe"],s:'_0?"":"selected"'},p:[109,82,4416]}]},f:["Disabled"]}]}]}," ",{p:[112,2,4495],t:7,e:"ui-section",a:{label:"Door timing safety"},f:[{t:4,f:["[ ",{p:[114,6,4569],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.timing"],s:"!_0"},p:[113,3,4537]}," ",{p:[116,3,4628],t:7,e:"div",a:{style:"float:right"},f:[{p:[117,4,4657],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[117,22,4675]}],icon:"power-off",action:"speed-on",style:[{t:2,x:{r:["data.speed"],s:'_0?"selected":""'},p:[117,88,4741]}]},f:["Enabled"]}," ",{p:[118,4,4798],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[118,22,4816]}],icon:"close",action:"speed-off",style:[{t:2,x:{r:["data.speed"],s:'_0?"":"selected"'},p:[118,85,4879]}]},f:["Disabled"]}]}]}," ",{p:[121,2,4959],t:7,e:"br"}," ",{p:[122,2,4967],t:7,e:"ui-section",a:{label:"Door control"},f:[{t:4,f:["[ ",{p:[124,6,5043],t:7,e:"span",a:{"class":"bad"},f:["Door is ",{t:2,x:{r:["data.locked","data.welded"],s:'(_0?"bolted":"")+(_0&&_1?" and ":"")+(_1?"welded":"")'},p:[124,32,5069]}]}," ]"],n:50,x:{r:["data.locked","data.welded"],s:"_0||_1"},p:[123,3,5003]}," ",{p:[126,3,5202],t:7,e:"div",a:{style:"float:right"},f:[{p:[127,4,5231],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(_2&&"disabled")'},p:[127,22,5249]}],icon:"sign-out",action:"open-close"},f:["Open door"]}," ",{p:[128,4,5375],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(!_2&&"disabled")'},p:[128,22,5393]}],icon:"sign-in",action:"open-close"},f:["Close door"]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],356:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," ",{p:[7,1,261],t:7,e:"ui-notice",f:[{t:4,f:[{p:[9,5,304],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[10,7,346],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[10,24,363]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[10,75,414]}]}]}],n:50,r:"data.siliconUser",p:[8,3,275]},{t:4,n:51,f:[{p:[13,5,502],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,31,528]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[16,1,610],t:7,e:"status"}," ",{t:4,f:[{t:4,f:[{p:[19,7,701],t:7,e:"ui-display",a:{title:"Air Controls"},f:[{p:[20,9,743],t:7,e:"ui-section",f:[{p:[21,11,766],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"exclamation-triangle":"exclamation"'},p:[21,28,783]}],style:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"caution":null'},p:[21,98,853]}],action:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"reset":"alarm"'},p:[22,23,916]}]},f:["Area Atmosphere Alarm"]}]}," ",{p:[24,9,1022],t:7,e:"ui-section",f:[{p:[25,11,1045],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==3?"exclamation-triangle":"exclamation"'},p:[25,28,1062]}],style:[{t:2,x:{r:["data.mode"],s:'_0==3?"danger":null'},p:[25,96,1130]}],action:"mode",params:['{"mode": ',{t:2,x:{r:["data.mode"],s:"_0==3?1:3"},p:[26,44,1211]},"}"]},f:["Panic Siphon"]}]}," ",{p:[28,9,1295],t:7,e:"br"}," ",{p:[29,9,1309],t:7,e:"ui-section",f:[{p:[30,11,1332],t:7,e:"ui-button",a:{icon:"sign-out",action:"tgui:view",params:'{"screen": "vents"}'},f:["Vent Controls"]}]}," ",{p:[32,9,1463],t:7,e:"ui-section",f:[{p:[33,11,1486],t:7,e:"ui-button",a:{icon:"filter",action:"tgui:view",params:'{"screen": "scrubbers"}'},f:["Scrubber Controls"]}]}," ",{p:[35,9,1623],t:7,e:"ui-section",f:[{p:[36,11,1646],t:7,e:"ui-button",a:{icon:"cog",action:"tgui:view",params:'{"screen": "modes"}'},f:["Operating Mode"]}]}," ",{p:[38,9,1773],t:7,e:"ui-section",f:[{p:[39,11,1796],t:7,e:"ui-button",a:{icon:"bar-chart",action:"tgui:view",params:'{"screen": "thresholds"}'},f:["Alarm Thresholds"]}]}]}],n:50,x:{r:["config.screen"],s:'_0=="home"'},p:[18,3,663]},{t:4,n:51,f:[{t:4,n:50,x:{r:["config.screen"],s:'_0=="vents"'},f:[{p:[43,5,1990],t:7,e:"vents"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&(_0=="scrubbers")'},f:[" ",{p:[45,5,2045],t:7,e:"scrubbers"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&(_0=="modes"))'},f:[" ",{p:[47,5,2100],t:7,e:"modes"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&((!(_0=="modes"))&&(_0=="thresholds")))'},f:[" ",{p:[49,5,2156],t:7,e:"thresholds"}]}],x:{r:["config.screen"],s:'_0=="home"'}}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[17,1,620]}]},r.exports.components=r.exports.components||{};var i={vents:t(362),modes:t(358),thresholds:t(361),status:t(360),scrubbers:t(359)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,358:358,359:359,360:360,361:361,362:362}],357:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-button",a:{icon:"arrow-left",action:"tgui:view",params:'{"screen": "home"}'},f:["Back"]}]},e.exports=a.extend(r.exports)},{341:341}],358:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,111],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Operating Modes",button:0},f:[" ",{t:4,f:[{p:[8,5,161],t:7,e:"ui-section",f:[{p:[9,7,180],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["selected"],s:'_0?"check-square-o":"square-o"'},p:[9,24,197]}],state:[{t:2,x:{r:["selected","danger"],s:'_0?_1?"danger":"selected":null'},p:[10,16,258]}],action:"mode",params:['{"mode": ',{t:2,r:"mode",p:[11,40,351]},"}"]},f:[{t:2,r:"name",p:[11,51,362]}]}]}],n:52,r:"data.modes",p:[7,3,136]}]}]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],359:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," ",{p:{button:[{p:[6,5,180],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Scrubber Controls",button:0},f:[" ",{t:4,f:[{p:[9,5,234],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[9,27,256]}]},f:[{p:[10,7,278],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,313],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[11,26,330]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[11,68,372]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[12,46,448]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[12,66,468]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[12,80,482]}]}]}," ",{p:[14,7,545],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[15,9,579],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["scrubbing"],s:'_0?"filter":"sign-in"'},p:[15,26,596]}],style:[{t:2,x:{r:["scrubbing"],s:'_0?null:"danger"'},p:[15,71,641]}],action:"scrubbing",params:['{"id_tag": "',{t:2,r:"id_tag",p:[16,50,723]},'", "val": ',{t:2,x:{r:["scrubbing"],s:"+!_0"},p:[16,70,743]},"}"]},f:[{t:2,x:{r:["scrubbing"],s:'_0?"Scrubbing":"Siphoning"'},p:[16,88,761]}]}]}," ",{p:[18,7,841],t:7,e:"ui-section",a:{label:"Range"},f:[{p:[19,9,876],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["widenet"],s:'_0?"expand":"compress"'},p:[19,26,893]}],style:[{t:2,x:{r:["widenet"],s:'_0?"selected":null'},p:[19,70,937]}],action:"widenet",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,1017]},'", "val": ',{t:2,x:{r:["widenet"],s:"+!_0"},p:[20,68,1037]},"}"]},f:[{t:2,x:{r:["widenet"],s:'_0?"Expanded":"Normal"'},p:[20,84,1053]}]}]}," ",{p:[22,7,1127],t:7,e:"ui-section",a:{label:"Filters"},f:[{p:[23,9,1164],t:7,e:"filters"}]}]}],n:52,r:"data.scrubbers",p:[8,3,205]},{t:4,n:51,f:[{p:[27,5,1231],t:7,e:"span",a:{"class":"bad"},f:["Error: No scrubbers connected."]}],r:"data.scrubbers"}]}]},r.exports.components=r.exports.components||{};var i={filters:t(457),back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357,457:457}],360:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Air Status"},f:[{t:4,f:[{t:4,f:[{p:[4,7,107],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[4,26,126]}]},f:[{p:[5,6,142],t:7,e:"span",a:{"class":[{t:2,x:{r:["danger_level"],s:'_0==2?"bad":_0==1?"average":"good"'},p:[5,19,155]}]},f:[{t:2,x:{r:["value"],s:"Math.fixed(_0,2)"},p:[6,5,232]},{t:2,r:"unit",p:[6,29,256]}]}]}],n:52,r:"adata.environment_data",p:[3,5,68]}," ",{p:[10,5,313],t:7,e:"ui-section",a:{label:"Local Status"},f:[{p:[11,7,353],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.danger_level"],s:'_0==2?"bad bold":_0==1?"average bold":"good"'},p:[11,20,366]}]},f:[{t:2,x:{r:["data.danger_level"],s:'_0==2?"Danger (Internals Required)":_0==1?"Caution":"Optimal"'},p:[12,6,464]}]}]}," ",{p:[15,5,605],t:7,e:"ui-section",a:{label:"Area Status"},f:[{p:[16,7,644],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.atmos_alarm","data.fire_alarm"],s:'_0||_1?"bad bold":"good"'},p:[16,20,657]}]},f:[{t:2,x:{r:["data.atmos_alarm","fire_alarm"],s:'_0?"Atmosphere Alarm":_1?"Fire Alarm":"Nominal"'},p:[17,8,728]}]}]}],n:50,r:"data.environment_data",p:[2,3,34]},{t:4,n:51,f:[{p:[21,5,856],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[22,7,891],t:7,e:"span",a:{"class":"bad bold"},f:["Cannot obtain air sample for analysis."]}]}],r:"data.environment_data"}," ",{t:4,f:[{p:[26,5,1015],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[27,7,1050],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[25,3,990]}]}]},e.exports=a.extend(r.exports)},{341:341}],361:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.css=" th, td {\n padding-right: 16px;\n text-align: left;\n }",r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,112],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Alarm Thresholds",button:0},f:[" ",{p:[7,3,137],t:7,e:"table",f:[{p:[8,5,149],t:7,e:"thead",f:[{p:[8,12,156],t:7,e:"tr",f:[{p:[9,7,167],t:7,e:"th"}," ",{p:[10,7,183],t:7,e:"th",f:[{p:[10,11,187],t:7,e:"span",a:{"class":"bad"},f:["min2"]}]}," ",{p:[11,7,228],t:7,e:"th",f:[{p:[11,11,232],t:7,e:"span",a:{"class":"average"},f:["min1"]}]}," ",{p:[12,7,277],t:7,e:"th",f:[{p:[12,11,281],t:7,e:"span",a:{"class":"average"},f:["max1"]}]}," ",{p:[13,7,326],t:7,e:"th",f:[{p:[13,11,330],t:7,e:"span",a:{"class":"bad"},f:["max2"]}]}]}]}," ",{p:[15,5,387],t:7,e:"tbody",f:[{t:4,f:[{p:[16,32,426],t:7,e:"tr",f:[{p:[17,9,439],t:7,e:"th",f:[{t:3,r:"name",p:[17,13,443]}]}," ",{t:4,f:[{p:[18,27,485],t:7,e:"td",f:[{p:[19,11,500],t:7,e:"ui-button",a:{action:"threshold",params:['{"env": "',{t:2,r:"env",p:[19,58,547]},'", "var": "',{t:2,r:"val",p:[19,76,565]},'"}']},f:[{t:2,x:{r:["selected"],s:"Math.fixed(_0,2)"},p:[19,87,576]}]}]}],n:52,r:"settings",p:[18,9,467]}]}],n:52,r:"data.thresholds",p:[16,7,401]}]}," ",{p:[23,3,675],t:7,e:"table",f:[]}]}]}," "]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],362:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,109],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Vent Controls",button:0},f:[" ",{t:4,f:[{p:[8,5,159],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[8,27,181]}]},f:[{p:[9,7,203],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[10,9,238],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[10,26,255]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[10,68,297]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[11,46,373]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[11,66,393]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[11,80,407]}]}]}," ",{p:[13,7,470],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[14,9,504],t:7,e:"span",f:[{t:2,x:{r:["direction"],s:'_0=="release"?"Pressurizing":"Siphoning"'},p:[14,15,510]}]}]}," ",{p:[16,7,601],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[17,9,649],t:7,e:"ui-button",a:{icon:"sign-in",style:[{t:2,x:{r:["incheck"],s:'_0?"selected":null'},p:[17,42,682]}],action:"incheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[18,48,762]},'", "val": ',{t:2,r:"checks",p:[18,68,782]},"}"]},f:["Internal"]}," ",{p:[19,9,824],t:7,e:"ui-button",a:{icon:"sign-out",style:[{t:2,x:{r:["excheck"],s:'_0?"selected":null'},p:[19,43,858]}],action:"excheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,938]},'", "val": ',{t:2,r:"checks",p:[20,68,958]},"}"]},f:["External"]}]}," ",{t:4,f:[{p:[23,9,1042],t:7,e:"ui-section",a:{label:"Internal Target Pressure"},f:[{p:[24,11,1098],t:7,e:"ui-button",a:{icon:"pencil",action:"set_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[25,33,1186]},'"}']},f:[{t:2,x:{r:["internal"],s:"Math.fixed(_0)"},p:[25,47,1200]}]}," ",{p:[26,11,1247],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["intdefault"],s:'_0?"disabled":null'},p:[26,44,1280]}],action:"reset_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[27,33,1381]},'"}']},f:["Reset"]}]}],n:50,r:"incheck",p:[22,7,1018]}," ",{t:4,f:[{p:[31,11,1481],t:7,e:"ui-section",a:{label:"External Target Pressure"},f:[{p:[32,13,1539],t:7,e:"ui-button",a:{icon:"pencil",action:"set_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[33,35,1629]},'"}']},f:[{t:2,x:{r:["external"],s:"Math.fixed(_0)"},p:[33,49,1643]}]}," ",{p:[34,13,1692],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["extdefault"],s:'_0?"disabled":null'},p:[34,46,1725]}],action:"reset_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[35,35,1828]},'"}']},f:["Reset"]}]}],n:50,r:"excheck",p:[30,7,1455]}]}],n:52,r:"data.vents",p:[7,3,134]},{t:4,n:51,f:[{p:[40,5,1934],t:7,e:"span",a:{"class":"bad"},f:["Error: No vents connected."]}],r:"data.vents"}]}]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],363:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.css=" table {\n width: 100%;\n border-spacing: 2px;\n }\n th {\n text-align: left;\n }\n td {\n vertical-align: top;\n }\n td .button {\n margin-top: 4px\n }",r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,15],t:7,e:"ui-section",f:[{p:[3,5,32],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oneAccess"],s:'_0?"unlock":"lock"'},p:[3,22,49]}],action:"one_access"},f:[{t:2,x:{r:["data.oneAccess"],s:'_0?"One":"All"'},p:[3,82,109]}," Required"]}," ",{p:[4,5,169],t:7,e:"ui-button",a:{icon:"refresh",action:"clear"},f:["Clear"]}]}," ",{p:[6,3,246],t:7,e:"hr"}," ",{p:[7,3,254],t:7,e:"table",f:[{p:[8,3,264],t:7,e:"thead",f:[{p:[9,4,275],t:7,e:"tr",f:[{t:4,f:[{p:[10,5,306],t:7,e:"th",f:[{p:[10,9,310],t:7,e:"span",a:{"class":"highlight bold"},f:[{t:2,r:"name",p:[10,38,339]}]}]}],n:52,r:"data.regions",p:[9,8,279]}]}]}," ",{p:[13,3,391],t:7,e:"tbody",f:[{p:[14,4,402],t:7,e:"tr",f:[{t:4,f:[{p:[15,5,433],t:7,e:"td",f:[{t:4,f:[{p:[16,11,466],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["req"],s:'_0?"check-square-o":"square-o"'},p:[16,28,483]}],style:[{t:2,x:{r:["req"],s:'_0?"selected":null'},p:[16,76,531]}],action:"set",params:['{"access": "',{t:2,r:"id",p:[17,46,605]},'"}']},f:[{t:2,r:"name",p:[17,56,615]}]}," ",{p:[18,9,644],t:7,e:"br"}],n:52,r:"accesses",p:[15,9,437]}]}],n:52,r:"data.regions",p:[14,8,406]}]}]}]}," ",{p:[23,2,709],t:7,e:"hr"}," ",{p:[24,2,716],t:7,e:"span",a:{"class":"highlight bold"},f:["Unrestricted Access:"]}," ",{p:[25,2,774],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&1?"check-square-o":"square-o"'},p:[25,19,791]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&1?"selected":null'},p:[25,88,860]}],action:"direc_set",params:'{"unres_direction": "1"}'},f:["North"]}," ",{p:[26,2,982],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&4?"check-square-o":"square-o"'},p:[26,19,999]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&4?"selected":null'},p:[26,88,1068]}],action:"direc_set",params:'{"unres_direction": "4"}'},f:["East"]}," ",{p:[27,2,1189],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&2?"check-square-o":"square-o"'},p:[27,19,1206]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&2?"selected":null'
-},p:[27,88,1275]}],action:"direc_set",params:'{"unres_direction": "2"}'},f:["South"]}," ",{p:[28,2,1397],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&8?"check-square-o":"square-o"'},p:[28,19,1414]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&8?"selected":null'},p:[28,88,1483]}],action:"direc_set",params:'{"unres_direction": "8"}'},f:["West"]}]}," "]},e.exports=a.extend(r.exports)},{341:341}],364:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}},computed:{malfAction:function(){switch(this.get("data.malfStatus")){case 1:return"hack";case 2:return"occupy";case 3:return"deoccupy"}},malfButton:function(){switch(this.get("data.malfStatus")){case 1:return"Override Programming";case 2:case 4:return"Shunt Core Process";case 3:return"Return to Main Core"}},malfIcon:function(){switch(this.get("data.malfStatus")){case 1:return"terminal";case 2:case 4:return"caret-square-o-down";case 3:return"caret-square-o-left"}},powerCellStatusState:function(){var t=this.get("data.powerCellStatus");return t>50?"good":t>25?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[46,2,1161],t:7,e:"ui-notice",f:[{p:[47,3,1175],t:7,e:"b",f:[{p:[47,6,1178],t:7,e:"h3",f:["SYSTEM FAILURE"]}]}," ",{p:[48,3,1208],t:7,e:"i",f:["I/O regulators malfunction detected! Waiting for system reboot..."]},{p:[48,75,1280],t:7,e:"br"}," Automatic reboot in ",{t:2,r:"data.failTime",p:[49,23,1307]}," seconds... ",{p:[50,3,1338],t:7,e:"ui-button",a:{icon:"refresh",action:"reboot"},f:["Reboot Now"]},{p:[50,67,1402],t:7,e:"br"},{p:[50,71,1406],t:7,e:"br"},{p:[50,75,1410],t:7,e:"br"}]}],n:50,r:"data.failTime",p:[45,1,1138]},{t:4,n:51,f:[{p:[53,2,1439],t:7,e:"ui-notice",f:[{t:4,f:[{p:[55,3,1481],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[56,5,1521],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[56,22,1538]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[56,73,1589]}]}]}],n:50,r:"data.siliconUser",p:[54,4,1454]},{t:4,n:51,f:[{p:[59,3,1674],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[59,29,1700]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[62,2,1785],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[63,4,1822],t:7,e:"ui-section",a:{label:"Main Breaker"},f:[{t:4,f:[{p:[65,5,1903],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isOperating"],s:'_0?"good":"bad"'},p:[65,18,1916]}]},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[65,57,1955]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[64,3,1858]},{t:4,n:51,f:[{p:[67,5,2013],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[67,22,2030]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[67,75,2083]}],action:"breaker"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[68,21,2145]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}," ",{p:[71,4,2223],t:7,e:"ui-section",a:{label:"External Power"},f:[{p:[72,3,2261],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.externalPower"],s:"_0(_1)"},p:[72,16,2274]}]},f:[{t:2,x:{r:["data.externalPower"],s:'_0==2?"Good":_0==1?"Low":"None"'},p:[72,52,2310]}]}]}," ",{p:[74,4,2417],t:7,e:"ui-section",a:{label:"Power Cell"},f:[{t:4,f:[{p:[76,5,2492],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerCellStatus",p:[76,38,2525]}],state:[{t:2,r:"powerCellStatusState",p:[76,71,2558]}]},f:[{t:2,x:{r:["adata.powerCellStatus"],s:"Math.fixed(_0)"},p:[76,97,2584]},"%"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[75,3,2451]},{t:4,n:51,f:[{p:[78,5,2647],t:7,e:"span",a:{"class":"bad"},f:["Removed"]}],x:{r:["data.powerCellStatus"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[82,3,2749],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{t:4,f:[{p:[84,4,2830],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.chargeMode"],s:'_0?"good":"bad"'},p:[84,17,2843]}]},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[84,55,2881]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[83,5,2786]},{t:4,n:51,f:[{p:[86,4,2941],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.chargeMode"],s:'_0?"refresh":"close"'},p:[86,21,2958]}],style:[{t:2,x:{r:["data.chargeMode"],s:'_0?"selected":null'},p:[86,71,3008]}],action:"charge"},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[87,22,3070]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}," [",{p:[90,6,3147],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.chargingStatus"],s:"_0(_1)"},p:[90,19,3160]}]},f:[{t:2,x:{r:["data.chargingStatus"],s:'_0==2?"Fully Charged":_0==1?"Charging":"Not Charging"'},p:[90,56,3197]}]},"]"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[81,4,2710]}]}," ",{p:[94,2,3352],t:7,e:"ui-display",a:{title:"Power Channels"},f:[{t:4,f:[{p:[96,3,3422],t:7,e:"ui-section",a:{label:[{t:2,r:"title",p:[96,22,3441]}],nowrap:0},f:[{p:[97,5,3464],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.powerChannels",m:[{t:30,n:"@index"},"powerLoad"]},p:[97,26,3485]}]}," ",{p:[98,5,3537],t:7,e:"div",a:{"class":"content"},f:[{p:[98,26,3558],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0>=2?"good":"bad"'},p:[98,39,3571]}]},f:[{t:2,x:{r:["status"],s:'_0>=2?"On":"Off"'},p:[98,73,3605]}]}]}," ",{p:[99,5,3653],t:7,e:"div",a:{"class":"content"},f:["[",{p:[99,27,3675],t:7,e:"span",f:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"Auto":"Manual"'},p:[99,33,3681]}]},"]"]}," ",{p:[100,5,3750],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{t:4,f:[{p:[102,6,3841],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"selected":null'},p:[102,39,3874]}],action:"channel",params:[{t:2,r:"topicParams.auto",p:[103,30,3955]}]},f:["Auto"]}," ",{p:[104,6,3999],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["status"],s:'_0==2?"selected":null'},p:[104,41,4034]}],action:"channel",params:[{t:2,r:"topicParams.on",p:[105,13,4100]}]},f:["On"]}," ",{p:[106,6,4140],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["status"],s:'_0==0?"selected":null'},p:[106,37,4171]}],action:"channel",params:[{t:2,r:"topicParams.off",p:[107,13,4237]}]},f:["Off"]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[101,4,3795]}]}]}],n:52,r:"data.powerChannels",p:[95,4,3391]}," ",{p:[112,4,4328],t:7,e:"ui-section",a:{label:"Total Load"},f:[{p:[113,3,4362],t:7,e:"span",a:{"class":"bold"},f:[{t:2,r:"adata.totalLoad",p:[113,22,4381]}]}]}]}," ",{t:4,f:[{p:[117,4,4469],t:7,e:"ui-display",a:{title:"System Overrides"},f:[{p:[118,3,4509],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"overload"},f:["Overload"]}," ",{t:4,f:[{p:[120,5,4608],t:7,e:"ui-button",a:{icon:[{t:2,r:"malfIcon",p:[120,22,4625]}],state:[{t:2,x:{r:["data.malfStatus"],s:'_0==4?"disabled":null'},p:[120,43,4646]}],action:[{t:2,r:"malfAction",p:[120,97,4700]}]},f:[{t:2,r:"malfButton",p:[120,113,4716]}]}],n:50,r:"data.malfStatus",p:[119,3,4580]}]}],n:50,r:"data.siliconUser",p:[116,2,4441]}," ",{p:[124,2,4780],t:7,e:"ui-notice",f:[{p:[125,4,4795],t:7,e:"ui-section",a:{label:"Emergency Light Fallback"},f:[{t:4,f:[{p:[127,8,4894],t:7,e:"span",f:[{t:2,x:{r:["data.emergencyLights"],s:'_0?"Enabled":"Disabled"'},p:[127,14,4900]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[126,6,4846]},{t:4,n:51,f:[{p:[129,8,4978],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"emergency_lighting"},f:[{t:2,x:{r:["data.emergencyLights"],s:'_0?"Enabled":"Disabled"'},p:[129,66,5036]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}," ",{p:[133,2,5143],t:7,e:"ui-notice",f:[{p:[134,4,5158],t:7,e:"ui-section",a:{label:"Night Shift Lighting"},f:[{t:4,f:[{p:[136,8,5253],t:7,e:"span",f:[{t:2,x:{r:["data.nightshiftLights"],s:'_0?"Enabled":"Disabled"'},p:[136,14,5259]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[135,6,5205]},{t:4,n:51,f:[{p:[138,8,5338],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"toggle_nightshift"},f:[{t:2,x:{r:["data.nightshiftLights"],s:'_0?"Enabled":"Disabled"'},p:[138,65,5395]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}," ",{p:[142,2,5503],t:7,e:"ui-notice",f:[{p:[143,4,5518],t:7,e:"ui-section",a:{label:"Cover Lock"},f:[{t:4,f:[{p:[145,5,5597],t:7,e:"span",f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[145,11,5603]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[144,3,5552]},{t:4,n:51,f:[{p:[147,5,5673],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.coverLocked"],s:'_0?"lock":"unlock"'},p:[147,22,5690]}],action:"cover"},f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[147,79,5747]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}],r:"data.failTime"}]},e.exports=a.extend(r.exports)},{341:341}],365:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Alarms"},f:[{p:[2,3,30],t:7,e:"ul",f:[{t:4,f:[{p:[4,7,69],t:7,e:"li",f:[{p:[4,11,73],t:7,e:"ui-button",a:{icon:"close",style:"danger",action:"clear",params:['{"zone": "',{t:2,r:".",p:[4,83,145]},'"}']},f:[{t:2,r:".",p:[4,92,154]}]}]}],n:52,r:"data.priority",p:[3,5,39]},{t:4,n:51,f:[{p:[6,7,196],t:7,e:"li",f:[{p:[6,11,200],t:7,e:"span",a:{"class":"good"},f:["No Priority Alerts"]}]}],r:"data.priority"}," ",{t:4,f:[{p:[9,7,295],t:7,e:"li",f:[{p:[9,11,299],t:7,e:"ui-button",a:{icon:"close",style:"caution",action:"clear",params:['{"zone": "',{t:2,r:".",p:[9,84,372]},'"}']},f:[{t:2,r:".",p:[9,93,381]}]}]}],n:52,r:"data.minor",p:[8,5,268]},{t:4,n:51,f:[{p:[11,7,423],t:7,e:"li",f:[{p:[11,11,427],t:7,e:"span",a:{"class":"good"},f:["No Minor Alerts"]}]}],r:"data.minor"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],366:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.tank","data.sensors.0.long_name"],s:"_0?_1:null"},p:[1,20,19]}]},f:[{t:4,f:[{p:[3,5,100],t:7,e:"ui-subdisplay",a:{title:[{t:2,x:{r:["data.tank","long_name"],s:"!_0?_1:null"},p:[3,27,122]}]},f:[{p:[4,7,164],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[5,3,196],t:7,e:"span",f:[{t:2,x:{r:["pressure"],s:"Math.fixed(_0,2)"},p:[5,9,202]}," kPa"]}]}," ",{t:4,f:[{p:[8,9,295],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[9,11,338],t:7,e:"span",f:[{t:2,x:{r:["temperature"],s:"Math.fixed(_0,2)"},p:[9,17,344]}," K"]}]}],n:50,r:"temperature",p:[7,7,267]}," ",{t:4,f:[{p:[13,9,450],t:7,e:"ui-section",a:{label:[{t:2,r:"id",p:[13,28,469]}]},f:[{p:[14,5,482],t:7,e:"span",f:[{t:2,x:{r:["."],s:"Math.fixed(_0,2)"},p:[14,11,488]},"%"]}]}],n:52,i:"id",r:"gases",p:[12,4,423]}]}],n:52,r:"adata.sensors",p:[2,3,72]}]}," ",{t:4,f:[{p:{button:[{p:[23,5,682],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[25,5,768],t:7,e:"ui-section",a:{label:"Input Injector"},f:[{p:[26,7,810],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputting"],s:'_0?"power-off":"close"'},p:[26,24,827]}],style:[{t:2,x:{r:["data.inputting"],s:'_0?"selected":null'},p:[26,75,878]}],action:"input"},f:[{t:2,x:{r:["data.inputting"],s:'_0?"Injecting":"Off"'},p:[27,9,942]}]}]}," ",{p:[29,5,1016],t:7,e:"ui-section",a:{label:"Input Rate"},f:[{p:[30,7,1054],t:7,e:"span",f:[{t:2,x:{r:["adata.inputRate"],s:"Math.fixed(_0)"},p:[30,13,1060]}," L/s"]}]}," ",{p:[32,5,1125],t:7,e:"ui-section",a:{label:"Output Regulator"},f:[{p:[33,7,1169],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputting"],s:'_0?"power-off":"close"'},p:[33,24,1186]}],style:[{t:2,x:{r:["data.outputting"],s:'_0?"selected":null'},p:[33,76,1238]}],action:"output"},f:[{t:2,x:{r:["data.outputting"],s:'_0?"Open":"Closed"'},p:[34,9,1304]}]}]}," ",{p:[36,5,1377],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[37,7,1420],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure"},f:[{t:2,x:{r:["adata.outputPressure"],s:"Math.round(_0)"},p:[37,50,1463]}," kPa"]}]}]}],n:50,r:"data.tank",p:[20,1,599]}]},e.exports=a.extend(r.exports)},{341:341}],367:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,15],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,46],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,63]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,107]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,161]}]}]}," ",{p:[6,3,218],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,259],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,353],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,383]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,510],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[9,11,516]}," kPa"]}]}," ",{p:[11,3,576],t:7,e:"ui-section",a:{label:"Filter"},f:[{t:4,f:[{p:[13,7,642],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[13,25,660]}],action:"filter",params:['{"mode": ',{t:2,r:"id",p:[14,42,735]},"}"]},f:[{t:2,r:"name",p:[14,51,744]}]}],n:52,r:"data.filter_types",p:[12,5,608]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],368:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,15],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,46],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,63]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,107]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,161]}]}]}," ",{p:[6,3,218],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,259],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,353],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.set_pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,383]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,514],t:7,e:"span",f:[{t:2,x:{r:["adata.set_pressure"],s:"Math.round(_0)"},p:[9,11,520]}," kPa"]}]}," ",{p:[11,3,584],t:7,e:"ui-section",a:{label:"Node 1"},f:[{p:[12,5,616],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[12,44,655]}],action:"node1",params:'{"concentration": -0.1}'}}," ",{p:[14,5,770],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[14,39,804]}],action:"node1",params:'{"concentration": -0.01}'}}," ",{p:[16,5,920],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[16,38,953]}],action:"node1",params:'{"concentration": 0.01}'}}," ",{p:[18,5,1070],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[18,43,1108]}],action:"node1",params:'{"concentration": 0.1}'}}," ",{p:[20,5,1224],t:7,e:"span",f:[{t:2,x:{r:["adata.node1_concentration"],s:"Math.round(_0)"},p:[20,11,1230]},"%"]}]}," ",{p:[22,3,1298],t:7,e:"ui-section",a:{label:"Node 2"},f:[{p:[23,5,1330],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[23,44,1369]}],action:"node2",params:'{"concentration": -0.1}'}}," ",{p:[25,5,1484],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[25,39,1518]}],action:"node2",params:'{"concentration": -0.01}'}}," ",{p:[27,5,1634],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[27,38,1667]}],action:"node2",params:'{"concentration": 0.01}'}}," ",{p:[29,5,1784],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[29,43,1822]}],action:"node2",params:'{"concentration": 0.1}'}}," ",{p:[31,5,1938],t:7,e:"span",f:[{t:2,x:{r:["adata.node2_concentration"],s:"Math.round(_0)"},p:[31,11,1944]},"%"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],369:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,15],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,46],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,63]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,107]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,161]}]}]}," ",{t:4,f:[{p:[7,5,244],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{p:[8,7,285],t:7,e:"ui-button",a:{icon:"pencil",action:"rate",params:'{"rate": "input"}'},f:["Set"]}," ",{p:[9,7,373],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.rate","data.max_rate"],s:'_0==_1?"disabled":null'},p:[9,37,403]}],action:"rate",params:'{"rate": "max"}'},f:["Max"]}," ",{p:[10,7,516],t:7,e:"span",f:[{t:2,x:{r:["adata.rate"],s:"Math.round(_0)"},p:[10,13,522]}," L/s"]}]}],n:50,r:"data.max_rate",p:[6,3,218]},{t:4,n:51,f:[{p:[13,5,593],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[14,7,636],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[15,7,732],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[15,37,762]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[16,7,891],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[16,13,897]}," kPa"]}]}],r:"data.max_rate"}]}]},e.exports=a.extend(r.exports)},{341:341}],370:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"data.borg.name",p:[1,20,19]}],button:0},f:[" ",{p:[5,2,145],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[6,4,176],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.emagged"],s:'_0?"check-square-o":"square-o"'},p:[6,21,193]}],style:[{t:2,x:{r:["data.borg.emagged"],s:'_0?"selected":null'},p:[6,83,255]}],action:"toggle_emagged"},f:["Emagged"]}," ",{p:[7,4,345],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.lockdown"],s:'_0?"check-square-o":"square-o"'},p:[7,21,362]}],style:[{t:2,x:{r:["data.borg.lockdown"],s:'_0?"selected":null'},p:[7,84,425]}],action:"toggle_lockdown"},f:["Locked down"]}," ",{p:[8,4,521],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.scrambledcodes"],s:'_0?"check-square-o":"square-o"'},p:[8,21,538]}],style:[{t:2,x:{r:["data.borg.scrambledcodes"],s:'_0?"selected":null'},p:[8,90,607]}],action:"toggle_scrambledcodes"},f:["Scrambled codes"]}]}," ",{p:[10,2,732],t:7,e:"ui-section",a:{label:"Charge"},f:[{t:4,f:[{p:[12,4,792],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.cell.maxcharge",p:[12,25,813]}],value:[{t:2,r:"data.cell.charge",p:[12,57,845]}]},f:[{t:2,x:{r:["data.cell.charge"],s:"Math.round(_0)"},p:[12,79,867]}," / ",{t:2,x:{r:["data.cell.maxcharge"],s:"Math.round(_0)"},p:[12,114,902]}]}],n:50,x:{r:["data.cell.missing"],s:"!_0"},p:[11,3,762]},{t:4,n:51,f:[{p:[14,4,961],t:7,e:"span",a:{"class":"warning"},f:["Cell missing"]},{p:[14,45,1002],t:7,e:"br"}],x:{r:["data.cell.missing"],s:"!_0"}}," ",{p:[16,3,1020],t:7,e:"ui-button",a:{icon:"pencil",action:"set_charge"},f:["Set"]},{p:[16,63,1080],t:7,e:"ui-button",a:{icon:"eject",action:"change_cell"},f:["Change"]},{p:[16,126,1143],t:7,e:"ui-button",a:{icon:"trash","class":"bad",action:"remove_cell"},f:["Remove"]}]}," ",{p:[18,2,1235],t:7,e:"ui-section",a:{label:"Radio channels"},f:[{t:4,f:[{p:[20,4,1300],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["installed"],s:'_0?"check-square-o":"square-o"'},p:[20,21,1317]}],style:[{t:2,x:{r:["installed"],s:'_0?"selected":null'},p:[20,75,1371]}],action:"toggle_radio",params:['{"channel": "',{t:2,r:"name",p:[20,154,1450]},'"}']},f:[{t:2,r:"name",p:[20,166,1462]}]}],n:52,r:"data.channels",p:[19,3,1273]}]}," ",{p:[23,2,1511],t:7,e:"ui-section",a:{label:"Module"},f:[{t:4,f:[{p:[25,4,1567],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.active_module","type"],s:'_0==_1?"check-square-o":"square-o"'},p:[25,21,1584]}],style:[{t:2,x:{r:["data.borg.active_module","type"],s:'_0==_1?"selected":null'},p:[25,97,1660]}],action:"setmodule",params:['{"module": "',{t:2,r:"type",p:[25,193,1756]},'"}']},f:[{t:2,r:"name",p:[25,205,1768]}]}],n:52,r:"data.modules",p:[24,3,1541]}]}," ",{p:[28,2,1817],t:7,e:"ui-section",a:{label:"Upgrades"},f:[{t:4,f:[{p:[30,4,1876],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["installed"],s:'_0?"check-square-o":"square-o"'},p:[30,21,1893]}],style:[{t:2,x:{r:["installed"],s:'_0?"selected":null'},p:[30,75,1947]}],action:"toggle_upgrade",params:['{"upgrade": "',{t:2,r:"type",p:[30,155,2027]},'"}']},f:[{t:2,r:"name",p:[30,167,2039]}]}],n:52,r:"data.upgrades",p:[29,3,1849]}]}," ",{p:[33,2,2088],t:7,e:"ui-section",a:{label:"Master AI"},f:[{t:4,f:[{p:[35,4,2143],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["connected"],s:'_0?"check-square-o":"square-o"'},p:[35,21,2160]}],style:[{t:2,x:{r:["connected"],s:'_0?"selected":null'},p:[35,75,2214]}],action:"slavetoai",params:['{"slavetoai": "',{t:2,r:"ref",p:[35,152,2291]},'"}']},f:[{t:2,r:"name",p:[35,163,2302]}]}],n:52,r:"data.ais",p:[34,3,2121]}]}]}," ",{p:{button:[{p:[41,3,2420],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.lawupdate"],s:'_0?"check-square-o":"square-o"'},p:[41,20,2437]}],style:[{t:2,x:{r:["data.borg.lawupdate"],s:'_0?"selected":null'},p:[41,84,2501]}],action:"toggle_lawupdate"},f:["Lawsync"]}]},t:7,e:"ui-display",a:{title:"Laws",button:0},f:[" ",{t:4,f:[{p:[44,3,2629],t:7,e:"p",f:[{t:2,r:".",p:[44,6,2632]}]}],n:52,r:"data.laws",p:[43,2,2607]}]}]},e.exports=a.extend(r.exports)},{341:341}],371:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,5,65],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"selected":null'},p:[3,38,98]}],action:[{t:2,x:{r:["data.timing"],s:'_0?"stop":"start"'},p:[3,83,143]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"Stop":"Start"'},p:[3,119,179]}]}," ",{p:[4,5,230],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"flash",style:[{t:2,x:{r:["data.flash_charging"],s:'_0?"disabled":null'},p:[4,57,282]}]},f:[{t:2,x:{r:["data.flash_charging"],s:'_0?"Recharging":"Flash"'},p:[4,102,327]}]}]},t:7,e:"ui-display",a:{title:"Cell Timer",button:0},f:[" ",{p:[6,3,405],t:7,e:"ui-section",f:[{p:[7,5,422],t:7,e:"ui-button",a:{icon:"fast-backward",action:"time",params:'{"adjust": -600}'}}," ",{p:[8,5,511],t:7,e:"ui-button",a:{icon:"backward",action:"time",params:'{"adjust": -100}'}}," ",{p:[9,5,595],t:7,e:"span",f:[{t:2,x:{r:["text","data.minutes"],s:"_0.zeroPad(_1,2)"},p:[9,11,601]},":",{t:2,x:{r:["text","data.seconds"],s:"_0.zeroPad(_1,2)"},p:[9,45,635]}]}," ",{p:[10,5,680],t:7,e:"ui-button",a:{icon:"forward",action:"time",params:'{"adjust": 100}'}}," ",{p:[11,5,762],t:7,e:"ui-button",a:{icon:"fast-forward",action:"time",params:'{"adjust": 600}'}}]}," ",{p:[13,3,863],t:7,e:"ui-section",f:[{p:[14,7,882],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "short"}'},f:["Short"]}," ",{p:[15,7,985],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "medium"}'},f:["Medium"]}," ",{p:[16,7,1090],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "long"}'},f:["Long"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],372:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,22],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,38]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,77],t:7,e:"ui-display",a:{title:"Bluespace Artillery Control",button:0},f:[{t:4,f:[{p:[8,3,160],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,5,192],t:7,e:"ui-button",a:{icon:"crosshairs",action:"recalibrate"},f:[{t:2,r:"data.target",p:[9,55,242]}]}]}," ",{p:[11,3,288],t:7,e:"ui-section",a:{label:"Controls"},f:[{t:4,f:[{p:[13,3,344],t:7,e:"ui-notice",f:[{p:[14,4,359],t:7,e:"span",f:["Bluespace Artillery firing protocols must be globally unlocked from two keycard authentication devices first!"]}]}],n:50,x:{r:["data.unlocked"],s:"!_0"},p:[12,2,319]},{t:4,n:51,f:[{p:[17,3,509],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.ready"],s:'_0?null:"disabled"'},p:[17,36,542]}],action:"fire"},f:["FIRE!"]}],x:{r:["data.unlocked"],s:"!_0"}}]}],n:50,r:"data.connected",p:[7,3,135]}," ",{t:4,f:[{p:[22,3,673],t:7,e:"ui-section",a:{label:"Maintenance"},f:[{p:[23,7,712],t:7,e:"ui-button",a:{icon:"wrench",action:"build"},f:["Complete Deployment."]}]}],n:50,x:{r:["data.connected"],s:"!_0"},p:[21,3,647]}]}]},e.exports=a.extend(r.exports)},{341:341}],373:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,14],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.hasHoldingTank"],s:'_0?"is":"is not"'},p:[2,23,34]}," connected to a tank."]}]}," ",{p:{button:[{p:[6,5,180],t:7,e:"ui-button",a:{icon:"pencil",action:"relabel"},f:["Relabel"]}]},t:7,e:"ui-display",a:{title:"Canister",button:0},f:[" ",{p:[8,3,259],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[9,5,293],t:7,e:"span",f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[9,11,299]}," kPa"]}]}," ",{p:[11,3,363],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[12,5,393],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.portConnected"],s:'_0?"good":"average"'},p:[12,18,406]}]},f:[{t:2,x:{r:["data.portConnected"],s:'_0?"Connected":"Not Connected"'},p:[12,63,451]}]}]}," ",{t:4,f:[{p:[15,3,559],t:7,e:"ui-section",a:{label:"Access"},f:[{p:[16,7,593],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.restricted"],s:'_0?"lock":"unlock"'},p:[16,24,610]}],style:[{t:2,x:{r:[],s:'"caution"'},p:[17,14,664]}],action:"restricted"},f:[{t:2,x:{r:["data.restricted"],s:'_0?"Restricted to Engineering":"Public"'},p:[18,27,705]}]}]}],n:50,r:"data.isPrototype",p:[14,3,531]}]}," ",{p:[22,1,818],t:7,e:"ui-display",a:{title:"Valve"},f:[{p:[23,3,847],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[24,5,889],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[24,18,902]}],max:[{t:2,r:"data.maxReleasePressure",p:[24,52,936]}],value:[{t:2,r:"data.releasePressure",p:[25,14,978]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[25,40,1004]}," kPa"]}]}," ",{p:[27,3,1073],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[28,5,1117],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[28,38,1150]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[30,5,1304],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[30,36,1335]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[32,5,1480],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[33,5,1574],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[33,35,1604]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}," ",{p:[36,3,1763],t:7,e:"ui-section",a:{label:"Valve"},f:[{p:[37,5,1794],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.valveOpen"],s:'_0?"unlock":"lock"'},p:[37,22,1811]}],style:[{t:2,x:{r:["data.valveOpen","data.hasHoldingTank"],s:'_0?_1?"caution":"danger":null'},p:[38,14,1864]}],action:"valve"},f:[{t:2,x:{r:["data.valveOpen"],s:'_0?"Open":"Closed"'},p:[39,22,1957]}]}]}]}," ",{t:4,f:[{p:[42,1,2049],t:7,e:"ui-display",a:{title:"Valve Toggle Timer"},f:[{t:4,f:[{p:[44,5,2112],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[45,7,2152],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.timer_is_not_default"],s:'_0?null:"disabled"'},p:[45,40,2185]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[47,7,2312],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.timer_is_not_min"],s:'_0?null:"disabled"'},p:[47,38,2343]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[49,7,2472],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:[],s:'"disabled"'},p:[49,39,2504]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[51,7,2587],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.timer_is_not_max"],s:'_0?null:"disabled"'},p:[51,37,2617]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[43,3,2091]}," ",{p:[55,3,2779],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[56,6,2811],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[56,39,2844]}],action:"toggle_timer"},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[57,30,2913]}]}," ",{p:[59,2,2959],t:7,e:"ui-section",a:{label:"Time until Valve Toggle"},f:[{p:[60,2,3005],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[60,8,3011]}]}]}]}]}],n:50,r:"data.isPrototype",p:[41,1,2022]},{p:{button:[{t:4,f:[{p:[69,7,3209],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.valveOpen"],s:'_0?"danger":null'},p:[69,38,3240]}],action:"eject"},f:["Eject"]}],n:50,r:"data.hasHoldingTank",p:[68,5,3175]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[73,3,3370],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holdingTank.name",p:[74,4,3400]}]}," ",{p:[76,3,3444],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holdingTank.tankPressure"],s:"Math.round(_0)"},p:[77,4,3477]}," kPa"]}],n:50,r:"data.hasHoldingTank",p:[72,3,3340]},{t:4,n:51,f:[{p:[80,3,3556],t:7,e:"ui-section",f:[{p:[81,4,3572],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.hasHoldingTank"}]}]},e.exports=a.extend(r.exports)},{341:341}],374:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,158],t:7,e:"ui-display",a:{title:"Cargo"},f:[{p:[12,3,188],t:7,e:"ui-section",a:{label:"Shuttle"},f:[{t:4,f:[{p:[14,7,270],t:7,e:"ui-button",a:{action:"send"},f:[{t:2,r:"data.location",p:[14,32,295]}]}],n:50,x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"},p:[13,5,222]},{t:4,n:51,f:[{p:[16,7,346],t:7,e:"span",f:[{t:2,r:"data.location",p:[16,13,352]}]}],x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"}}]}," ",{p:[19,3,410],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[20,5,444],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[20,11,450]}]}]}," ",{p:[22,3,506],t:7,e:"ui-section",a:{label:"CentCom Message"},f:[{p:[23,7,550],t:7,e:"span",f:[{t:2,r:"data.message",p:[23,13,556]}]}]}," ",{t:4,f:[{p:[26,5,644],t:7,e:"ui-section",a:{label:"Loan"},f:[{t:4,f:[{p:[28,9,716],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.away","data.docked"],s:'_0&&_1?null:"disabled"'},p:[29,17,744]}],action:"loan"},f:["Loan Shuttle"]}],n:50,x:{r:["data.loan_dispatched"],s:"!_0"},p:[27,7,677]},{t:4,n:51,f:[{p:[32,9,868],t:7,e:"span",a:{"class":"bad"},f:["Loaned to CentCom"]}],x:{r:["data.loan_dispatched"],s:"!_0"}}]}],n:50,x:{r:["data.loan","data.requestonly"],s:"_0&&!_1"},p:[25,3,600]}]}," ",{t:4,f:[{p:{button:[{p:[40,7,1066],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.cart.length"],s:'_0?null:"disabled"'},p:[40,38,1097]}],action:"clear"},f:["Clear"]}]},t:7,e:"ui-display",a:{title:"Cart",button:0},f:[" ",{t:4,f:[{p:[43,7,1222],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[44,9,1263],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[44,31,1285]}]}," ",{p:[45,9,1307],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[45,30,1328]}]}," ",{p:[46,9,1354],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[46,30,1375]}," Credits"]}," ",{p:[47,9,1407],t:7,e:"div",a:{"class":"content"},f:[{p:[48,11,1440],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"id": "',{t:2,r:"id",
-p:[48,67,1496]},'"}']}}]}]}],n:52,r:"data.cart",p:[42,5,1195]},{t:4,n:51,f:[{p:[52,7,1566],t:7,e:"span",f:["Nothing in Cart"]}],r:"data.cart"}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[37,1,972]},{p:{button:[{t:4,f:[{p:[59,7,1735],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.requests.length"],s:'_0?null:"disabled"'},p:[59,38,1766]}],action:"denyall"},f:["Clear"]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[58,5,1702]}]},t:7,e:"ui-display",a:{title:"Requests",button:0},f:[" ",{t:4,f:[{p:[63,5,1908],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[64,7,1947],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[64,29,1969]}]}," ",{p:[65,7,1989],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[65,28,2010]}]}," ",{p:[66,7,2034],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[66,28,2055]}," Credits"]}," ",{p:[67,7,2085],t:7,e:"div",a:{"class":"content"},f:["By ",{t:2,r:"orderer",p:[67,31,2109]}]}," ",{p:[68,7,2134],t:7,e:"div",a:{"class":"content"},f:["Comment: ",{t:2,r:"reason",p:[68,37,2164]}]}," ",{t:4,f:[{p:[70,9,2223],t:7,e:"div",a:{"class":"content"},f:[{p:[71,11,2256],t:7,e:"ui-button",a:{icon:"check",action:"approve",params:['{"id": "',{t:2,r:"id",p:[71,68,2313]},'"}']}}," ",{p:[72,11,2336],t:7,e:"ui-button",a:{icon:"close",action:"deny",params:['{"id": "',{t:2,r:"id",p:[72,65,2390]},'"}']}}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[69,7,2188]}]}],n:52,r:"data.requests",p:[62,3,1879]},{t:4,n:51,f:[{p:[77,7,2473],t:7,e:"span",f:["No Requests"]}],r:"data.requests"}]}," ",{p:[80,1,2529],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[80,16,2544]}]},f:[{t:4,f:[{p:[82,5,2587],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[82,16,2598]}]},f:[{t:4,f:[{p:[84,9,2641],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,28,2660]}],candystripe:0,right:0},f:[{p:[85,11,2700],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"desc",p:[85,31,2720]}],"tooltip-side":"left",action:"add",params:['{"id": "',{t:2,r:"id",p:[85,90,2779]},'"}']},f:[{t:2,r:"cost",p:[85,100,2789]}," Credits"]}]}],n:52,r:"packs",p:[83,7,2616]}]}],n:52,r:"data.supplies",p:[81,3,2558]}]}]},e.exports=a.extend(r.exports)},{341:341}],375:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[12,1,163],t:7,e:"ui-notice",f:[{t:4,f:[{p:[14,5,207],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[15,7,249],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[15,24,266]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[15,75,317]}]}]}],n:50,r:"data.siliconUser",p:[13,3,177]},{t:4,n:51,f:[{p:[18,5,405],t:7,e:"span",f:["Swipe a QM-Level ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[18,39,439]}," this interface."]}],r:"data.siliconUser"}]}," ",{t:4,f:[{p:[23,3,546],t:7,e:"ui-display",a:{title:"Express Cargo Console"},f:[{p:[25,5,594],t:7,e:"ui-section",a:{label:"Landing Location"},f:[{p:[26,7,638],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.usingBeacon"],s:'_0?null:"selected"'},p:[26,25,656]}],action:"LZCargo"},f:["Cargo Bay"]}," ",{p:[27,7,744],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.hasBeacon","data.usingBeacon"],s:'_0?_1?"selected":null:"disabled"'},p:[27,25,762]}],action:"LZBeacon"},f:[{t:2,r:"data.beaconzone",p:[27,116,853]}," (",{t:2,r:"data.beaconName",p:[27,137,874]},")"]}," ",{p:[28,7,913],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.canBuyBeacon"],s:'_0?null:"disabled"'},p:[28,25,931]}],action:"printBeacon"},f:[{t:2,r:"data.printMsg",p:[28,90,996]}]}]}," ",{p:[31,5,1049],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[32,7,1084],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[32,13,1090]}]}]}," ",{p:[35,5,1149],t:7,e:"ui-section",a:{label:"Notice"},f:[{p:[36,7,1183],t:7,e:"span",f:[{t:2,r:"data.message",p:[36,13,1189]}]}]}]}," ",{p:[39,3,1249],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[39,18,1264]}]},f:[{t:4,f:[{p:[41,7,1309],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[41,18,1320]}]},f:[{t:4,f:[{p:[43,11,1365],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[43,30,1384]}],candystripe:0,right:0},f:[{p:[44,13,1425],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.canBeacon"],s:'_0?null:"disabled"'},p:[44,31,1443]}],tooltip:[{t:2,r:"desc",p:[44,80,1492]}],"tooltip-side":"left",action:"add",params:['{"id": "',{t:2,r:"id",p:[44,139,1551]},'"}']},f:[{t:2,r:"cost",p:[44,149,1561]}," Credits ",{t:2,r:"data.beaconError",p:[44,166,1578]}]}]}],n:52,r:"packs",p:[42,9,1339]}]}],n:52,r:"data.supplies",p:[40,5,1279]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[22,1,522]}]},e.exports=a.extend(r.exports)},{341:341}],376:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Cellular Emporium",button:0},f:[{p:[2,3,48],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.can_readapt"],s:'_0?null:"disabled"'},p:[2,36,81]}],action:"readapt"},f:["Readapt"]}," ",{p:[4,3,166],t:7,e:"ui-section",a:{label:"Genetic Points Remaining",right:0},f:[{t:2,r:"data.genetic_points_remaining",p:[5,5,222]}]}]}," ",{p:[8,1,286],t:7,e:"ui-display",f:[{t:4,f:[{p:[10,3,326],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[10,22,345]}],candystripe:0,right:0},f:[{p:[11,5,378],t:7,e:"span",f:[{t:2,r:"desc",p:[11,11,384]}]}," ",{p:[12,5,404],t:7,e:"span",f:[{t:2,r:"helptext",p:[12,11,410]}]}," ",{p:[13,5,434],t:7,e:"span",f:["Cost: ",{t:2,r:"dna_cost",p:[13,17,446]}]}," ",{p:[14,5,470],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["owned","can_purchase"],s:'_0?"selected":_1?null:"disabled"'},p:[15,14,494]}],action:"evolve",params:['{"name": "',{t:2,r:"name",p:[17,25,599]},'"}']},f:[{t:2,x:{r:["owned"],s:'_0?"Evolved":"Evolve"'},p:[18,7,618]}]}]}],n:52,r:"data.abilities",p:[9,1,299]},{t:4,f:[{p:[23,3,716],t:7,e:"span",a:{"class":"warning"},f:["No abilities available."]}],n:51,r:"data.abilities",p:[22,1,694]}]}]},e.exports=a.extend(r.exports)},{341:341}],377:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,5,16],t:7,e:"span",f:["To use this, simply spawn the atoms you want in one of the four Centcom Supplypod Bays. Items in the bay will then be launched inside your supplypod, one turf-full at a time! You can optionally use the following buttons to configure how the supplypod acts."]}]}," ",{p:[5,1,300],t:7,e:"ui-display",a:{title:"Centcom Pod Customization (to be used against helen weinstein)"},f:[{p:[6,4,387],t:7,e:"ui-section",a:{label:"Which supplypod bay will you use?"},f:[{p:[7,9,452],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==1?"selected":null'},p:[7,27,470]}],action:"bay1"},f:["Bay #1"]}," ",{p:[8,9,550],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==2?"selected":null'},p:[8,27,568]}],action:"bay2"},f:["Bay #2"]}," ",{p:[9,9,648],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==3?"selected":null'},p:[9,27,666]}],action:"bay3"},f:["Bay #3"]}," ",{p:[10,9,746],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==4?"selected":null'},p:[10,27,764]}],action:"bay4"},f:["Bay #4"]}]}," ",{p:[13,5,859],t:7,e:"ui-section",a:{label:"Useful teleport tools!"},f:[{p:[14,9,913],t:7,e:"ui-button",a:{action:"teleportCentcom"},f:["Teleport to Centcom's Supplypod Loading Bay"]}," ",{p:[15,9,1013],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.oldArea"],s:'_0?null:"disabled"'},p:[15,27,1031]}],action:"teleportBack"},f:["Teleport Back to ",{t:2,x:{r:["data.oldArea"],s:'_0?_0:"where you were"'},p:[15,103,1107]}]}]}," ",{p:[18,5,1193],t:7,e:"ui-section",a:{label:"Keep stuff after launching?"},f:[{p:[19,9,1250],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchClone"],s:'_0?"selected":null'},p:[19,27,1268]}],action:"launchClone","tooltip-side":"left",tooltip:"Choosing this will create a duplicate of the item to be launched in Centcom, allowing you to send one type of item multiple times. Either way, the atoms are forceMoved into the supplypod after it lands (but before it opens)."},f:["Clone and Launch"]}]}," ",{p:[23,5,1646],t:7,e:"ui-section",a:{label:"Launch all at once?"},f:[{p:[24,9,1695],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchChoice"],s:'_0==1?"selected":null'},p:[24,27,1713]}],action:"launchOrdered","tooltip-side":"left",tooltip:'Instead of launching everything in the bay at once, this will "scan" things (one turf-full at a time) in order, left to right and top to bottom. Refreshing will reset the "scanner" to the top-leftmost position.'},f:["Ordered"]}," ",{p:[26,9,2061],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchChoice"],s:'_0==2?"selected":null'},p:[26,27,2079]}],action:"launchRandom","tooltip-side":"left",tooltip:"Instead of launching everything in the bay at once, this will launch one random turf of items at a time."},f:["Random"]}]}," ",{p:[30,5,2333],t:7,e:"ui-section",a:{label:"Add an explosion?"},f:[{p:[31,9,2380],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.explosionChoice"],s:'_0==1?"selected":null'},p:[31,27,2398]}],action:"explosionCustom","tooltip-side":"left",tooltip:"This will cause an explosion of whatever size you like (including flame range) to occur as soon as the supplypod lands. Dont worry, supply-pods are explosion-proof!"},f:["Custom Size"]}," ",{p:[33,9,2708],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.explosionChoice"],s:'_0==2?"selected":null'},p:[33,27,2726]}],action:"explosionBus","tooltip-side":"left",tooltip:"This will cause a maxcap explosion (dependent on server config) to occur as soon as the supplypod lands. Dont worry, supply-pods are explosion-proof!"},f:["Adminbus"]}]}," ",{p:[37,5,3030],t:7,e:"ui-section",a:{label:"Extra damage?","(default":"None)"},f:[{p:[38,9,3090],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.damageChoice"],s:'_0==1?"selected":null'},p:[38,27,3108]}],action:"damageCustom","tooltip-side":"left",tooltip:"Anyone caught under the pod when it lands will be dealt this amount of brute damage. Sucks to be them!"},f:["Custom Damage"]}," ",{p:[40,9,3353],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.damageChoice"],s:'_0==2?"selected":null'},p:[40,27,3371]}],action:"damageGib","tooltip-side":"left",tooltip:"This will attempt to gib any mob caught under the pod when it lands, as well as dealing a nice 5000 brute damage. Ya know, just to be sure!"},f:["Gib"]}]}," ",{p:[44,5,3655],t:7,e:"ui-section",a:{label:"Extra effects?"},f:[{p:[45,9,3699],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectStun"],s:'_0?"selected":null'},p:[45,27,3717]}],action:"effectStun","tooltip-side":"left",tooltip:"Anyone who is on the turf when the supplypod is launched will be stunned until the supplypod lands. They cant get away that easy!"},f:["Stun"]}," ",{p:[47,9,3971],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectLimb"],s:'_0?"selected":null'},p:[47,27,3989]}],action:"effectLimb","tooltip-side":"left",tooltip:"This will cause anyone caught under the pod to lose a limb, excluding their head."},f:["Delimb"]}," ",{p:[49,9,4197],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectBluespace"],s:'_0?"selected":null'},p:[49,27,4215]}],action:"effectBluespace","tooltip-side":"left",tooltip:"Gives the supplypod an advanced Bluespace Recyling Device. After opening, the supplypod will be warped directly to the surface of a nearby NT-designated trash planet (/r/ss13)."},f:["Bluespace"]}," ",{p:[51,9,4531],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectStealth"],s:'_0?"selected":null'},p:[51,27,4549]}],action:"effectStealth","tooltip-side":"left",tooltip:'This hides the red target icon from appearing when you launch the supplypod. Combos well with the "Invisible" style. Sneak attack, go!'},f:["Stealth"]}," ",{p:[53,9,4817],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectQuiet"],s:'_0?"selected":null'},p:[53,27,4835]}],action:"effectQuiet","tooltip-side":"left",tooltip:"This will keep the supplypod from making any sounds, except for those specifically set by admins in the Sound section."},f:["Quiet Landing"]}," ",{p:[55,9,5089],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectReverse"],s:'_0?"selected":null'},p:[55,27,5107]}],action:"effectReverse","tooltip-side":"left",tooltip:"This pod will not send any items. Instead, after landing, the supplypod will close (similar to a normal closet closing), and then launch back to the right centcom bay to drop off any new contents."},f:["Reverse Mode"]}," ",{p:[57,9,5442],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectMissile"],s:'_0?"selected":null'},p:[57,27,5460]}],action:"effectMissile","tooltip-side":"left",tooltip:"This pod will not send any items. Instead, it will immediatley delete after landing (Similar visually to setting openDelay & departDelay to 0, but this looks nicer). Useful if you just wanna fuck some shit up. Combos well with the Missile style."},f:["Missile Mode"]}," ",{p:[59,9,5844],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectCircle"],s:'_0?"selected":null'},p:[59,27,5862]}],action:"effectCircle","tooltip-side":"left",tooltip:"This will make the supplypod come in from any angle. Im not sure why this feature exists, but here it is."},f:["Any Descent Angle"]}," ",{p:[61,9,6109],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectBurst"],s:'_0?"selected":null'},p:[61,27,6127]}],action:"effectBurst","tooltip-side":"left",tooltip:"This will make each click launch 5 supplypods inaccuratly around the target turf (a 3x3 area). Combos well with the Missle Mode if you dont want shit lying everywhere after."},f:["Machine Gun Mode"]}," ",{p:[63,9,6439],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectTarget"],s:'_0?"selected":null'},p:[63,27,6457]}],action:"effectTarget","tooltip-side":"left",tooltip:"This will make the supplypod target a specific atom, instead of the mouses position. Smiting does this automatically!"},f:["Specific Target"]}," ",{p:[65,9,6714],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectName"],s:'_0?"selected":null'},p:[65,27,6732]}],action:"effectName","tooltip-side":"left",tooltip:"Allows you to add a custom name and description."},f:["Custom Name/Desc"]}]}," ",{p:[69,5,6932],t:7,e:"ui-section",a:{label:"Sound?"},f:[{p:[70,9,6968],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.landingSound"],s:'_0?"selected":null'},p:[70,27,6986]}],action:"landingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod lands."},f:["Custom Landing Sound"]}," ",{p:[72,10,7174],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.openingSound"],s:'_0?"selected":null'},p:[72,28,7192]}],action:"openingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod opens."},f:["Custom Opening Sound"]}," ",{p:[74,9,7379],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.leavingSound"],s:'_0?"selected":null'},p:[74,27,7397]}],action:"leavingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod departs (whether that be delection in the case of a bluespace pod, or leaving for centcom for a reversing pod)."},f:["Custom Leaving Sound"]}," ",{p:[76,9,7689],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.soundVolume"],s:'_0?"selected":null'},p:[76,27,7707]}],action:"soundVolume","tooltip-side":"left",tooltip:"Choose the volume for the sound to play at. Default values are between 1 and 100, but hey, do whatever. Im a tooltip, not a cop."},f:["Admin Sound Volume"]}]}," ",{p:[80,5,7991],t:7,e:"ui-section",a:{label:"Delay timers?"},f:[{p:[81,9,8034],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.landingDelay"],s:'_0!=5?"selected":null'},p:[81,27,8052]}],action:"landingDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to hit the station. By default this value is 0.5 seconds."},f:["Custom Landing Time"]}," ",{p:[83,10,8312],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.openingDelay"],s:'_0!=30?"selected":null'},p:[83,28,8330]}],action:"openingDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to open after landing. Useful for giving whatevers inside the pod a nice dramatic entrance! By default this value is 3 seconds."},f:["Custom Opening Time"]}," ",{p:[85,9,8660],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.departureDelay"],s:'_0!=30?"selected":null'},p:[85,27,8678]}],action:"departureDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to leave after landing. By default this value is 3 seconds."},f:["Custom Leaving Time"]}]}," ",{p:[89,5,8959],t:7,e:"ui-section",a:{label:"Style?"},f:[{p:[90,9,8995],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==1?"selected":null'},p:[90,27,9013]}],action:"styleStandard","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to your standard Nanotrasen black and orange. Same color scheme as the normal station-used supplypods."},f:["Standard"]}," ",{p:[92,9,9314],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==2?"selected":null'},p:[92,27,9332]}],action:"styleBluespace","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to the same as the stations upgraded blue-and-white Bluespace Supplypods."},f:["Advanced"]}," ",{p:[94,9,9605],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==4?"selected":null'},p:[94,27,9623]}],action:"styleSyndie","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a menacing black and blood-red. Great for sending meme-ops in style!"},f:["Syndicate"]}," ",{p:[96,9,9892],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==5?"selected":null'},p:[96,27,9910]}],action:"styleBlue","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a menacing black and dark blue. Great for sending deathsquads in style!"},f:["Deathsquad"]}," ",{p:[98,10,10182],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==6?"selected":null'},p:[98,28,10200]}],action:"styleCult","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a blood and rune covered cult pod!"},f:["Cult Pod"]}," ",{p:[100,9,10425],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==7?"selected":null'},p:[100,27,10443]}],action:"styleMissile","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large missile. Combos well with a missile mode, so the missile doesnt stick around after landing."},f:["Missile"]}," ",{p:[102,9,10735],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==8?"selected":null'},p:[102,27,10753]}],action:"styleSMissile","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large blood-red missile. Combos well with missile mode, so the missile doesnt stick around after landing."},f:["Syndicate Missile"]}," ",{p:[104,9,11064],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==9?"selected":null'},p:[104,27,11082]}],action:"styleBox","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large, dark-green military supply crate."},f:["Supply Crate"]}," ",{p:[106,9,11318],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==10?"selected":null'},p:[106,27,11336]}],action:"styleHONK","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a colorful, clown inspired look."},f:["HONK"]}," ",{p:[108,9,11563],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==11?"selected":null'},p:[108,27,11581]}],action:"styleFruit","tooltip-side":"left",tooltip:"for when an orange is angry"},f:["Fruit~"]}," ",{p:[110,9,11742],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==12?"selected":null'},p:[110,27,11760]}],action:"styleInvisible","tooltip-side":"left",tooltip:'Makes the supplypod invisible! Useful for when you want to use this feature with a gateway or something. Combos well with the "Stealth" and "Quiet Landing" effects.'},f:["Invisible"]}," ",{p:[112,9,12064],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==13?"selected":null'},p:[112,27,12082]}],action:"styleGondola","tooltip-side":"left",tooltip:"this gondola can control when he wants to deliver his supplies if he has a smart enough mind, so offer up his body to ghosts for maximum enjoyment. (Make sure to turn off bluespace and set a arbitrarily high open-time if you do!)"},f:["Gondola (alive)"]}]}]}," ",{p:[117,1,12481],t:7,e:"ui-display",f:[{p:[118,5,12498],t:7,e:"ui-section",a:{label:[{t:2,r:"data.numObjects",p:[118,26,12519]}," turfs with launchable atoms found in Bay #",{t:2,r:"data.bay",p:[118,88,12581]}]},f:[{p:[119,9,12604],t:7,e:"ui-button",a:{action:"refresh","tooltip-side":"right",tooltip:"Manually refreshes the possible things to launch in the pod bay."},f:["Refresh Pod Bay"]}]}," ",{p:[123,5,12787],t:7,e:"ui-section",f:[{p:[124,9,12808],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.giveLauncher"],s:'_0?"selected":null'},p:[124,27,12826]}],action:"giveLauncher","tooltip-side":"right",tooltip:"THE CODEX ASTARTES CALLS THIS MANEUVER: STEEL RAIN!!"},f:["Enter Launch Mode"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],378:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Energy"},f:[{p:[3,5,64],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.maxEnergy",p:[3,26,85]}],value:[{t:2,r:"data.energy",p:[3,53,112]}]},f:[{t:2,x:{r:["adata.energy"],s:"Math.fixed(_0)"},p:[3,70,129]}," Units"]}]}]}," ",{p:[6,1,206],t:7,e:"ui-display",a:{title:"Saved Recipes",button:0},f:[{p:[7,3,251],t:7,e:"ui-section",f:[{p:[8,5,269],t:7,e:"ui-button",a:{icon:"plus",action:"add_recipe"},f:["Add Recipe"]}," ",{p:[9,2,337],t:7,e:"ui-button",a:{icon:"minus",action:"clear_recipes"},f:["Clear Recipes"]}," ",{t:4,f:[{p:[11,7,445],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense_recipe",params:['{"recipe": "',{t:2,r:"contents",p:[11,80,518]},'"}']},f:[{t:2,r:"recipe_name",p:[11,96,534]}]}],n:52,r:"data.recipes",p:[10,5,415]}]}]}," ",{p:{button:[{t:4,f:[{p:[18,7,719],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.amount","."],s:'_0==_1?"selected":null'},p:[18,37,749]}],action:"amount",params:['{"target": ',{t:2,r:".",p:[18,114,826]},"}"]},f:[{t:2,r:".",p:[18,122,834]}]}],n:52,r:"data.beakerTransferAmounts",p:[17,5,675]}]},t:7,e:"ui-display",a:{title:"Dispense",button:0},f:[" ",{p:[21,3,886],t:7,e:"ui-section",f:[{t:4,f:[{p:[23,7,936],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense",params:['{"reagent": "',{t:2,r:"id",p:[23,74,1003]},'"}']},f:[{t:2,r:"title",p:[23,84,1013]}]}],n:52,r:"data.chemicals",p:[22,5,904]}]}]}," ",{p:{button:[{t:4,f:[{p:[30,7,1190],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"amount": ',{t:2,r:".",p:[30,66,1249]},"}"]},f:[{t:2,r:".",p:[30,74,1257]}]}],n:52,r:"data.beakerTransferAmounts",p:[29,5,1146]}," ",{p:[32,5,1295],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[32,36,1326]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[34,3,1423],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[36,7,1493],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[36,13,1499]},"/",{t:2,r:"data.beakerMaxVolume",p:[36,55,1541]}," Units"]}," ",{p:[37,4,1583],t:7,e:"span",f:["pH: ",{t:2,x:{r:["adata.beakerCurrentpH","adata.partRating"],s:"Math.round(_0*_1)/_1"},p:[37,14,1593]}]}," ",{p:[38,7,1679],t:7,e:"br"}," ",{t:4,f:[{p:[40,9,1732],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[40,52,1775]}," units of ",{t:2,r:"name",p:[40,87,1810]}]},{p:[40,102,1825],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[39,7,1692]},{t:4,n:51,f:[{p:[42,9,1856],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[35,5,1458]},{t:4,n:51,f:[{p:[45,7,1932],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],379:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[2,3,35],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isActive"],s:'_0?"power-off":"close"'},p:[3,22,84]}],style:[{t:2,x:{r:["data.isActive"],s:'_0?"selected":null'},p:[4,10,137]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,10,186]}],action:"power"},f:[{t:2,x:{r:["data.isActive"],s:'_0?"On":"Off"'},p:[6,18,249]}]}]}," ",{p:[8,3,314],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,4,346],t:7,e:"ui-button",a:{icon:"pencil",action:"temperature",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[9,79,421]}," K"]}]}]}," ",{p:{button:[{p:[14,5,564],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[14,36,595]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[16,3,692],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[18,7,762],t:7,e:"span",f:["Temperature: ",{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[18,26,781]}," K"]}," ",{p:[19,4,828],t:7,e:"br"}," ",{p:[20,7,842],t:7,e:"span",f:["pH: ",{t:2,x:{r:["adata.currentpH","adata.partRating"],s:"Math.round(_0*_1)/_1"},p:[20,17,852]}]}," ",{p:[21,7,932],t:7,e:"br"}," ",{t:4,f:[{p:[23,3,980],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[23,46,1023]}," units of ",{t:2,r:"name",p:[23,81,1058]}]},{p:[23,96,1073],t:7,e:"br"}," ",{t:4,f:[{p:[25,4,1111],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:["Purity: ",{t:2,x:{r:["purity"],s:"Math.fixed(_0,2)"},p:[25,55,1162]}]},{p:[25,87,1194],t:7,e:"br"}],n:50,r:"data.showPurity",p:[24,3,1083]}],n:52,r:"adata.beakerContents",p:[22,7,946]},{t:4,n:51,f:[{p:[28,9,1237],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[17,5,727]},{t:4,n:51,f:[{p:[31,7,1313],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],380:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:["\ufeff",{t:4,f:[" ",{p:[2,2,33],t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[{p:[3,3,71],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"close"'},p:[3,20,88]}],style:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"selected":null'},p:[4,11,144]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,11,200]}],action:"eject"},f:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"No beaker"'},p:[7,5,269]}]}," ",{p:[10,3,341],t:7,e:"ui-section",f:[{t:4,f:[{t:4,f:[{p:[13,6,427],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[13,25,446]}," units of ",{t:2,r:"name",p:[13,60,481]}],nowrap:0},f:[{p:[14,7,506],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[15,8,556],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[15,61,609]},'", "amount": 1}']},f:["1"]}," ",{p:[16,8,654],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[16,61,707]},'", "amount": 5}']},f:["5"]}," ",{p:[17,8,752],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[17,61,805]},'", "amount": 10}']},f:["10"]}," ",{p:[18,8,852],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[18,61,905]},'", "amount": 1000}']},f:["All"]}," ",{p:[19,8,955],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[19,61,1008]},'", "amount": -1}']},f:["Custom"]}," ",{p:[20,8,1059],t:7,e:"ui-button",a:{action:"analyzeBeak",params:['{"id": "',{t:2,r:"id",p:[20,56,1107]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.beakerContents",p:[12,5,391]},{t:4,n:51,f:[{p:[24,5,1189],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"data.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,4,358]},{t:4,n:51,f:[{p:[27,5,1260],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}," ",{p:[32,2,1348],t:7,e:"ui-display",a:{title:"Buffer"},f:[{p:[33,3,1379],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?null:"selected"'},p:[33,41,1417]}]},f:["Destroy"]}," ",{p:[34,3,1475],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?"selected":null'},p:[34,41,1513]}]},f:["Transfer to Beaker"]}," ",{p:[35,3,1582],t:7,e:"ui-section",f:[{t:4,f:[{p:[37,5,1634],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[37,24,1653]}," units of ",{t:2,r:"name",p:[37,59,1688]}],nowrap:0},f:[{p:[38,6,1712],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[39,7,1761],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[39,62,1816]},'", "amount": 1}']},f:["1"]}," ",{p:[40,7,1860],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[40,62,1915]},'", "amount": 5}']},f:["5"]}," ",{p:[41,7,1959],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[41,62,2014]},'", "amount": 10}']},f:["10"]}," ",{p:[42,7,2060],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[42,62,2115]},'", "amount": 1000}']},f:["All"]}," ",{p:[43,7,2164],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[43,62,2219]},'", "amount": -1}']},f:["Custom"]}," ",{p:[44,7,2269],t:7,e:"ui-button",a:{action:"analyzeBuff",params:['{"id": "',{t:2,r:"id",p:[44,55,2317]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.bufferContents",p:[36,4,1599]}]}]}," ",{t:4,f:[{p:[52,3,2453],t:7,e:"ui-display",a:{title:"Pills, Bottles and Patches"},f:[{t:4,f:[{p:[54,5,2537],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["id","data.chosenPillStyle"],s:'_0==_1?"selected":null'},p:[54,23,2555]}],action:"pillStyle",params:['{"id": "',{t:2,r:"id",p:[54,108,2640]},'"}']},f:[{t:3,r:"htmltag",p:[54,118,2650]}]}],n:52,r:"data.pillStyles",p:[53,4,2506]}," ",{p:[56,4,2694],t:7,e:"br"}," ",{t:4,f:[{p:[58,5,2740],t:7,e:"ui-button",a:{action:"ejectp",state:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?null:"disabled"'},p:[58,39,2774]}]},f:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?"Eject":"No Pill bottle loaded"'},p:[58,88,2823]}]}," ",{p:[59,5,2904],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.pillBotContent",p:[59,27,2926]},"/",{t:2,r:"data.pillBotMaxContent",p:[59,51,2950]}]}],n:50,r:"data.isPillBottleLoaded",p:[57,4,2703]},{t:4,n:51,f:[{p:[61,5,3002],t:7,e:"span",a:{"class":"average"},f:["No Pillbottle"]}],r:"data.isPillBottleLoaded"}," ",{p:[64,4,3063],t:7,e:"br"}," ",{p:[65,4,3073],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[65,63,3132]}]},f:["Create Pill (max 50µ)"]}," ",{p:[66,4,3216],t:7,e:"br"}," ",{p:[67,4,3226],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[67,63,3285]}]},f:["Create Multiple Pills"]}," ",{p:[68,4,3369],t:7,e:"br"}," ",{p:[69,4,3379],t:7,e:"br"}," ",{p:[70,4,3389],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[70,64,3449]}]},f:["Create Patch (max 40µ)"]}," ",{p:[71,4,3534],t:7,e:"br"}," ",{p:[72,4,3544],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[72,64,3604]}]},f:["Create Multiple Patches"]}," ",{p:[73,4,3690],t:7,e:"br"}," ",{p:[74,4,3700],t:7,e:"br"}," ",{p:[75,4,3710],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[75,65,3771]}]},f:["Create Bottle (max 30µ)"]}," ",{p:[76,4,3857],t:7,e:"br"}," ",{p:[77,4,3867],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 1}',
-state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[77,65,3928]}]},f:["Dispense Buffer to Bottles"]}," ",{p:[78,4,4017],t:7,e:"br"}," ",{p:[79,4,4027],t:7,e:"br"}," ",{p:[80,4,4037],t:7,e:"ui-button",a:{action:"createVial",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[80,63,4096]}]},f:["Create Hypo Vial (max 60µ)"]}," ",{p:[81,4,4185],t:7,e:"br"}," ",{p:[82,4,4195],t:7,e:"ui-button",a:{action:"createVial",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[82,63,4254]}]},f:["Dispense Buffer to Hypo vials"]}," ",{p:[83,4,4347],t:7,e:"br"}]}],n:50,x:{r:["data.condi"],s:"!_0"},p:[51,2,2430]},{t:4,n:51,f:[{p:[88,3,4390],t:7,e:"ui-display",a:{title:"Condiments bottles and packs"},f:[{p:[89,4,4445],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[89,63,4504]}]},f:["Create Pack (max 10µ)"]}," ",{p:[90,4,4588],t:7,e:"br"}," ",{p:[91,4,4598],t:7,e:"br"}," ",{p:[92,4,4608],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[92,65,4669]}]},f:["Create Bottle (max 50µ)"]}]}],x:{r:["data.condi"],s:"!_0"}}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,2,1]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.screen"],s:'_0=="analyze"'},f:[{p:[96,2,4817],t:7,e:"ui-display",a:{title:[{t:2,r:"data.analyzeVars.name",p:[96,20,4835]}]},f:[{p:[97,3,4866],t:7,e:"span",a:{"class":"highlight"},f:["Description:"]}," ",{p:[98,3,4914],t:7,e:"span",a:{"class":"content",style:"float:center"},f:[{t:2,r:"data.analyzeVars.description",p:[98,46,4957]}]}," ",{p:[99,3,5e3],t:7,e:"br"}," ",{p:[100,3,5009],t:7,e:"span",a:{"class":"highlight"},f:["Color:"]}," ",{p:[101,3,5051],t:7,e:"span",a:{style:["color: ",{t:2,r:"data.analyzeVars.color",p:[101,23,5071]},"; background-color: ",{t:2,r:"data.analyzeVars.color",p:[101,69,5117]}]},f:[{t:2,r:"data.analyzeVars.color",p:[101,97,5145]}]}," ",{p:[102,3,5182],t:7,e:"br"}," ",{p:[103,3,5191],t:7,e:"span",a:{"class":"highlight"},f:["State:"]}," ",{p:[104,3,5233],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.state",p:[104,25,5255]}]}," ",{p:[105,3,5292],t:7,e:"br"}," ",{p:[106,3,5301],t:7,e:"span",a:{"class":"highlight"},f:["Metabolization Rate:"]}," ",{p:[107,3,5357],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.metaRate",p:[107,25,5379]},"µ/minute"]}," ",{p:[108,3,5427],t:7,e:"br"}," ",{p:[109,3,5436],t:7,e:"span",a:{"class":"highlight"},f:["Overdose Threshold:"]}," ",{p:[110,3,5491],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.overD",p:[110,25,5513]}]}," ",{p:[111,3,5550],t:7,e:"br"}," ",{p:[112,3,5559],t:7,e:"span",a:{"class":"highlight"},f:["Addiction Threshold:"]}," ",{p:[113,3,5615],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.addicD",p:[113,25,5637]}]}," ",{p:[114,3,5675],t:7,e:"br"}," ",{t:4,f:[{p:[116,4,5714],t:7,e:"span",a:{"class":"highlight"},f:["Minumum Reaction Temperature:"]}," ",{p:[117,4,5780],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.minTemp",p:[117,26,5802]},"K"]}," ",{p:[118,4,5843],t:7,e:"br"}," ",{p:[119,4,5853],t:7,e:"span",a:{"class":"highlight"},f:["Optimal Reaction Temperature:"]}," ",{p:[120,4,5919],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.maxTemp",p:[120,26,5941]},"K"]}," ",{p:[121,4,5982],t:7,e:"br"}," ",{p:[122,4,5992],t:7,e:"span",a:{"class":"highlight"},f:["Explosion Reaction Temperature:"]}," ",{p:[123,4,6060],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.eTemp",p:[123,26,6082]},"K"]}," ",{p:[124,4,6121],t:7,e:"br"}," ",{p:[125,4,6131],t:7,e:"span",a:{"class":"highlight"},f:["Optimal reaction pH:"]}," ",{p:[126,4,6188],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.pHpeak",p:[126,26,6210]}]}," ",{p:[127,4,6249],t:7,e:"br"}," ",{p:[128,4,6259],t:7,e:"span",a:{"class":"highlight"},f:["Current Purity:"]}," ",{p:[129,4,6311],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.purityF",p:[129,26,6333]}]}," ",{p:[130,4,6373],t:7,e:"br"}," ",{p:[131,4,6383],t:7,e:"span",a:{"class":"highlight"},f:["Inverse Purity Threshold:"]}," ",{p:[132,4,6445],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.inverseRatioF",p:[132,26,6467]}]}," ",{p:[133,4,6513],t:7,e:"br"}," ",{p:[134,4,6523],t:7,e:"span",a:{"class":"highlight"},f:["Explosion Purity Threshold:"]}," ",{p:[135,4,6587],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.purityE",p:[135,26,6609]}]}," ",{p:[136,4,6649],t:7,e:"br"}],n:50,r:"data.fermianalyze",p:[115,3,5684]}," ",{p:[138,3,6669],t:7,e:"br"}," ",{p:[139,3,6678],t:7,e:"ui-button",a:{action:"goScreen",params:'{"screen": "home"}'},f:["Back"]}]}]}],x:{r:["data.screen"],s:'_0=="home"'}}]},e.exports=a.extend(r.exports)},{341:341}],381:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Recipient Contents"},f:[{p:[2,2,41],t:7,e:"ui-section",f:[{p:[3,3,56],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[3,34,87]}],action:"ejectBeaker"},f:["Eject"]}," ",{p:[4,3,173],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[4,35,205]}],action:"input"},f:["Input"]}," ",{p:[5,3,285],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,35,317]}],action:"amount"},f:[{t:2,r:"data.amount",p:[5,96,378]},"U"]}," ",{p:[6,3,409],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"disabled":null'},p:[6,33,439]}],action:"makecup"},f:["Create Beaker"]}]}]}," ",{p:[9,1,556],t:7,e:"ui-display",a:{title:"Recipient"},f:[{p:[10,2,588],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[12,4,651],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[12,10,657]},"/",{t:2,r:"data.beakerMaxVolume",p:[12,52,699]}," Units"]}," ",{t:4,f:[{p:[14,5,775],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[14,48,818]}," units of ",{t:2,r:"name",p:[14,83,853]}]},{p:[14,98,868],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[13,4,740]},{t:4,n:51,f:[{p:[16,5,890],t:7,e:"span",a:{"class":"bad"},f:["Recipient Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,3,620]},{t:4,n:51,f:[{p:[19,4,958],t:7,e:"span",a:{"class":"average"},f:["No Recipient"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],382:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,15],t:7,e:"ui-button",a:{action:"toggle"},f:[{t:2,x:{r:["data.recollection"],s:'_0?"Recital":"Recollection"'},p:[2,30,42]}]}]}," ",{t:4,f:[{p:[5,3,145],t:7,e:"ui-display",f:[{t:3,r:"data.rec_text",p:[6,3,160]}," ",{t:4,f:[{p:[8,4,224],t:7,e:"br"},{p:[8,8,228],t:7,e:"ui-button",a:{action:"rec_category",params:['{"category": "',{t:2,r:"name",p:[8,63,283]},'"}']},f:[{t:3,r:"name",p:[8,75,295]}," - ",{t:3,r:"desc",p:[8,88,308]}]}],n:52,r:"data.recollection_categories",p:[7,3,182]}," ",{t:3,r:"data.rec_section",p:[10,3,345]}," ",{t:3,r:"data.rec_binds",p:[11,3,370]}]}],n:50,r:"data.recollection",p:[4,1,117]},{t:4,n:51,f:[{p:[14,2,418],t:7,e:"ui-display",a:{title:"Power",button:0},f:[{p:[15,4,455],t:7,e:"ui-section",f:[{t:3,r:"data.power",p:[16,6,473]}]}]}," ",{p:[19,2,523],t:7,e:"ui-display",f:[{p:[20,3,538],t:7,e:"ui-section",f:[{p:[21,4,554],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Driver"?"selected":null'},p:[21,22,572]}],action:"select",params:'{"category": "Driver"}'},f:["Driver"]}," ",{p:[22,4,694],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Script"?"selected":null'},p:[22,22,712]}],action:"select",params:'{"category": "Script"}'},f:["Scripts"]}," ",{p:[23,4,835],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Application"?"selected":null'},p:[23,22,853]}],action:"select",params:'{"category": "Application"}'},f:["Applications"]}," ",{p:[24,4,991],t:7,e:"br"},{t:3,r:"data.tier_info",p:[24,8,995]}]}," ",{p:[26,3,1034],t:7,e:"ui-section",f:[{t:3,r:"data.scripturecolors",p:[27,4,1050]}]},{p:[28,16,1092],t:7,e:"hr"}," ",{p:[29,3,1099],t:7,e:"ui-section",f:[{t:4,f:[{p:[31,4,1142],t:7,e:"div",f:[{p:[31,9,1147],t:7,e:"ui-button",a:{tooltip:[{t:3,r:"tip",p:[31,29,1167]}],"tooltip-side":"right",action:"recite",params:['{"category": "',{t:2,r:"type",p:[31,99,1237]},'"}']},f:["Recite ",{t:3,r:"required",p:[31,118,1256]}]}," ",{t:4,f:[{t:4,f:[{p:[34,6,1329],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[34,53,1376]},'"}']},f:["Unbind ",{t:3,r:"bound",p:[34,72,1395]}]}],n:50,r:"bound",p:[33,5,1310]},{t:4,n:51,f:[{p:[36,6,1437],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[36,53,1484]},'"}']},f:["Quickbind"]}],r:"bound"}],n:50,r:"quickbind",p:[32,6,1288]}," ",{t:3,r:"name",p:[39,6,1548]}," ",{t:3,r:"descname",p:[39,17,1559]}," ",{t:3,r:"invokers",p:[39,32,1574]}]}],n:52,r:"data.scripture",p:[30,3,1114]}]}]}],r:"data.recollection"}]},e.exports=a.extend(r.exports)},{341:341}],383:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Codex Gigas"},f:[{p:[2,2,34],t:7,e:"ui-section",f:[{t:2,r:"data.name",p:[3,3,49]}]}," ",{p:[5,5,82],t:7,e:"ui-section",a:{label:"Prefix"},f:[{p:[6,3,112],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[6,22,131]}],action:"Dark "},f:["Dark"]}," ",{p:[7,3,215],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[7,22,234]}],action:"Hellish "},f:["Hellish"]}," ",{p:[8,3,324],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[8,22,343]}],action:"Fallen "},f:["Fallen"]}," ",{p:[9,3,431],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[9,22,450]}],action:"Fiery "},f:["Fiery"]}," ",{p:[10,3,536],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[10,22,555]}],action:"Sinful "},f:["Sinful"]}," ",{p:[11,3,643],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[11,22,662]}],action:"Blood "},f:["Blood"]}," ",{p:[12,3,748],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[12,22,767]}],action:"Fluffy "},f:["Fluffy"]}]}," ",{p:[14,5,875],t:7,e:"ui-section",a:{label:"Title"},f:[{p:[15,3,904],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[15,22,923]}],action:"Lord "},f:["Lord"]}," ",{p:[16,3,1007],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[16,22,1026]}],action:"Prelate "},f:["Prelate"]}," ",{p:[17,3,1116],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[17,22,1135]}],action:"Count "},f:["Count"]}," ",{p:[18,3,1221],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[18,22,1240]}],action:"Viscount "},f:["Viscount"]}," ",{p:[19,3,1332],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[19,22,1351]}],action:"Vizier "},f:["Vizier"]}," ",{p:[20,3,1439],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[20,22,1458]}],action:"Elder "},f:["Elder"]}," ",{p:[21,3,1544],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[21,22,1563]}],action:"Adept "},f:["Adept"]}]}," ",{p:[23,5,1669],t:7,e:"ui-section",a:{label:"Name"},f:[{p:[24,3,1697],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[24,22,1716]}],action:"hal"},f:["hal"]}," ",{p:[25,3,1797],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[25,22,1816]}],action:"ve"},f:["ve"]}," ",{p:[26,3,1895],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[26,22,1914]}],action:"odr"},f:["odr"]}," ",{p:[27,3,1995],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[27,22,2014]}],action:"neit"},f:["neit"]}," ",{p:[28,3,2097],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[28,22,2116]}],action:"ci"},f:["ci"]}," ",{p:[29,3,2195],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[29,22,2214]}],action:"quon"},f:["quon"]}," ",{p:[30,3,2297],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[30,22,2316]}],action:"mya"},f:["mya"]}," ",{p:[31,3,2397],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[31,22,2416]}],action:"folth"},f:["folth"]}," ",{p:[32,3,2501],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[32,22,2520]}],action:"wren"},f:["wren"]}," ",{p:[33,3,2603],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[33,22,2622]}],action:"geyr"},f:["geyr"]}," ",{p:[34,3,2705],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[34,22,2724]}],action:"hil"},f:["hil"]}," ",{p:[35,3,2805],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[35,22,2824]}],action:"niet"},f:["niet"]}," ",{p:[36,3,2907],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[36,22,2926]}],action:"twou"},f:["twou"]}," ",{p:[37,3,3009],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[37,22,3028]}],action:"phi"},f:["phi"]}," ",{p:[38,3,3109],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[38,22,3128]}],action:"coa"},f:["coa"]}]}," ",{p:[40,5,3229],t:7,e:"ui-section",a:{label:"suffix"},f:[{p:[41,3,3259],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[41,22,3278]}],action:" the Red"},f:["the Red"]}," ",{p:[42,3,3368],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[42,22,3387]}],action:" the Soulless"},f:["the Soulless"]}," ",{p:[43,3,3487],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[43,22,3506]}],action:" the Master"},f:["the Master"]}," ",{p:[44,3,3602],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[44,22,3621]}],action:", the Lord of all things"},f:["the Lord of all things"]}," ",{p:[45,3,3742],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[45,22,3761]}],action:", Jr."},f:["jr"]}]}," ",{p:[47,5,3863],t:7,e:"ui-section",a:{label:"submit"},f:[{p:[48,3,3894],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0>=4?null:"disabled"'},p:[48,21,3912]}],action:"search"},f:["search"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],384:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[2,1,1],t:7,e:"ui-button",a:{icon:"circle",action:"clean_order"},f:["Clear Order"]},{p:[2,70,70],t:7,e:"br"},{p:[2,74,74],t:7,e:"br"}," ",{p:[3,1,79],t:7,e:"i",f:["Your new computer device you always dreamed of is just four steps away..."]},{p:[3,81,159],t:7,e:"hr"}," ",{t:4,f:[" ",{p:[5,1,219],t:7,e:"div",a:{"class":"item"},f:[{p:[6,2,239],t:7,e:"h2",f:["Step 1: Select your device type"]}," ",{p:[7,2,281],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "1"}'},f:["Laptop"]}," ",{p:[8,2,370],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "2"}'},f:["LTablet"]}]}],n:50,x:{r:["data.state"],s:"_0==0"},p:[4,1,164]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.state"],s:"_0==1"},f:[{p:[11,1,492],t:7,e:"div",a:{"class":"item"},f:[{p:[12,2,512],t:7,e:"h2",f:["Step 2: Personalise your device"]}," ",{p:[13,2,554],t:7,e:"table",f:[{p:[14,3,564],t:7,e:"tr",f:[{p:[15,4,572],t:7,e:"td",f:[{p:[15,8,576],t:7,e:"b",f:["Current Price:"]}]},{p:[16,4,601],t:7,e:"td",f:[{t:2,r:"data.totalprice",p:[16,8,605]},"C"]}]}," ",{p:[18,3,636],t:7,e:"tr",f:[{p:[19,4,645],t:7,e:"td",f:[{p:[19,8,649],t:7,e:"b",f:["Battery:"]}]},{p:[20,4,668],t:7,e:"td",f:[{p:[20,8,672],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "1"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==1?"selected":null'},p:[20,73,737]}]},f:["Standard"]}]},{p:[21,4,807],t:7,e:"td",f:[{p:[21,8,811],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "2"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==2?"selected":null'},p:[21,73,876]}]},f:["Upgraded"]}]},{p:[22,4,946],t:7,e:"td",f:[{p:[22,8,950],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "3"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==3?"selected":null'},p:[22,73,1015]}]},f:["Advanced"]}]}]}," ",{p:[24,3,1092],t:7,e:"tr",f:[{p:[25,4,1100],t:7,e:"td",f:[{p:[25,8,1104],t:7,e:"b",f:["Hard Drive:"]}]},{p:[26,4,1126],t:7,e:"td",f:[{p:[26,8,1130],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "1"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==1?"selected":null'},p:[26,67,1189]}]},f:["Standard"]}]},{p:[27,4,1256],t:7,e:"td",f:[{p:[27,8,1260],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "2"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==2?"selected":null'},p:[27,67,1319]}]},f:["Upgraded"]}]},{p:[28,4,1386],t:7,e:"td",f:[{p:[28,8,1390],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "3"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==3?"selected":null'},p:[28,67,1449]}]},f:["Advanced"]}]}]}," ",{p:[30,3,1523],t:7,e:"tr",f:[{p:[31,4,1531],t:7,e:"td",f:[{p:[31,8,1535],t:7,e:"b",f:["Network Card:"]}]},{p:[32,4,1559],t:7,e:"td",f:[{p:[32,8,1563],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "0"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==0?"selected":null'},p:[32,73,1628]}]},f:["None"]}]},{p:[33,4,1694],t:7,e:"td",f:[{p:[33,8,1698],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "1"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==1?"selected":null'},p:[33,73,1763]}]},f:["Standard"]}]},{p:[34,4,1833],t:7,e:"td",f:[{p:[34,8,1837],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "2"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==2?"selected":null'},p:[34,73,1902]}]},f:["Advanced"]}]}]}," ",{p:[36,3,1979],t:7,e:"tr",f:[{p:[37,4,1987],t:7,e:"td",f:[{p:[37,8,1991],t:7,e:"b",f:["Nano Printer:"]}]},{p:[38,4,2015],t:7,e:"td",f:[{p:[38,8,2019],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "0"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==0?"selected":null'},p:[38,73,2084]}]},f:["None"]}]},{p:[39,4,2152],t:7,e:"td",f:[{p:[39,8,2156],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "1"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==1?"selected":null'},p:[39,73,2221]}]},f:["Standard"]}]}]}," ",{p:[41,3,2300],t:7,e:"tr",f:[{p:[42,4,2308],t:7,e:"td",f:[{p:[42,8,2312],t:7,e:"b",f:["Card Reader:"]}]},{p:[43,4,2335],t:7,e:"td",f:[{p:[43,8,2339],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "0"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==0?"selected":null'},p:[43,67,2398]}]},f:["None"]}]},{p:[44,4,2461],t:7,e:"td",f:[{p:[44,8,2465],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "1"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==1?"selected":null'},p:[44,67,2524]}]},f:["Standard"]}]}]}]}," ",{t:4,f:[" ",{p:[49,4,2658],t:7,e:"table",f:[{p:[50,5,2670],t:7,e:"tr",f:[{p:[51,6,2680],t:7,e:"td",f:[{p:[51,10,2684],t:7,e:"b",f:["Processor Unit:"]}]},{p:[52,6,2712],t:7,e:"td",f:[{p:[52,10,2716],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "1"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==1?"selected":null'},p:[52,67,2773]}]},f:["Standard"]}]},{p:[53,6,2841],t:7,e:"td",f:[{p:[53,10,2845],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "2"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==2?"selected":null'},p:[53,67,2902]}]},f:["Advanced"]}]}]}," ",{p:[55,5,2979],t:7,e:"tr",f:[{p:[56,6,2989],t:7,e:"td",f:[{p:[56,10,2993],t:7,e:"b",f:["Tesla Relay:"]}]},{p:[57,6,3018],t:7,e:"td",f:[{p:[57,10,3022],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "0"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==0?"selected":null'},p:[57,71,3083]}]},f:["None"]}]},{p:[58,6,3149],t:7,e:"td",f:[{p:[58,10,3153],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "1"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==1?"selected":null'},p:[58,71,3214]}]},f:["Standard"]}]}]}]}],n:50,x:{r:["data.devtype"],s:"_0!=2"},p:[48,3,2612]}," ",{p:[62,3,3313],t:7,e:"table",f:[{p:[63,4,3324],t:7,e:"tr",f:[{p:[64,5,3333],t:7,e:"td",f:[{p:[64,9,3337],t:7,e:"b",f:["Confirm Order:"]}]},{p:[65,5,3363],t:7,e:"td",f:[{p:[65,9,3367],t:7,e:"ui-button",a:{action:"confirm_order"},f:["CONFIRM"]}]}]}]}," ",{p:[69,2,3444],t:7,e:"hr"}," ",{p:[70,2,3450],t:7,e:"b",f:["Battery"]}," allows your device to operate without external utility power source. Advanced batteries increase battery life.",{p:[70,127,3575],t:7,e:"br"}," ",{p:[71,2,3581],t:7,e:"b",f:["Hard Drive"]}," stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.",{p:[71,130,3709],t:7,e:"br"}," ",{p:[72,2,3715],t:7,e:"b",f:["Network Card"]}," allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts.",{p:[72,233,3946],t:7,e:"br"}," ",{p:[73,2,3952],t:7,e:"b",f:["Processor Unit"]}," is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.",{p:[73,208,4158],t:7,e:"br"}," ",{p:[74,2,4164],t:7,e:"b",f:["Tesla Relay"]}," is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source. This component is currently unavailable on tablet computers due to size restrictions.",{p:[74,246,4408],t:7,e:"br"}," ",{p:[75,2,4414],t:7,e:"b",f:["Nano Printer"]}," is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.",{p:[75,241,4653],t:7,e:"br"}," ",{p:[76,2,4659],t:7,e:"b",f:["Card Reader"]}," adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards."]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&(_0==2)"},f:[" ",{p:[79,2,4903],t:7,e:"h2",f:["Step 3: Payment"]}," ",{p:[80,2,4929],t:7,e:"b",f:["Your device is now ready for fabrication.."]},{p:[80,51,4978],t:7,e:"br"}," ",{p:[81,2,4984],t:7,e:"i",f:["Please ensure the required amount of credits are in the machine, then press purchase."]},{p:[81,94,5076],t:7,e:"br"}," ",{p:[82,2,5082],t:7,e:"i",f:["Current credits: ",{p:[82,22,5102],t:7,e:"b",f:[{t:2,r:"data.credits",p:[82,25,5105]},"C"]}]},{p:[82,50,5130],t:7,e:"br"}," ",{p:[83,2,5136],t:7,e:"i",f:["Total price: ",{p:[83,18,5152],t:7,e:"b",f:[{t:2,r:"data.totalprice",p:[83,21,5155]},"C"]}]},{p:[83,49,5183],t:7,e:"br"},{p:[83,53,5187],t:7,e:"br"}," ",{p:[84,2,5193],t:7,e:"ui-button",a:{action:"purchase",state:[{t:2,x:{r:["data.credits","data.totalprice"],s:'_0>=_1?null:"disabled"'},p:[84,38,5229]}]},f:["PURCHASE"]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&((!(_0==2))&&(_0==3))"},f:[" ",{p:[87,2,5337],t:7,e:"h2",f:["Step 4: Thank you for your purchase"]},{p:[87,46,5381],t:7,e:"br"}," ",{p:[88,2,5387],t:7,e:"b",f:["Should you experience any issues with your new device, contact your local network admin for assistance."]}]}],x:{r:["data.state"],s:"_0==0"}}]},e.exports=a.extend(r.exports)},{341:341}],385:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,22],t:7,e:"ui-display",f:[{p:[3,2,37],t:7,e:"ui-section",a:{label:"Cap"},f:[{p:[4,3,65],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.is_capped"],s:'_0?"power-off":"close"'},p:[4,20,82]}],style:[{t:2,x:{r:["data.is_capped"],s:'_0?null:"selected"'},p:[4,71,133]}],action:"toggle_cap"},f:[{t:2,x:{r:["data.is_capped"],s:'_0?"On":"Off"'},p:[6,4,202]}]}]}]}],n:50,r:"data.has_cap",p:[1,1,0]},{p:[10,1,288],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,2,419],t:7,e:"ui-section",f:[{p:[15,3,435],t:7,e:"ui-button",a:{action:"select_colour"},f:["Select New Colour"]}]}],n:50,r:"data.can_change_colour",p:[13,1,386]}]}," ",{p:[19,1,540],t:7,e:"ui-display",a:{title:"Stencil"},f:[{t:4,f:[{p:[21,2,599],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[21,21,618]}]},f:[{t:4,f:[{p:[23,7,655],t:7,e:"ui-button",a:{action:"select_stencil",params:['{"item":"',{t:2,r:"item",p:[23,59,707]},'"}'],style:[{t:2,x:{r:["item","data.selected_stencil"],s:'_0==_1?"selected":null'},p:[24,12,731]}]},f:[{t:2,r:"item",p:[25,4,791]}]}],n:52,r:"items",p:[22,3,632]}]}],n:52,r:"data.drawables",p:[20,3,572]}]}," ",{p:[31,1,874],t:7,e:"ui-display",a:{title:"Text Mode"},f:[{p:[32,2,907],t:7,e:"ui-section",a:{label:"Current Buffer"},f:[{t:2,r:"data.text_buffer",p:[32,37,942]}]}," ",{p:[34,2,981],t:7,e:"ui-section",f:[{p:[34,14,993],t:7,e:"ui-button",a:{action:"enter_text"},f:["New Text"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],386:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{isHead:function(t){return t%10==0},dept_class:function(t){return 0==t?"dept-cap":t>=10&&20>t?"dept-sec":t>=20&&30>t?"dept-med":t>=30&&40>t?"dept-sci":t>=40&&50>t?"dept-eng":t>=50&&60>t?"dept-cargo":t>=200&&230>t?"dept-cent":"dept-other"},health_state:function(t,e,n,a){var r=t+e+n+a;return 0>=r?"health-5":25>=r?"health-4":50>=r?"health-3":75>=r?"health-2":"health-0"}}}}(r),r.exports.css=" .health {\n width: 16px;\n height: 16px;\n background-color: #FFF;\n border: 1px solid #434343;\n position: relative;\n top: 2px;\n display: inline-block;\n }\n .health-5 { background-color: #17d568; }\n .health-4 { background-color: #2ecc71; }\n .health-3 { background-color: #e67e22; }\n .health-2 { background-color: #ed5100; }\n .health-1 { background-color: #e74c3c; }\n .health-0 { background-color: #ed2814; }\n\n .dept-cap {color : #C06616;}\n .dept-sec {color : #E74C3C;}\n .dept-med {color : #3498DB;}\n .dept-sci {color : #9B59B6;}\n .dept-eng {color : #F1C40F;}\n .dept-cargo {color : #F39C12;}\n .dept-cent {color : #00C100;}\n .dept-other {color: #C38312;}\n\n .oxy { color : #3498db; }\n .toxin { color : #2ecc71; }\n .burn { color : #e67e22; }\n .brute { color : #e74c3c; }\n\n table.crew{\n border-collapse: collapse;\n }\n\n table.crew td {\n padding : 0px 10px;\n }",r.exports.template={v:3,t:[" ",{p:[27,1,1004],t:7,e:"ui-display",f:[{p:[28,2,1018],t:7,e:"ui-section",f:[{p:[29,3,1033],t:7,e:"table",a:{"class":"crew"},f:[{p:[30,3,1056],t:7,e:"thead",f:[{p:[31,3,1066],t:7,e:"tr",f:[{p:[32,4,1074],t:7,e:"th",f:["Name"]}," ",{p:[33,4,1091],t:7,e:"th",f:["Status"]}," ",{p:[34,4,1110],t:7,e:"th",f:["Vitals"]}," ",{p:[35,4,1129],t:7,e:"th",f:["Position"]}," ",{t:4,f:[{p:[37,5,1180],t:7,e:"th",f:["Tracking"]}],n:50,r:"data.link_allowed",p:[36,4,1150]}]}]}," ",{p:[41,3,1230],t:7,e:"tbody",f:[{t:4,f:[{p:[43,4,1266],t:7,e:"tr",f:[{p:[44,5,1275],t:7,e:"td",f:[{p:[45,6,1285],t:7,e:"span",a:{"class":[{t:2,x:{r:["isHead","ijob"],s:'_0(_1)?"bold ":""'},p:[45,19,1298]},{t:2,x:{r:["dept_class","ijob"],s:"_0(_1)"},p:[45,49,1328]}]},f:[{t:2,r:"name",p:[46,7,1357]}," (",{t:2,r:"assignment",p:[46,17,1367]},") ",{p:[47,6,1388],t:7,e:"span",f:[]}]}]}," ",{p:[49,5,1409],t:7,e:"td",f:[{t:4,f:[{p:[51,7,1448],t:7,e:"span",a:{"class":["health ",{t:2,x:{r:["health_state","oxydam","toxdam","burndam","brutedam"],s:"_0(_1,_2,_3,_4)"},p:[51,27,1468]}]}}],n:50,x:{r:["oxydam"],s:"_0!=null"},p:[50,6,1419]},{t:4,n:51,f:[{t:4,f:[{p:[54,8,1573],t:7,e:"span",a:{"class":"health health-5"}}],n:50,r:"life_status",p:[53,7,1546]},{t:4,n:51,f:[{p:[56,8,1633],t:7,e:"span",a:{"class":"health health-0"}}],r:"life_status"}],x:{r:["oxydam"],s:"_0!=null"}}]}," ",{p:[60,5,1712],t:7,e:"td",f:[{t:4,f:[{p:[62,7,1751],t:7,e:"span",f:["( ",{p:[64,8,1773],t:7,e:"span",a:{"class":"oxy"},f:[{t:2,r:"oxydam",p:[64,26,1791]}]}," / ",{p:[66,8,1825],t:7,e:"span",a:{"class":"toxin"},f:[{t:2,r:"toxdam",p:[66,28,1845]}]}," / ",{p:[68,8,1879],t:7,e:"span",a:{"class":"burn"},f:[{t:2,r:"burndam",p:[68,27,1898]}]}," / ",{p:[70,8,1933],t:7,e:"span",a:{"class":"brute"},f:[{t:2,r:"brutedam",p:[70,28,1953]}]}," )"]}],n:50,x:{r:["oxydam"],s:"_0!=null"},p:[61,6,1722]},{t:4,n:51,f:[{t:4,f:[{p:[75,8,2042],t:7,e:"span",f:["Alive"]}],n:50,r:"life_status",p:[74,7,2015]},{t:4,n:51,f:[{p:[77,8,2083],t:7,e:"span",f:["Dead"]}],r:"life_status"}],x:{r:["oxydam"],s:"_0!=null"}}]}," ",{p:[81,5,2142],t:7,e:"td",f:[{t:4,f:[{p:[83,6,2178],t:7,e:"span",f:[{t:2,r:"area",p:[83,12,2184]}]}],n:50,x:{r:["pos_x"],s:"_0!=null"},p:[82,5,2151]},{t:4,n:51,f:[{p:[85,6,2218],t:7,e:"span",f:["N/A"]}],x:{r:["pos_x"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[89,6,2293],t:7,e:"td",f:[{p:[90,7,2304],t:7,e:"ui-button",a:{action:"select_person",state:[{t:2,x:{r:["can_track"],s:'_0?null:"disabled"'},p:[90,48,2345]}],params:['{"name":"',{t:2,r:"name",p:[90,100,2397]},'"}']},f:["Track"]}]}],n:50,r:"data.link_allowed",p:[88,5,2261]}]}],n:52,r:"data.sensors",p:[42,3,1240]}]}]}]}]}," "]},e.exports=a.extend(r.exports)},{341:341}],387:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,32],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,64],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,70]}]}]}," ",{t:4,f:[{p:[6,5,184],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,217],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,230]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,259]}]}]}," ",{p:[9,4,309],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[10,6,347],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.temperaturestatus",p:[10,19,360]}]},f:[{t:2,r:"data.occupant.bodyTemperature",p:[10,56,397]}," K"]}]}," ",{p:[12,5,461],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[13,7,495],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[13,20,508]}],max:[{t:2,r:"data.occupant.maxHealth",p:[13,54,542]}],value:[{t:2,r:"data.occupant.health",p:[13,90,578]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[14,16,619]}]},f:[{t:2,r:"data.occupant.health",p:[14,68,671]}]}]}," ",{t:4,f:[{p:[17,7,892],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[17,26,911]}]},f:[{p:[18,9,931],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[18,30,952]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,66,988]}],state:"bad"},f:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,103,1025]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[16,5,727]}],n:50,r:"data.hasOccupant",p:[5,3,155]}]}," ",{p:[23,1,1116],t:7,e:"ui-display",a:{title:"Cell"},f:[{p:[24,3,1144],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[25,5,1175],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[25,22,1192]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[26,14,1251]}],state:[{t:2,x:{r:["data.isOpen"],s:'_0?"disabled":null'},p:[27,14,1306]}],action:"power"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[28,22,1364]}]}]}," ",{p:[30,3,1430],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[31,3,1465],t:7,e:"span",a:{"class":[{t:2,r:"data.temperaturestatus",p:[31,16,1478]}]},f:[{t:2,r:"data.cellTemperature",p:[31,44,1506]}," K"]}]}," ",{p:[33,2,1556],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[34,5,1586],t:7,
-e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOpen"],s:'_0?"unlock":"lock"'},p:[34,22,1603]}],action:"door"},f:[{t:2,x:{r:["data.isOpen"],s:'_0?"Open":"Closed"'},p:[34,73,1654]}]}," ",{p:[35,5,1706],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoEject"],s:'_0?"sign-out":"sign-in"'},p:[35,22,1723]}],action:"autoeject"},f:[{t:2,x:{r:["data.autoEject"],s:'_0?"Auto":"Manual"'},p:[35,86,1787]}]}]}]}," ",{p:{button:[{p:[40,5,1928],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[40,36,1959]}],action:"ejectbeaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[42,3,2060],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[45,9,2167],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,r:"volume",p:[45,52,2210]}," units of ",{t:2,r:"name",p:[45,72,2230]}]},{p:[45,87,2245],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[44,7,2128]},{t:4,n:51,f:[{p:[47,9,2274],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[43,5,2094]},{t:4,n:51,f:[{p:[50,7,2347],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],388:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,14],t:7,e:"ui-section",a:{label:"State"},f:[{t:4,f:[{p:[4,4,73],t:7,e:"span",a:{"class":"good"},f:["Ready"]}],n:50,r:"data.full_pressure",p:[3,3,43]},{t:4,n:51,f:[{t:4,f:[{p:[7,5,147],t:7,e:"span",a:{"class":"bad"},f:["Power Disabled"]}],n:50,r:"data.panel_open",p:[6,4,119]},{t:4,n:51,f:[{t:4,f:[{p:[10,6,239],t:7,e:"span",a:{"class":"average"},f:["Pressurizing"]}],n:50,r:"data.pressure_charging",p:[9,5,203]},{t:4,n:51,f:[{p:[12,6,299],t:7,e:"span",a:{"class":"bad"},f:["Off"]}],r:"data.pressure_charging"}],r:"data.panel_open"}],r:"data.full_pressure"}]}," ",{p:[17,2,377],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[18,3,409],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.per",p:[18,36,442]}],state:"good"},f:[{t:2,r:"data.per",p:[18,63,469]},"%"]}]}," ",{p:[20,5,511],t:7,e:"ui-section",a:{label:"Handle"},f:[{p:[21,9,547],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.flush"],s:'_0?"toggle-on":"toggle-off"'},p:[22,10,568]}],state:[{t:2,x:{r:["data.isai","data.panel_open"],s:'_0||_1?"disabled":null'},p:[23,11,625]}],action:[{t:2,x:{r:["data.flush"],s:'_0?"handle-0":"handle-1"'},p:[24,12,691]}]},f:[{t:2,x:{r:["data.flush"],s:'_0?"Disengage":"Engage"'},p:[25,5,739]}]}]}," ",{p:[27,2,811],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[28,3,840],t:7,e:"ui-button",a:{icon:"sign-out",state:[{t:2,x:{r:["data.isai"],s:'_0?"disabled":null'},p:[28,37,874]}],action:"eject"},f:["Eject Contents"]},{p:[28,114,951],t:7,e:"br"}]}," ",{p:[30,2,973],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,3,1002],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["data.panel_open"],s:'_0?"disabled":null'},p:[31,38,1037]}],action:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"pump-0":"pump-1"'},p:[31,87,1086]}],style:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"selected":null'},p:[31,145,1144]}]}},{p:[31,206,1205],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],389:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"DNA Vault Database"},f:[{p:[2,3,42],t:7,e:"ui-section",a:{label:"Human DNA"},f:[{p:[3,7,79],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.dna_max",p:[3,28,100]}],value:[{t:2,r:"data.dna",p:[3,53,125]}]},f:[{t:2,r:"data.dna",p:[3,67,139]},"/",{t:2,r:"data.dna_max",p:[3,80,152]}," Samples"]}]}," ",{p:[5,3,204],t:7,e:"ui-section",a:{label:"Plant Data"},f:[{p:[6,5,240],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.plants_max",p:[6,26,261]}],value:[{t:2,r:"data.plants",p:[6,54,289]}]},f:[{t:2,r:"data.plants",p:[6,71,306]},"/",{t:2,r:"data.plants_max",p:[6,87,322]}," Samples"]}]}," ",{p:[8,3,377],t:7,e:"ui-section",a:{label:"Animal Data"},f:[{p:[9,5,414],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.animals_max",p:[9,26,435]}],value:[{t:2,r:"data.animals",p:[9,55,464]}]},f:[{t:2,r:"data.animals",p:[9,73,482]},"/",{t:2,r:"data.animals_max",p:[9,90,499]}," Samples"]}]}]}," ",{t:4,f:[{p:[13,1,604],t:7,e:"ui-display",a:{title:"Personal Gene Therapy"},f:[{p:[14,3,650],t:7,e:"ui-section",f:[{p:[15,2,664],t:7,e:"span",f:["Applicable gene therapy treatments:"]}]}," ",{p:[17,3,731],t:7,e:"ui-section",f:[{p:[18,2,745],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceA",p:[18,47,790]},'"}']},f:[{t:2,r:"data.choiceA",p:[18,67,810]}]}," ",{p:[19,2,840],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceB",p:[19,47,885]},'"}']},f:[{t:2,r:"data.choiceB",p:[19,67,905]}]}]}]}],n:50,x:{r:["data.completed","data.used"],s:"_0&&!_1"},p:[12,1,567]}]},e.exports=a.extend(r.exports)},{341:341}],390:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,32],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,64],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,70]}]}]}," ",{t:4,f:[{p:[6,5,178],t:7,e:"ui-section",a:{label:"Items in storage"},f:[{p:[7,4,219],t:7,e:"span",f:[{t:2,r:"data.items",p:[7,10,225]}]}]}],n:50,r:"data.items",p:[5,3,155]}," ",{t:4,f:[{p:[11,5,300],t:7,e:"ui-section",a:{label:"State"},f:[{p:[12,7,333],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[12,20,346]}]},f:[{t:2,r:"data.occupant.stat",p:[12,49,375]}]}]}," ",{p:[14,5,426],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[15,7,460],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[15,20,473]}],max:[{t:2,r:"data.occupant.maxHealth",p:[15,54,507]}],value:[{t:2,r:"data.occupant.health",p:[15,90,543]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[16,16,584]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[16,68,636]}]}]}," ",{t:4,f:[{p:[19,7,870],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[19,26,889]}]},f:[{p:[20,9,909],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[20,30,930]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[20,66,966]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[20,103,1003]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[18,5,705]}," ",{p:[23,5,1087],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[24,9,1122],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[24,22,1135]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[24,68,1181]}]}]}," ",{p:[26,5,1262],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[27,9,1297],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[27,22,1310]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[27,68,1356]}]}]}," ",{p:[29,5,1438],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[31,11,1523],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[31,54,1566]}," units of ",{t:2,r:"name",p:[31,89,1601]}]},{p:[31,104,1616],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[30,9,1479]},{t:4,n:51,f:[{p:[33,11,1649],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[10,3,274]}]}," ",{p:[38,1,1740],t:7,e:"ui-display",a:{title:"Operations"},f:[{p:[39,3,1774],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[41,7,1832],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied"],s:'_0?null:"disabled"'},p:[41,38,1863]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[41,111,1936]},'"}']},f:[{t:2,r:"name",p:[41,121,1946]}]},{p:[41,141,1966],t:7,e:"br"}],n:52,r:"data.chem",p:[40,5,1806]}]}," ",{p:[44,2,2003],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[45,6,2035],t:7,e:"ui-button",a:{icon:"sign-out",action:"eject"},f:["Eject Contents"]}]}," ",{p:[47,2,2120],t:7,e:"ui-section",a:{label:"Self Cleaning"},f:[{p:[48,3,2157],t:7,e:"ui-button",a:{icon:"recycle",action:"cleaning"},f:["Self-Clean Cycle"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],391:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-display",a:{title:[{t:2,r:"data.question",p:[2,21,41]}]},f:[{p:[3,5,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,9,114],t:7,e:"ui-button",a:{action:"vote",params:['{"answer": "',{t:2,r:"answer",p:[6,45,169]},'"}'],style:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[7,18,200]}]},f:[{t:2,r:"answer",p:[7,53,235]}," (",{t:2,r:"amount",p:[7,65,247]},")"]}],n:52,r:"data.answers",p:[4,7,83]}]}]}],n:50,r:"data.shaking",p:[1,1,0]},{t:4,n:51,f:[{p:[13,3,341],t:7,e:"ui-notice",f:["The eightball is not currently being shaken."]}],r:"data.shaking"}]},e.exports=a.extend(r.exports)},{341:341}],392:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,5,16],t:7,e:"span",f:["Time Until Launch: ",{t:2,r:"data.timer_str",p:[2,30,41]}]}]}," ",{p:[4,1,80],t:7,e:"ui-notice",f:[{p:[5,3,94],t:7,e:"span",f:["Engines: ",{t:2,x:{r:["data.engines_started"],s:'_0?"Online":"Idle"'},p:[5,18,109]}]}]}," ",{p:[7,1,174],t:7,e:"ui-display",a:{title:"Early Launch"},f:[{p:[8,2,209],t:7,e:"span",f:["Authorizations Remaining: ",{t:2,x:{r:["data.emagged","data.authorizations_remaining"],s:'_0?"ERROR":_1'},p:[9,2,242]}]}," ",{p:[10,2,309],t:7,e:"ui-button",a:{icon:"exclamation-triangle",action:"authorize",style:"danger",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[12,10,393]}]},f:["AUTHORIZE"]}," ",{p:[15,2,459],t:7,e:"ui-button",a:{icon:"minus",action:"repeal",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[16,10,508]}]},f:["Repeal"]}," ",{p:[19,2,571],t:7,e:"ui-button",a:{icon:"close",action:"abort",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[20,10,619]}]},f:["Repeal All"]}]}," ",{p:[24,1,699],t:7,e:"ui-display",a:{title:"Authorizations"},f:[{t:4,f:[{p:[26,3,768],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{t:2,r:"name",p:[26,34,799]}," (",{t:2,r:"job",p:[26,44,809]},")"]}],n:52,r:"data.authorizations",p:[25,2,736]},{t:4,n:51,f:[{p:[28,3,843],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:["No authorizations."]}],r:"data.authorizations"}]}]},e.exports=a.extend(r.exports)},{341:341}],393:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,15],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.hidden_message",p:[3,5,48]}]}," ",{p:[5,3,90],t:7,e:"ui-section",a:{label:"Created On"},f:[{t:2,r:"data.realdate",p:[6,5,126]}]}," ",{p:[8,3,162],t:7,e:"ui-section",a:{label:"Approval"},f:[{p:[9,5,196],t:7,e:"ui-button",a:{icon:"arrow-up",state:[{t:2,x:{r:["data.is_creator","data.has_liked"],s:'_0?"disabled":_1?"selected":null'},p:[11,14,242]}],action:"like"},f:[{t:2,r:"data.num_likes",p:[12,21,333]}]}," ",{p:[13,5,368],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.is_creator","data.has_liked","data.has_disliked"],s:'_0?"disabled":!_1&&!_2?"selected":null'},p:[15,14,412]}],action:"neutral"}}," ",{p:[17,5,546],t:7,e:"ui-button",a:{icon:"arrow-down",state:[{t:2,x:{r:["data.is_creator","data.has_disliked"],s:'_0?"disabled":_1?"selected":null'},p:[19,14,594]}],action:"dislike"},f:[{t:2,r:"data.num_dislikes",p:[20,24,691]}]}]}]}," ",{t:4,f:[{p:[24,3,782],t:7,e:"ui-display",a:{title:"Admin Panel"},f:[{p:[25,5,819],t:7,e:"ui-section",a:{label:"Creator Ckey"},f:[{t:2,r:"data.creator_key",p:[25,38,852]}]}," ",{p:[26,5,890],t:7,e:"ui-section",a:{label:"Creator Character Name"},f:[{t:2,r:"data.creator_name",p:[26,48,933]}]}," ",{p:[27,5,972],t:7,e:"ui-button",a:{icon:"remove",action:"delete",style:"danger"},f:["Delete"]}]}],n:50,r:"data.admin_mode",p:[23,1,756]}]},e.exports=a.extend(r.exports)},{341:341}],394:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,14],t:7,e:"span",f:["The requested interface (",{t:2,r:"config.interface",p:[2,34,45]},") was not found. Does it exist?"]}]}]},e.exports=a.extend(r.exports)},{341:341}],395:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,19],t:7,e:"ui-notice",f:["Currently syncing with the database"]}],n:50,r:"data.sync",p:[1,1,0]},{t:4,n:51,f:[{p:{button:[{p:[8,4,156],t:7,e:"ui-button",a:{icon:"eject",action:"eject_all"},f:["Eject all"]}," ",{p:[9,4,224],t:7,e:"ui-button",a:{icon:["toggle-",{t:2,x:{r:["data.show_materials"],s:'_0?"off":"on"'},p:[9,28,248]}],action:"toggle_materials_visibility"},f:[{t:2,x:{r:["data.show_materials"],s:'_0?"Hide":"Show"'},p:[10,5,330]}]}]},t:7,e:"ui-display",a:{title:"Materials",button:0},f:[" ",{t:4,f:[{p:[14,4,436],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[15,5,470],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[16,6,505],t:7,e:"section",a:{"class":"cell"}}," ",{p:[17,6,543],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[20,6,601],t:7,e:"section",a:{"class":"cell"},f:["Amount"]}," ",{p:[23,6,658],t:7,e:"section",a:{"class":"cell"}}," ",{p:[24,6,696],t:7,e:"section",a:{"class":"cell"}}]}," ",{t:4,f:[{p:[27,6,782],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[28,7,818],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[29,8,848]}]}," ",{p:[31,7,880],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"amount",p:[32,8,910]}]}," ",{p:[34,7,944],t:7,e:"section",a:{"class":"cell"},f:[{p:[35,8,974],t:7,e:"ui-button",a:{icon:"eject"},f:["Release amount"]}]}," ",{p:[37,7,1048],t:7,e:"section",a:{"class":"cell",style:"width: 40px;"},f:[{p:[38,8,1099],t:7,e:"ui-button",a:{icon:"eject"},f:["Release all"]}]}]}],n:52,r:"data.all_materials",p:[26,5,748]}]}],n:50,r:"data.show_materials",p:[13,3,405]}]}," ",{p:[45,2,1230],t:7,e:"ui-display",a:{title:"Categories"},f:[{t:4,f:[{p:[47,4,1288],t:7,e:"ui-button",f:[{t:2,r:".",p:[47,15,1299]}]}],r:"data.categories",p:[46,3,1264]}]}],r:"data.sync"}]},e.exports=a.extend(r.exports)},{341:341}],396:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,15],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,5,47],t:7,e:"ui-button",a:{action:"toggle_power",style:[{t:2,x:{r:["data.toggle"],s:'_0?"selected":null'},p:[5,18,107]}]},f:["Turn ",{t:2,x:{r:["data.toggle"],s:'_0?"off":"on"'},p:[6,16,161]}]}]}," ",{p:[9,3,227],t:7,e:"ui-display",a:{title:"Logging"},f:[{t:4,f:[{p:[11,3,282],t:7,e:"ui-section",a:{label:">"},f:[{t:2,r:".",p:[11,25,304]},{p:[11,30,309],t:7,e:"ui-section",f:[]}]}],n:52,r:"data.logs",p:[10,5,260]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],397:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{seclevelState:function(){switch(this.get("data.seclevel")){case"blue":return"average";case"red":return"bad";case"delta":return"bad bold";default:return"good"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[16,1,308],t:7,e:"ui-display",f:[{p:[17,5,325],t:7,e:"ui-section",a:{label:"Alert Level"},f:[{p:[18,9,366],t:7,e:"span",a:{"class":[{t:2,r:"seclevelState",p:[18,22,379]}]},f:[{t:2,x:{r:["text","data.seclevel"],s:"_0.titleCase(_1)"},p:[18,41,398]}]}]}," ",{p:[20,5,461],t:7,e:"ui-section",a:{label:"Controls"},f:[{p:[21,9,499],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.alarm"],s:'_0?"close":"bell-o"'},p:[21,26,516]}],action:[{t:2,x:{r:["data.alarm"],s:'_0?"reset":"alarm"'},p:[21,71,561]}]},f:[{t:2,x:{r:["data.alarm"],s:'_0?"Reset":"Activate"'},p:[22,13,610]}]}]}," ",{t:4,f:[{p:[25,7,709],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[26,9,746],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[24,5,682]}]}]},e.exports=a.extend(r.exports)},{341:341}],398:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[2,1,30],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,2,58],t:7,e:"ui-button",a:{icon:"power-off",style:[{t:2,x:{r:["data.power"],s:'_0?"selected":"danger"'},p:[3,37,93]}],action:"power"},f:[{t:2,x:{r:["data.power"],s:'_0?"Enabled":"Disabled"'},p:[3,92,148]}]}]}," ",{p:[5,1,214],t:7,e:"ui-section",a:{label:"Tag"},f:[{p:[6,2,240],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:[{t:2,r:"data.tag",p:[6,43,281]}]}]}," ",{p:[8,1,320],t:7,e:"ui-section",a:{label:"Scanning mode"},f:[{p:[9,2,356],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.updating"],s:'_0?"unlock":"lock"'},p:[9,18,372]}],style:[{t:2,x:{r:["data.updating"],s:'_0?null:"danger"'},p:[9,63,417]}],action:"updating",tooltip:"Toggle between automatic scanning or scan only when a button is pressed.","tooltip-side":"right"},f:[{t:2,x:{r:["data.updating"],s:'_0?"AUTO":"MANUAL"'},p:[9,221,575]}]}]}," ",{p:[11,1,639],t:7,e:"ui-section",a:{label:"Detection range"},f:[{p:[12,2,677],t:7,e:"ui-button",a:{icon:"refresh",style:[{t:2,x:{r:["data.globalmode"],s:'_0?null:"selected"'},p:[12,35,710]}],action:"globalmode",tooltip:"Local sector or whole region scanning.","tooltip-side":"right"},f:[{t:2,x:{r:["data.globalmode"],s:'_0?"MAXIMUM":"LOCAL"'},p:[12,165,840]}]}]}]}," ",{t:4,f:[{p:[16,2,942],t:7,e:"ui-display",a:{title:"Current Location"},f:[{p:[17,3,982],t:7,e:"span",f:[{t:2,r:"data.current",p:[17,9,988]}]}]}," ",{p:[20,2,1029],t:7,e:"ui-display",a:{title:"Detected Signals"},f:[{t:4,f:[{p:[22,3,1093],t:7,e:"ui-section",a:{label:[{t:2,r:"entrytag",p:[22,21,1111]}]},f:[{p:[23,3,1127],t:7,e:"span",f:[{t:2,r:"area",p:[23,9,1133]}," (",{t:2,r:"coord",p:[23,19,1143]},")"]}," ",{t:4,f:[{p:[25,4,1185],t:7,e:"span",f:["Dist: ",{t:2,r:"dist",p:[25,16,1197]},"m Dir: ",{t:2,r:"degrees",p:[25,31,1212]},"° (",{t:2,r:"direction",p:[25,45,1226]},")"]}],n:50,r:"direction",p:[24,3,1164]}]}],n:52,r:"data.signals",p:[21,2,1068]}]}],n:50,r:"data.power",p:[15,1,922]}]},e.exports=a.extend(r.exports)},{341:341}],399:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Labor Camp Teleporter"},f:[{p:[2,2,44],t:7,e:"ui-section",a:{label:"Teleporter Status"},f:[{p:[3,3,85],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.teleporter"],s:'_0?"good":"bad"'},p:[3,16,98]}]},f:[{t:2,x:{r:["data.teleporter"],s:'_0?"Connected":"Not connected"'},p:[3,54,136]}]}]}," ",{t:4,f:[{p:[6,4,239],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[7,5,273],t:7,e:"span",f:[{t:2,r:"data.teleporter_location",p:[7,11,279]}]}]}," ",{p:[9,4,335],t:7,e:"ui-section",a:{label:"Locked status"},f:[{p:[10,5,374],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"lock":"unlock"'},p:[10,22,391]}],action:"teleporter_lock"},f:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"Locked":"Unlocked"'},p:[10,93,462]}]}," ",{p:[11,5,527],t:7,e:"ui-button",a:{action:"toggle_open"},f:[{t:2,x:{r:["data.teleporter_state_open"],s:'_0?"Open":"Closed"'},p:[11,37,559]}]}]}],n:50,r:"data.teleporter",p:[5,3,212]},{t:4,n:51,f:[{p:[14,4,653],t:7,e:"span",f:[{p:[14,10,659],t:7,e:"ui-button",a:{action:"scan_teleporter"},f:["Scan Teleporter"]}]}],r:"data.teleporter"}]}," ",{p:[17,1,754],t:7,e:"ui-display",a:{title:"Labor Camp Beacon"},f:[{p:[18,2,794],t:7,e:"ui-section",a:{label:"Beacon Status"},f:[{p:[19,3,831],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.beacon"],s:'_0?"good":"bad"'},p:[19,16,844]}]},f:[{t:2,x:{r:["data.beacon"],s:'_0?"Connected":"Not connected"'},p:[19,50,878]}]}]}," ",{t:4,f:[{p:[22,3,971],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[23,4,1004],t:7,e:"span",f:[{t:2,r:"data.beacon_location",p:[23,10,1010]}]}]}],n:50,r:"data.beacon",p:[21,2,949]},{t:4,n:51,f:[{p:[26,4,1072],t:7,e:"span",f:[{p:[26,10,1078],t:7,e:"ui-button",a:{action:"scan_beacon"},f:["Scan Beacon"]}]}],r:"data.beacon"}]}," ",{p:[29,1,1165],t:7,e:"ui-display",a:{title:"Prisoner details"},f:[{p:[30,2,1204],t:7,e:"ui-section",a:{label:"Prisoner ID"},f:[{p:[31,3,1239],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[31,33,1269]}]}]}," ",{t:4,f:[{p:[34,2,1359],t:7,e:"ui-section",a:{label:"Set ID goal"},f:[{p:[35,4,1395],t:7,e:"ui-button",a:{action:"set_goal"},f:[{t:2,r:"data.goal",p:[35,33,1424]}]}]}],n:50,r:"data.id",p:[33,2,1342]}," ",{p:[38,2,1475],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[39,3,1507],t:7,e:"span",f:[{t:2,x:{r:["data.prisoner.name"],s:'_0?_0:"No Occupant"'},p:[39,9,1513]}]}]}," ",{t:4,f:[{p:[42,3,1620],t:7,e:"ui-section",a:{label:"Criminal Status"},f:[{p:[43,4,1660],t:7,e:"span",f:[{t:2,r:"data.prisoner.crimstat",p:[43,10,1666]}]}]}],n:50,r:"data.prisoner",p:[41,2,1596]}]}," ",{p:[47,1,1739],t:7,e:"ui-display",f:[{p:[48,2,1753],t:7,e:"center",f:[{p:[48,10,1761],t:7,e:"ui-button",a:{action:"teleport",state:[{t:2,x:{r:["data.can_teleport"],s:'_0?null:"disabled"'},p:[48,45,1796]}]},f:["Process Prisoner"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],400:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Stored Items"},f:[{t:4,f:[{p:[3,3,59],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,22,78]}]},f:[{p:[4,4,93],t:7,e:"ui-button",a:{action:"release_items",params:['{"mobref":',{t:2,r:"mob",p:[4,56,145]},"}"],state:[{t:2,x:{r:["data.can_reclaim"],s:'_0?null:"disabled"'},p:[4,72,161]}]},f:["Drop Items"]}]}],n:52,r:"data.mobs",p:[2,2,36]}]}]},e.exports=a.extend(r.exports)},{341:341}],401:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,68],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.emagged"],s:'_0?"un":null'},p:[3,20,85]},"lock"],state:[{t:2,x:{r:["data.can_toggle_safety"],s:'_0?null:"disabled"'},p:[3,63,128]}],action:"safety"},f:["Safeties: ",{p:[4,14,206],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.emagged"],s:'_0?"bad":"good"'},p:[4,27,219]}]},f:[{t:2,x:{r:["data.emagged"],s:'_0?"OFF":"ON"'},p:[4,62,254]}]}]}]},t:7,e:"ui-display",a:{title:"Default Programs",button:0},f:[" ",{t:4,f:[{p:[8,2,356],t:7,e:"ui-button",a:{action:"load_program",params:['{"type": ',{t:2,r:"type",p:[8,52,406]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[8,70,424]}]},f:[{t:2,r:"name",p:[9,5,475]}," "]},{p:[10,14,497],t:7,e:"br"}],n:52,r:"data.default_programs",p:[7,2,323]}]}," ",{t:4,f:[{p:[14,2,549],t:7,e:"ui-display",a:{title:"Dangerous Programs"},f:[{t:4,f:[{p:[16,4,623],t:7,e:"ui-button",a:{icon:"warning",action:"load_program",params:['{"type": ',{t:2,r:"type",p:[16,69,688]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[16,87,706]}]},f:[{t:2,r:"name",p:[17,5,757]}," "]},{p:[18,16,781],t:7,e:"br"}],n:52,r:"data.emag_programs",p:[15,3,591]}]}],n:50,r:"data.emagged",p:[13,1,527]}]},e.exports=a.extend(r.exports)},{341:341}],402:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,266],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,298],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,330],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,336]}]}]}," ",{t:4,f:[{p:[20,5,447],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,480],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,493]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,516]}]}]}],n:50,r:"data.occupied",p:[19,3,421]}]}," ",{p:[25,1,656],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[26,2,687],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[27,5,717],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[27,22,734]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[27,71,783]}]}]}," ",{p:[29,3,846],t:7,e:"ui-section",a:{label:"Uses"},f:[{t:2,r:"data.ready_implants",p:[30,5,876]}," ",{t:4,f:[{p:[32,7,938],t:7,e:"span",a:{"class":"fa fa-cog fa-spin"}}],n:50,r:"data.replenishing",p:[31,5,906]}]}," ",{p:[35,3,1002],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[36,7,1038],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.occupied","data.ready_implants","data.ready"],s:'_0&&_1>0&&_2?null:"disabled"'},p:[36,25,1056]}],action:"implant"},f:[{t:2,x:{r:["data.ready","data.special_name"],s:'_0?(_1?_1:"Implant"):"Recharging"'},p:[37,9,1162]}," "]},{p:[38,19,1265],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],403:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[15,3,282],t:7,e:"ui-notice",f:[{p:[16,5,298],t:7,e:"span",f:["Wipe in progress!"]}]}],n:50,r:"data.wiping",p:[14,1,260]},{p:{button:[{t:4,f:[{p:[22,7,458],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.isDead"],s:'_0?"disabled":null'},p:[22,38,489]}],action:"wipe"},f:[{t:2,x:{r:["data.wiping"],s:'_0?"Stop Wiping":"Wipe"'},p:[22,89,540]}," AI"]}],n:50,r:"data.name",p:[21,5,434]}]},t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.name"],s:'_0||"Empty Card"'},p:[19,19,370]}],button:0},f:[" ",{t:4,f:[{p:[26,5,647],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[27,9,683],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"bad":"good"'},p:[27,22,696]}]},f:[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"Offline":"Operational"'},p:[27,76,750]}]}]}," ",{p:[29,5,843],t:7,e:"ui-section",a:{label:"Software Integrity"},f:[{p:[30,7,889],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[30,40,922]}],state:[{t:2,r:"healthState",p:[30,64,946]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[30,81,963]},"%"]}]}," ",{p:[32,5,1024],t:7,e:"ui-section",a:{label:"Laws"},f:[{t:4,f:[{p:[34,9,1084],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[34,33,1108]}]},{p:[34,45,1120],t:7,e:"br"}],n:52,r:"data.laws",p:[33,7,1056]}]}," ",{p:[37,5,1164],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[38,7,1200],t:7,e:"ui-button",a:{icon:"signal",style:[{t:2,x:{r:["data.wireless"],s:'_0?"selected":null'},p:[38,39,1232]}],action:"wireless"},f:["Wireless Activity"]}," ",{p:[39,7,1325],t:7,e:"ui-button",a:{icon:"microphone",style:[{t:2,x:{r:["data.radio"],s:'_0?"selected":null'},p:[39,43,1361]}],action:"radio"},f:["Subspace Radio"]}]}],n:50,r:"data.name",p:[25,3,625]}]}]},e.exports=a.extend(r.exports)},{341:341}],404:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,22],t:7,e:"ui-notice",f:[{p:[3,3,36],t:7,e:"span",f:["Waiting for another device to confirm your request..."]}]}],n:50,r:"data.waiting",p:[1,1,0]},{t:4,n:51,f:[{p:[6,2,127],t:7,e:"ui-display",f:[{p:[7,3,142],t:7,e:"ui-section",f:[{t:4,f:[{p:[9,5,189],t:7,e:"ui-button",a:{icon:"check",action:"auth_swipe"},f:["Authorize ",{t:2,r:"data.auth_required",p:[9,59,243]}]}],n:50,r:"data.auth_required",p:[8,4,158]},{t:4,n:51,f:[{p:[11,5,294],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.red_alert"],s:'_0?"disabled":null'},p:[11,38,327]}],action:"red_alert"},f:["Red Alert"]}," ",{p:[12,5,412],t:7,e:"ui-button",a:{icon:"wrench",state:[{t:2,x:{r:["data.emergency_maint"],s:'_0?"disabled":null'},p:[12,37,444]}],action:"emergency_maint"},f:["Emergency Maintenance Access"]}," ",{p:[13,5,560],t:7,e:"ui-button",a:{icon:"warning",state:"null",action:"bsa_unlock"},f:["Bluespace Artillery Unlock"]}],r:"data.auth_required"}]}]}],r:"data.waiting"}]},e.exports=a.extend(r.exports)},{341:341}],405:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Ore values"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"ui-section",a:{label:[{t:2,r:"ore",p:[3,22,76]}]},f:[{p:[4,4,90],t:7,e:"span",f:[{t:2,r:"value",p:[4,10,96]}]}]}],n:52,r:"data.ores",p:[2,2,34]}]}," ",{p:[8,1,158],t:7,e:"ui-display",a:{title:"Points"},f:[{p:[9,2,188],t:7,e:"ui-section",a:{label:"Unclaimed points"},f:[{p:[10,3,229],t:7,e:"span",f:[{t:2,r:"data.unclaimed_points",p:[10,9,235]}]}," ",{p:[11,3,271],t:7,e:"ui-button",a:{action:"claim_points",state:[{t:2,x:{r:["data.unclaimed_points"],s:'_0?null:"disabled"'},p:[11,42,310]}]},f:["Claim points"]}]}]}," ",{p:[14,1,413],t:7,e:"ui-display",f:[{p:[15,2,428],t:7,e:"span",f:["Points: ",{t:2,r:"data.id_points",p:[15,16,442]}]}," ",{p:[16,2,470],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[17,3,501],t:7,e:"span",f:[{t:2,r:"data.status_info",p:[17,9,507]}]}," ",{p:[18,3,538],t:7,e:"ui-button",a:{action:"move_shuttle",state:[{t:2,x:{r:["data.can_go_home"],s:'_0?null:"disabled"'},p:[18,42,577]}]},f:["Move shuttle"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],406:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Known Languages"},f:[{t:4,f:[{p:[3,5,68],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,23,86]}]},f:[{p:[4,7,102],t:7,e:"span",f:[{t:2,r:"desc",p:[4,13,108]}]}," ",{p:[5,7,130],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[5,19,142]}]}," ",{t:4,f:[{p:[7,9,186],t:7,e:"span",f:["(gained from mob)"]}],n:50,r:"shadow",p:[6,7,163]}," ",{p:[9,7,237],t:7,e:"span",f:[{t:2,x:{r:["can_speak"],s:'_0?"Can Speak":"Cannot Speak"'},p:[9,13,243]}]}," ",{t:4,f:[{p:[11,9,332],t:7,e:"ui-button",a:{action:"select_default",params:['{"language_name":"',{t:2,r:"name",p:[13,37,413]},'"}'],style:[{t:2,x:{r:["is_default","can_speak"],s:'_0?"selected":_1?null:"disabled"'},p:[14,18,442]}]},f:[{t:2,x:{r:["is_default"],s:'_0?"Default Language":"Select as Default"'},p:[15,10,512]}]}],n:50,r:"data.is_living",p:[10,7,301]}," ",{t:4,f:[{t:4,f:[{p:[20,11,666],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[20,72,727]},'"}']},f:["Grant"]}],n:50,r:"shadow",p:[19,9,641]},{t:4,n:51,f:[{p:[22,11,784],t:7,e:"ui-button",a:{action:"remove_language",params:['{"language_name":"',{t:2,r:"name",p:[22,73,846]},'"}']},f:["Remove"]}],r:"shadow"}],n:50,r:"data.admin_mode",p:[18,7,609]}]}],n:52,r:"data.languages",p:[2,3,39]}]}," ",{t:4,f:[{t:4,f:[{p:[30,5,1004],t:7,e:"ui-button",a:{action:"toggle_omnitongue",style:[{t:2,x:{r:["data.omnitongue"],s:'_0?"selected":null'},p:[32,14,1061]}]},f:["Omnitongue ",{t:2,x:{r:["data.omnitongue"],s:'_0?"Enabled":"Disabled"'},p:[33,19,1120]}]}],n:50,r:"data.is_living",p:[29,3,977]}," ",{p:[36,3,1196],t:7,e:"ui-display",a:{title:"Unknown Languages"},f:[{t:4,f:[{p:[38,7,1278],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[38,25,1296]}]},f:[{p:[39,9,1314],t:7,e:"span",f:[{t:2,r:"desc",p:[39,15,1320]}]}," ",{p:[40,9,1344],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[40,21,1356]}]}," ",{p:[41,9,1379],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[43,37,1460]},'"}']},f:["Grant"]}]}],n:52,r:"data.unknown_languages",p:[37,5,1239]}]}],n:50,r:"data.admin_mode",p:[28,1,951]}]},e.exports=a.extend(r.exports)},{341:341}],407:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{t:4,f:[{t:4,f:[{p:[4,4,81],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[5,5,114],t:7,e:"span",f:["Launchpad closed."]}]}],n:50,r:"data.pad_closed",p:[3,3,54]},{t:4,n:51,f:[{p:[8,4,176],t:7,e:"ui-section",a:{label:"Launchpad"},f:[{p:[9,4,210],t:7,e:"span",f:[{p:[9,10,216],t:7,e:"b",f:[{t:2,r:"data.pad_name",p:[9,13,219]}]}]},{p:[9,41,247],t:7,e:"br"}," ",{p:[10,4,255],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}," ",{p:[11,4,318],t:7,e:"ui-button",a:{icon:"remove",style:"danger",action:"remove"},f:["Remove"]}]}," ",{p:[14,4,414],t:7,e:"ui-section",a:{label:"Set Target"},f:[{p:[15,4,449],t:7,e:"table",f:[{p:[16,4,460],t:7,e:"tr",f:[{p:[17,5,469],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[17,38,502],t:7,e:"ui-button",a:{action:"up-left"},f:["↖"]}]}," ",{p:[18,5,553],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[18,57,605],t:7,e:"ui-button",a:{action:"up"
-},f:["↑"]}]}," ",{p:[19,5,651],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[19,56,702],t:7,e:"ui-button",a:{action:"up-right"},f:["↗"]}]}]}," ",{p:[21,4,762],t:7,e:"tr",f:[{p:[22,5,771],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[22,38,804],t:7,e:"ui-button",a:{action:"left",style:"width:35px!important"},f:["←"]}]}," ",{p:[23,5,881],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[23,57,933],t:7,e:"ui-button",a:{action:"reset"},f:["R"]}]}," ",{p:[24,5,982],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[24,56,1033],t:7,e:"ui-button",a:{action:"right"},f:["→"]}]}]}," ",{p:[26,4,1090],t:7,e:"tr",f:[{p:[27,5,1099],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[27,38,1132],t:7,e:"ui-button",a:{action:"down-left"},f:["↙"]}]}," ",{p:[28,5,1185],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[28,57,1237],t:7,e:"ui-button",a:{action:"down"},f:["↓"]}]}," ",{p:[29,5,1285],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[29,56,1336],t:7,e:"ui-button",a:{action:"down-right"},f:["↘"]}]}]}]}]}," ",{p:[33,4,1427],t:7,e:"ui-section",a:{label:"Current Target"},f:[{p:[34,5,1467],t:7,e:"span",f:[{t:2,r:"data.abs_y",p:[34,11,1473]}," ",{t:2,r:"data.north_south",p:[34,26,1488]}]},{p:[34,53,1515],t:7,e:"br"}," ",{p:[35,5,1524],t:7,e:"span",f:[{t:2,r:"data.abs_x",p:[35,11,1530]}," ",{t:2,r:"data.east_west",p:[35,26,1545]}]}]}," ",{p:[37,4,1591],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[38,5,1625],t:7,e:"ui-button",a:{action:"launch",tooltip:"Teleport everything on the pad to the target.","tooltip-side":"down"},f:["Launch"]}," ",{p:[39,5,1751],t:7,e:"ui-button",a:{action:"pull",tooltip:"Teleport everything from the target to the pad.","tooltip-side":"down"},f:["Pull"]}]}],r:"data.pad_closed"}],n:50,r:"data.has_pad",p:[2,2,31]},{t:4,n:51,f:[{p:[45,3,1912],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[46,4,1944],t:7,e:"span",f:["No launchpad found. Link the remote to a launchpad."]}]}],r:"data.has_pad"}]}]},e.exports=a.extend(r.exports)},{341:341}],408:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{mechChargeState:function(t){var e=this.get("data.recharge_port.mech.cell.maxcharge");return t>=e/1.5?"good":t>=e/3?"average":"bad"},mechHealthState:function(t){var e=this.get("data.recharge_port.mech.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[20,1,526],t:7,e:"ui-display",a:{title:"Mech Status"},f:[{t:4,f:[{t:4,f:[{p:[23,4,624],t:7,e:"ui-section",a:{label:"Integrity"},f:[{p:[24,6,660],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,27,681]}],value:[{t:2,r:"adata.recharge_port.mech.health",p:[24,74,728]}],state:[{t:2,x:{r:["mechHealthState","adata.recharge_port.mech.health"],s:"_0(_1)"},p:[24,117,771]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.health"],s:"Math.round(_0)"},p:[24,171,825]},"/",{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,219,873]}]}]}," ",{t:4,f:[{t:4,f:[{p:[28,5,1034],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[28,31,1060],t:7,e:"span",a:{"class":"bad"},f:["Cell Critical Failure"]}]}],n:50,r:"data.recharge_port.mech.cell.critfail",p:[27,3,984]},{t:4,n:51,f:[{p:[30,11,1141],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,13,1180],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.cell.maxcharge",p:[31,34,1201]}],value:[{t:2,r:"adata.recharge_port.mech.cell.charge",p:[31,86,1253]}],state:[{t:2,x:{r:["mechChargeState","adata.recharge_port.mech.cell.charge"],s:"_0(_1)"},p:[31,134,1301]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.cell.charge"],s:"Math.round(_0)"},p:[31,193,1360]},"/",{t:2,x:{r:["adata.recharge_port.mech.cell.maxcharge"],s:"Math.round(_0)"},p:[31,246,1413]}]}]}],r:"data.recharge_port.mech.cell.critfail"}],n:50,r:"data.recharge_port.mech.cell",p:[26,4,945]},{t:4,n:51,f:[{p:[35,3,1524],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[35,29,1550],t:7,e:"span",a:{"class":"bad"},f:["Cell Missing"]}]}],r:"data.recharge_port.mech.cell"}],n:50,r:"data.recharge_port.mech",p:[22,2,589]},{t:4,n:51,f:[{p:[38,4,1625],t:7,e:"ui-section",f:["Mech Not Found"]}],r:"data.recharge_port.mech"}],n:50,r:"data.recharge_port",p:[21,3,561]},{t:4,n:51,f:[{p:[41,5,1689],t:7,e:"ui-section",f:["Recharging Port Not Found"]}," ",{p:[42,2,1741],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}],r:"data.recharge_port"}]}]},e.exports=a.extend(r.exports)},{341:341}],409:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{t:4,f:[{p:[3,5,43],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[4,7,85],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[4,24,102]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[4,75,153]}]}]}],n:50,r:"data.siliconUser",p:[2,3,14]},{t:4,n:51,f:[{p:[7,5,241],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[7,31,267]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[10,1,349],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[11,3,379],t:7,e:"ui-section",a:{label:"Power"},f:[{t:4,f:[{p:[13,7,458],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[13,24,475]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[13,68,519]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[13,116,567]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[12,5,410]},{t:4,n:51,f:[{p:[15,7,625],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.on"],s:'_0?"good":"bad"'},p:[15,20,638]}],state:[{t:2,x:{r:["data.cell"],s:'_0?null:"disabled"'},p:[15,57,675]}]},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[15,92,710]}]}],x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"}}]}," ",{p:[18,3,774],t:7,e:"ui-section",a:{label:"Cell"},f:[{p:[19,5,804],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.cell"],s:'_0?null:"bad"'},p:[19,18,817]}]},f:[{t:2,x:{r:["data.cell","data.cellPercent"],s:'_0?_1+"%":"No Cell"'},p:[19,48,847]}]}]}," ",{p:[21,3,923],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[22,5,953],t:7,e:"span",a:{"class":[{t:2,r:"data.modeStatus",p:[22,18,966]}]},f:[{t:2,r:"data.mode",p:[22,39,987]}]}]}," ",{p:[24,3,1026],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[25,5,1056],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.load"],s:'_0?"good":"average"'},p:[25,18,1069]}]},f:[{t:2,x:{r:["data.load"],s:'_0?_0:"None"'},p:[25,54,1105]}]}]}," ",{p:[27,3,1165],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[28,5,1202],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.destination"],s:'_0?"good":"average"'},p:[28,18,1215]}]},f:[{t:2,x:{r:["data.destination"],s:'_0?_0:"None"'},p:[28,60,1257]}]}]}]}," ",{t:4,f:[{p:{button:[{t:4,f:[{p:[35,9,1479],t:7,e:"ui-button",a:{icon:"eject",action:"unload"},f:["Unload"]}],n:50,r:"data.load",p:[34,7,1453]}," ",{t:4,f:[{p:[38,9,1586],t:7,e:"ui-button",a:{icon:"eject",action:"ejectpai"},f:["Eject PAI"]}],n:50,r:"data.haspai",p:[37,7,1558]}," ",{p:[40,7,1670],t:7,e:"ui-button",a:{icon:"pencil",action:"setid"},f:["Set ID"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[42,5,1750],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[43,7,1789],t:7,e:"ui-button",a:{icon:"pencil",action:"destination"},f:["Set Destination"]}," ",{p:[44,7,1869],t:7,e:"ui-button",a:{icon:"stop",action:"stop"},f:["Stop"]}," ",{p:[45,7,1929],t:7,e:"ui-button",a:{icon:"play",action:"go"},f:["Go"]}]}," ",{p:[47,5,2001],t:7,e:"ui-section",a:{label:"Home"},f:[{p:[48,7,2033],t:7,e:"ui-button",a:{icon:"home",action:"home"},f:["Go Home"]}," ",{p:[49,7,2096],t:7,e:"ui-button",a:{icon:"pencil",action:"sethome"},f:["Set Home"]}]}," ",{p:[51,5,2181],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[52,7,2217],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoReturn"],s:'_0?"check-square-o":"square-o"'},p:[52,24,2234]}],style:[{t:2,x:{r:["data.autoReturn"],s:'_0?"selected":null'},p:[52,84,2294]}],action:"autoret"},f:["Auto-Return Home"]}," ",{p:[54,7,2396],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoPickup"],s:'_0?"check-square-o":"square-o"'},p:[54,24,2413]}],style:[{t:2,x:{r:["data.autoPickup"],s:'_0?"selected":null'},p:[54,84,2473]}],action:"autopick"},f:["Auto-Pickup Crate"]}," ",{p:[56,7,2577],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"check-square-o":"square-o"'},p:[56,24,2594]}],style:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"selected":null'},p:[56,88,2658]}],action:"report"},f:["Report Deliveries"]}]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[31,1,1343]}]},e.exports=a.extend(r.exports)},{341:341}],410:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Chamber Console"},f:[{p:[2,1,44],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{t:4,f:[{p:[4,2,101],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]},{p:[4,63,162],t:7,e:"br"}," ",{t:4,f:[{p:[6,3,195],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[6,36,228]}]}," ",{p:[7,3,262],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[7,35,294]}]}," ",{p:[8,3,328],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["data.disk.activated"],s:'_0?"Active":"Inactive"'},p:[8,41,366]}]}," ",{t:4,f:[{p:[10,4,468],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"data.disk.activation_delay",p:[10,41,505]}]}],n:50,r:"data.disk.activation_delay",p:[9,3,430]}," ",{t:4,f:[{p:[13,4,588],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"data.disk.timer",p:[13,30,614]}]}," ",{p:[14,4,650],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"data.disk.timer_type",p:[14,36,682]}]}],n:50,r:"data.disk.timer",p:[12,3,561]}," ",{t:4,f:[{p:[17,4,769],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"data.disk.activation_code",p:[17,40,805]}]}],n:50,r:"data.disk.activation_code",p:[16,3,732]}," ",{t:4,f:[{p:[20,4,899],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"data.disk.deactivation_code",p:[20,42,937]}]}],n:50,r:"data.disk.deactivation_code",p:[19,3,860]}," ",{t:4,f:[{p:[23,4,1025],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"data.disk.kill_code",p:[23,34,1055]}]}],n:50,r:"data.disk.kill_code",p:[22,3,994]}," ",{t:4,f:[{p:[26,4,1138],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"data.disk.trigger_code",p:[26,37,1171]}]}],n:50,r:"data.disk.trigger_code",p:[25,3,1104]}," ",{t:4,f:[{t:4,f:[{p:[30,6,1303],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[30,25,1322]}]},f:[{t:2,r:"value",p:[30,35,1332]}]}],n:52,r:"data.disk.extra_settings",p:[29,4,1263]}],n:50,r:"data.disk.has_extra_settings",p:[28,3,1223]}],n:50,r:"data.has_program",p:[5,2,168]},{t:4,n:51,f:[{p:[34,3,1390],t:7,e:"ui-notice",f:["No program detected."]}],r:"data.has_program"}],n:50,r:"data.has_disk",p:[3,1,78]},{t:4,n:51,f:[{p:[37,2,1453],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"}]}," ",{p:[40,1,1511],t:7,e:"br"}," ",{t:4,f:[{p:[42,2,1541],t:7,e:"ui-notice",f:[{t:2,r:"data.status_msg",p:[42,13,1552]}]}],n:50,r:"data.status_msg",p:[41,1,1516]},{t:4,n:51,f:[{p:[44,2,1594],t:7,e:"ui-display",a:{title:"Chamber"},f:[{p:[45,2,1624],t:7,e:"ui-section",f:[{p:[45,14,1636],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock-open":"lock"'},p:[45,30,1652]}],action:"toggle_lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[45,90,1712]}," Chamber"]},{p:[45,146,1768],t:7,e:"br"}]}," ",{p:[46,2,1787],t:7,e:"ui-section",f:[{p:[46,14,1799],t:7,e:"b",f:["Occupant:"]}," ",{t:2,r:"data.occupant_name",p:[46,31,1816]}]}," ",{t:4,f:[{p:[48,4,1882],t:7,e:"ui-section",f:[{p:[48,16,1894],t:7,e:"ui-notice",f:["No nanites detected."]}]}," ",{p:[49,4,1954],t:7,e:"ui-section",f:[{p:[49,16,1966],t:7,e:"ui-button",a:{icon:"syringe",action:"nanite_injection"},f:["Implant Nanites"]}]}],n:50,x:{r:["data.has_nanites"],s:"!_0"},p:[47,2,1853]},{t:4,n:51,f:[{p:[51,3,2071],t:7,e:"ui-display",a:{title:"Nanites"},f:[{t:4,f:[{p:[53,5,2129],t:7,e:"ui-button",a:{icon:"download",action:"add_program"},f:["Install Program From Disk"]},{p:[53,90,2214],t:7,e:"br"}," ",{p:[54,5,2223],t:7,e:"br"}],n:50,r:"data.has_disk",p:[52,4,2103]}," ",{p:[56,4,2242],t:7,e:"ui-section",f:[{p:[57,5,2259],t:7,e:"ui-section",a:{label:"Nanite Volume"},f:[{t:2,r:"data.nanite_volume",p:[57,39,2293]}]}," ",{p:[58,5,2333],t:7,e:"ui-section",a:{label:"Growth Rate"},f:[{t:2,r:"data.regen_rate",p:[58,37,2365]}]}," ",{p:[59,5,2402],t:7,e:"ui-section",a:{label:"Safety Threshold"},f:[{t:2,r:"data.safety_threshold",p:[59,42,2439]}," ",{p:[59,68,2465],t:7,e:"ui-button",a:{icon:"pencil",action:"set_safety"},f:["Set"]}]}," ",{p:[60,5,2544],t:7,e:"ui-section",a:{label:"Cloud ID"},f:[{t:2,x:{r:["data.cloud_id"],s:'_0?_0:"No Cloud"'},p:[60,34,2573]}," ",{p:[60,82,2621],t:7,e:"ui-button",a:{icon:"pencil",action:"set_cloud"},f:["Set"]}]}]}," ",{p:[62,4,2715],t:7,e:"ui-display",a:{title:"Programs"},f:[{t:4,f:[{p:[64,6,2782],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[64,25,2801]}],button:0},f:[{p:[65,6,2824],t:7,e:"ui-button",a:{icon:"minus",action:"remove_program",params:['{"program_id": "',{t:2,r:"id",p:[65,78,2896]},'"}']},f:["Uninstall"]}," ",{p:[66,6,2933],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"desc",p:[66,38,2965]}]}," ",{t:4,f:[{p:[68,7,3027],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["activated"],s:'_0?"Active":"Inactive"'},p:[68,45,3065]}]}," ",{p:[69,7,3123],t:7,e:"ui-section",a:{label:"Nanites Consumed"},f:[{t:2,r:"use_rate",p:[69,44,3160]},"/s"]}," ",{t:4,f:[{p:[71,8,3221],t:7,e:"ui-section",a:{label:"Trigger Cost"},f:[{t:2,r:"trigger_cost",p:[71,41,3254]}]}," ",{p:[72,8,3291],t:7,e:"ui-section",a:{label:"Trigger Cooldown"},f:[{t:2,r:"trigger_cooldown",p:[72,45,3328]}," seconds"]}],n:50,r:"can_trigger",p:[70,7,3194]}," ",{t:4,f:[{t:4,f:[{p:[76,9,3459],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"activation_delay",p:[76,46,3496]}]}],n:50,r:"activation_delay",p:[75,8,3426]}," ",{t:4,f:[{p:[79,9,3574],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"timer",p:[79,35,3600]}]}," ",{p:[80,9,3631],t:7,e:"ui-section",a:{label:"Timer Type"},f:[{t:2,r:"timer_type",p:[80,40,3662]}]}],n:50,r:"timer",p:[78,8,3552]}," ",{t:4,f:[{t:4,f:[{p:[84,11,3782],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,30,3801]}]},f:[{t:2,r:"value",p:[84,40,3811]}]}],n:52,r:"extra_settings",p:[83,9,3747]}],n:50,r:"has_extra_settings",p:[82,8,3712]}," ",{t:4,f:[{t:4,f:[{p:[89,10,3944],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"activation_code",p:[89,46,3980]}]}],n:50,r:"activation_code",p:[88,9,3911]}," ",{t:4,f:[{p:[92,10,4072],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"deactivation_code",p:[92,48,4110]}]}],n:50,r:"deactivation_code",p:[91,9,4037]}," ",{t:4,f:[{p:[95,10,4196],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"kill_code",p:[95,40,4226]}]}],n:50,r:"kill_code",p:[94,9,4169]}," ",{t:4,f:[{p:[98,10,4307],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"trigger_code",p:[98,43,4340]}]}],n:50,r:"trigger_code",p:[97,9,4277]}],n:50,x:{r:["data.scan_level"],s:"_0>=4"},p:[87,8,3874]}],n:50,x:{r:["data.scan_level"],s:"_0>=3"},p:[74,7,3390]}],n:50,x:{r:["data.scan_level"],s:"_0>=2"},p:[67,6,2992]}]}],n:52,r:"data.mob_programs",p:[63,5,2749]}]}]}],x:{r:["data.has_nanites"],s:"!_0"}}]}],r:"data.status_msg"}]}]},e.exports=a.extend(r.exports)},{341:341}],411:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Cloud Console"},f:[{p:[2,1,42],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{t:4,f:[{p:[4,3,101],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]},{p:[4,64,162],t:7,e:"br"}," ",{t:4,f:[{p:[6,4,197],t:7,e:"ui-section",f:[{p:[7,5,214],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[7,38,247]}]}," ",{p:[8,5,283],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[8,37,315]}]}," ",{p:[9,5,351],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["data.disk.activated"],s:'_0?"Active":"Inactive"'},p:[9,43,389]}]}," ",{t:4,f:[{p:[11,6,495],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"data.disk.activation_delay",p:[11,43,532]}]}],n:50,r:"data.disk.activation_delay",p:[10,5,455]}," ",{t:4,f:[{p:[14,6,621],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"data.disk.timer",p:[14,32,647]}]}," ",{p:[15,6,685],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"data.disk.timer_type",p:[15,38,717]}]}],n:50,r:"data.disk.timer",p:[13,5,592]}," ",{t:4,f:[{p:[18,6,810],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"data.disk.activation_code",p:[18,42,846]}]}],n:50,r:"data.disk.activation_code",p:[17,5,771]}," ",{t:4,f:[{p:[21,6,946],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"data.disk.deactivation_code",p:[21,44,984]}]}],n:50,r:"data.disk.deactivation_code",p:[20,5,905]}," ",{t:4,f:[{p:[24,6,1078],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"data.disk.kill_code",p:[24,36,1108]}]}],n:50,r:"data.disk.kill_code",p:[23,5,1045]}," ",{t:4,f:[{p:[27,6,1197],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"data.disk.trigger_code",p:[27,39,1230]}]}],n:50,r:"data.disk.trigger_code",p:[26,5,1161]}," ",{t:4,f:[{t:4,f:[{p:[31,8,1370],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[31,27,1389]}]},f:[{t:2,r:"value",p:[31,37,1399]}]}],n:52,r:"data.disk.extra_settings",p:[30,6,1328]}],n:50,r:"data.disk.has_extra_settings",p:[29,5,1286]}]}],n:50,r:"data.has_program",p:[5,3,169]},{t:4,n:51,f:[{p:[36,4,1480],t:7,e:"ui-notice",f:["No program detected."]}],r:"data.has_program"}],n:50,r:"data.has_disk",p:[3,2,77]},{t:4,n:51,f:[{p:[39,3,1546],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"}]}," ",{p:[42,1,1605],t:7,e:"ui-display",a:{title:"Cloud Storage"},f:[{t:4,f:[{p:[44,3,1670],t:7,e:"ui-button",a:{icon:"plus-circle",action:"create_backup"},f:["Create New Backup"]}," ",{p:[45,3,1755],t:7,e:"ui-display",a:{title:"Active Backups"},f:[{t:4,f:[{p:[47,5,1827],t:7,e:"ui-button",a:{action:"set_view",params:['{"view": "',{t:2,r:"cloud_id",p:[47,52,1874]},'"}']},f:["Backup #",{t:2,r:"cloud_id",p:[47,76,1898]}]}],n:52,r:"data.cloud_backups",p:[46,4,1794]}]}],n:50,x:{r:["data.current_view"],s:"!_0"},p:[43,2,1641]},{t:4,n:51,f:[{p:[51,3,1964],t:7,e:"ui-button",a:{icon:"undo",action:"set_view",params:'{"view": "0"}'},f:["Return"]}," ",{t:4,f:[{p:[53,4,2079],t:7,e:"ui-notice",f:["ERROR: Backup not found."]}],n:50,x:{r:["data.cloud_backup"],s:"!_0"},p:[52,3,2049]},{t:4,n:51,f:[{p:[55,4,2141],t:7,e:"ui-display",a:{title:["Backup #",{t:2,r:"data.current_view",p:[55,31,2168]}]},f:[{t:4,f:[{p:[57,6,2226],t:7,e:"ui-button",a:{icon:"upload",action:"upload_program",style:"selected"},f:["Upload Program From Disk"]},{p:[57,108,2328],t:7,e:"br"}],n:50,r:"data.has_program",p:[56,5,2196]}," ",{t:4,f:[{p:[60,6,2384],t:7,e:"hr"}," ",{p:[61,6,2394],t:7,e:"ui-section",f:[{p:[62,7,2413],t:7,e:"h3",f:[{t:2,r:"name",p:[62,11,2417]}]}," ",{p:[63,7,2437],t:7,e:"div",a:{style:"float:right"},f:[{p:[64,8,2470],t:7,e:"ui-button",a:{icon:"minus-circle",action:"remove_program",style:"danger",params:['{"program_id": "',{t:2,r:"id",p:[64,102,2564]},'"}']},f:["Uninstall"]}]}]}," ",{p:[67,6,2633],t:7,e:"ui-section",f:[{p:[68,7,2652],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"desc",p:[68,39,2684]}]}," ",{p:[69,7,2712],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["activated"],s:'_0?"Active":"Inactive"'},p:[69,45,2750]}]}," ",{p:[70,7,2808],t:7,e:"ui-section",a:{label:"Nanites Consumed"},f:[{t:2,r:"use_rate",p:[70,44,2845]},"/s"]}," ",{t:4,f:[{p:[72,8,2906],t:7,e:"ui-section",a:{label:"Trigger Cost"},f:[{t:2,r:"trigger_cost",p:[72,41,2939]},"/s"]}," ",{p:[73,8,2978],t:7,e:"ui-section",a:{label:"Trigger Cooldown"},f:[{t:2,r:"trigger_cooldown",p:[73,45,3015]},"/s"]}],n:50,r:"can_trigger",p:[71,7,2879]}," ",{t:4,f:[{p:[76,8,3103],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"activation_delay",p:[76,45,3140]}]}],n:50,r:"activation_delay",p:[75,7,3071]}," ",{t:4,f:[{p:[79,8,3215],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"timer",p:[79,34,3241]}]}," ",{p:[80,8,3271],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"timer_type",p:[80,40,3303]}]}],n:50,r:"timer",p:[78,7,3194]}," ",{t:4,f:[{p:[83,8,3382],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"activation_code",p:[83,44,3418]}]}],n:50,r:"activation_code",p:[82,7,3351]}," ",{t:4,f:[{p:[86,8,3504],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"deactivation_code",p:[86,46,3542]}]}],n:50,r:"deactivation_code",p:[85,7,3471]}," ",{t:4,f:[{p:[89,8,3622],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"kill_code",p:[89,38,3652]}]}],n:50,r:"kill_code",p:[88,7,3597]}," ",{t:4,f:[{p:[92,8,3727],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"trigger_code",p:[92,41,3760]}]}],n:50,r:"trigger_code",p:[91,7,3699]}," ",{t:4,f:[{t:4,f:[{p:[96,10,3878],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[96,29,3897]}]},f:[{t:2,r:"value",p:[96,39,3907]}]}],n:52,r:"extra_settings",p:[95,8,3844]}],n:50,r:"has_extra_settings",p:[94,7,3810]}]}],n:52,r:"data.cloud_programs",p:[59,5,2349]}]}],x:{r:["data.cloud_backup"],s:"!_0"}}],x:{r:["data.current_view"],s:"!_0"}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],412:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Program Hub"},f:[{t:4,f:[{p:[3,2,63],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{p:[4,3,99],t:7,e:"ui-section",f:[{p:[5,4,115],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]}," ",{p:[6,4,180],t:7,e:"ui-button",a:{icon:"minus-circle",action:"clear"},f:["Delete Program"]}]}," ",{t:4,f:[{p:[9,4,299],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[9,37,332]}]}," ",{p:[10,4,367],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[10,36,399]}]}],n:50,r:"data.has_program",p:[8,3,271]},{t:4,n:51,f:[{p:[12,4,445],t:7,e:"ui-notice",f:["No program installed."]}],r:"data.has_program"}]}],n:50,r:"data.has_disk",p:[2,1,40]},{t:4,n:51,f:[{p:[16,2,525],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"},{p:[18,1,569],t:7,e:"br"}," ",{p:[19,1,574],t:7,e:"ui-display",a:{title:"Programs"},f:[{p:[20,2,605],t:7,e:"ui-section",f:[{p:[21,3,620],t:7,e:"ui-button",a:{icon:"undo",action:"set_category",params:'{"category": "Main"}'},f:["Return"]}," ",{p:[22,3,716],t:7,e:"ui-button",a:{icon:"align-justify ",action:"toggle_details"},f:[{t:2,x:{r:["data.detail_view"],s:'_0?"Compact View":"Detailed View"'},p:[22,60,773]}]}]}," ",{t:4,f:[{p:[25,3,892],t:7,e:"ui-display",f:[{t:4,f:[{p:[27,5,938],t:7,e:"ui-section",f:[{p:[27,17,950],t:7,e:"ui-button",a:{action:"set_category",params:['{"category": "',{t:2,r:"name",p:[27,72,1005]},'"}']},f:[{t:2,r:"name",p:[27,84,1017]}]}]}],n:52,r:"data.categories",p:[26,4,908]}]}],n:50,x:{r:["data.category"],s:'_0=="Main"'},p:[24,2,858]},{t:4,n:51,f:[{p:[31,3,1092],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[31,22,1111]}]},f:[{t:4,f:[{t:4,f:[{p:[34,6,1196],t:7,e:"ui-display",f:[{p:[35,7,1215],t:7,e:"ui-section",f:[{p:[35,19,1227],t:7,e:"b",f:[{t:2,r:"name",p:[35,22,1230]}]}]}," ",{p:[36,7,1262],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[36,19,1274]}]}," ",{p:[37,7,1302],t:7,e:"ui-section",f:[{p:[38,8,1322],t:7,e:"ui-button",a:{icon:"download",action:"download",params:['{"program_id": "',{t:2,r:"id",p:[38,77,1391]},'"}'],state:[{t:2,x:{r:["data.has_disk"],s:'_0?null:"disabled"'},p:[38,94,1408]}]},f:["Download"]}]}]}],n:50,r:"data.detail_view",p:[33,5,1166]},{t:4,n:51,f:[{p:[44,6,1542],t:7,e:"ui-section",f:[{p:[44,18,1554],t:7,e:"ui-button",a:{action:"download",params:['{"program_id": "',{t:2,r:"id",p:[44,71,1607]},'"}']},f:[{t:2,r:"name",p:[44,81,1617]}]}]}],r:"data.detail_view"}],n:52,r:"data.program_list",p:[32,4,1134]}]}],x:{r:["data.category"],s:'_0=="Main"'}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],413:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Programming"},f:[{t:4,f:[{p:[3,3,65],t:7,e:"ui-notice",f:["Insert a nanite program disk."]}],n:50,x:{r:["data.has_disk"],s:"!_0"},p:[2,1,40]},{t:4,n:51,f:[{p:[5,3,129],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]}," ",{t:4,f:[{p:[7,5,223],t:7,e:"ui-notice",f:["No program detected."]}],n:50,x:{r:["data.has_program"],s:"!_0"},p:[6,3,193]},{t:4,n:51,f:[{p:[9,5,282],t:7,e:"ui-section",f:[{p:[10,7,301],t:7,e:"ui-display",a:{title:[{t:2,r:"data.name",p:[10,26,320]}]},f:[{t:2,r:"data.desc",p:[11,9,344]}]}]}," ",{p:[14,5,400],t:7,e:"ui-section",f:[{p:[15,7,419],t:7,e:"ui-section",a:{label:"Program Info"},f:["Nanites Consumed: ",{t:2,r:"data.use_rate",p:[16,26,478]},{p:[16,43,495],t:7,e:"br"}," ",{t:4,f:["Trigger Cost: ",{t:2,r:"data.trigger_cost",p:[18,25,557]},"u",{p:[18,47,579],t:7,e:"br"}],n:50,r:"data.can_trigger",p:[17,9,508]}]}," ",{p:[22,7,627],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[23,9,663],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.activated"],s:'_0?"toggle-on":"toggle-off"'},p:[24,17,690]}],action:"toggle_active"},f:[{t:2,x:{r:["data.activated"],s:'_0?"Active":"Inactive"'},p:[26,11,784]}]}]}," ",{p:[30,7,876],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[31,9,914],t:7,e:"ui-button",a:{icon:"pencil",action:"set_activation_delay"}}," Activation Delay: ",{t:2,r:"data.activation_delay",p:[31,95,1e3]}," ",{p:[31,121,1026],t:7,e:"br"}," ",{p:[32,9,1039],t:7,e:"ui-button",a:{icon:"pencil",action:"set_timer"}}," Timer: ",{t:2,r:"data.timer",p:[32,73,1103]}," ",{p:[32,88,1118],t:7,e:"br"}," ",{p:[33,9,1131],t:7,e:"ui-button",a:{icon:"pencil",action:"set_timer_type"}}," Timer Type: ",{t:2,r:"data.timer_type",p:[33,83,1205]}," ",{p:[33,103,1225],t:7,e:"br"}]}," ",{p:[36,7,1257],t:7,e:"ui-section",a:{label:"Codes"},f:[{p:[37,9,1292],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "activation"}'}}," Activation Code: ",{t:2,r:"data.activation_code",p:[37,121,1404]}," ",{p:[37,146,1429],t:7,e:"br"}," ",{p:[38,9,1442],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "deactivation"}'}}," Deactivation Code: ",{t:2,r:"data.deactivation_code",p:[38,125,1558]}," ",{p:[38,152,1585],t:7,e:"br"}," ",{p:[39,9,1598],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "kill"}'}}," Kill Code: ",{t:2,r:"data.kill_code",p:[39,109,1698]}," ",{p:[39,128,1717],t:7,e:"br"}," ",{t:4,f:[{p:[41,11,1765],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "trigger"}'}}," Trigger Code: ",{t:2,r:"data.trigger_code",p:[41,117,1871]}," ",{p:[41,139,1893],t:7,e:"br"}],n:50,r:"data.can_trigger",p:[40,9,1730]}]}," ",{t:4,f:[{p:[46,9,1981],t:7,e:"ui-section",a:{label:"Special"},f:[{t:4,f:[{p:[48,13,2062],t:7,e:"ui-button",a:{icon:"pencil",action:"set_extra_setting",params:['{"target_setting": "',{t:2,r:"name",p:[48,93,2142]},'"}']}}," ",{t:2,r:"name",p:[48,118,2167]},": ",{t:2,r:"value",p:[48,128,2177]}," ",{p:[48,138,2187],t:7,e:"br"}],n:52,r:"data.extra_settings",p:[47,11,2020]}]}],n:50,r:"data.has_extra_settings",p:[45,7,1941]}]}],x:{r:["data.has_program"],s:"!_0"}}],x:{r:["data.has_disk"],s:"!_0"}}]}]},e.exports=a.extend(r.exports)},{341:341}],414:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Control"},f:[{t:4,f:[{p:[3,3,58],t:7,e:"ui-notice",f:["The interface is locked."]}],n:50,r:"data.locked",p:[2,1,36]},{t:4,n:51,f:[{p:[5,3,117],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock Interface"]}," ",{p:[6,3,183],t:7,e:"ui-button",a:{icon:"save",action:"save"},f:["Save Current Setting"]}," ",{p:[7,3,255],t:7,e:"ui-section",a:{label:"Signal Code"},f:[{p:[8,5,292],t:7,e:"span",f:[{t:2,r:"data.code",p:[8,11,298]}]}," ",{p:[9,4,322],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code"},f:["Set"]}]}," ",{t:4,f:[{p:[12,5,432],t:7,e:"ui-section",a:{label:"Relay Code"},f:[{p:[13,7,470],t:7,e:"span",f:[{t:2,r:"data.relay_code",p:[13,13,476]}]}," ",{p:[14,5,507],t:7,e:"ui-button",a:{icon:"pencil",action:"set_relay_code"},f:["Set"]}]}],n:50,x:{r:["data.mode"],s:'_0=="Relay"'},p:[11,3,399]}," ",{p:[17,3,602],t:7,e:"ui-section",a:{label:"Signal Mode"},f:[{p:[18,5,639],t:7,e:"span",f:[{t:2,r:"data.mode",p:[18,11,645]}]}," ",{p:[19,5,670],t:7,e:"br"}," ",{p:[20,4,678],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Off"}'},f:["Off"]}," ",{p:[21,5,755],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Local"}'},f:["Local"]}," ",{p:[22,5,836],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Targeted"}'},f:["Targeted"]}," ",{p:[23,5,923],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Area"}'},f:["Area"]}," ",{p:[24,5,1002],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Relay"}'},f:["Relay"]}]}],r:"data.locked"}]}," ",{p:[28,1,1117],t:7,e:"ui-display",a:{title:"Saved Settings"},f:[{t:4,f:[{p:[30,3,1186],t:7,e:"ui-button",a:{icon:"load",action:"load",params:['{"save_id": "',{t:2,r:"id",p:[30,61,1244]},'"}']},f:[{t:2,r:"name",p:[30,71,1254]}]}," ",{t:4,f:[{p:[32,4,1301],t:7,e:"ui-button",a:{icon:"remove",action:"remove_save",params:['{"save_id": "',{t:2,r:"id",p:[32,71,1368]},'"}']},f:["Remove"]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[31,3,1277]}," ",{p:[34,3,1409],t:7,e:"br"}],n:52,r:"data.saved_settings",p:[29,2,1154]}]}]},e.exports=a.extend(r.exports)},{341:341}],415:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Ghost roles"},f:[{p:[2,2,34],t:7,e:"ui-section",a:{label:"Ignored roles"},f:[{t:4,f:[{p:[4,4,96],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[4,21,113]}],style:[{t:2,x:{r:["enabled"],s:'_0?"danger":null'},p:[4,73,165]}],action:"toggle_ignore",params:['{"key": "',{t:2,r:"key",p:[4,144,236]},'"}']},f:[{t:2,r:"desc",p:[4,155,247]}]}],n:52,r:"data.ignore",p:[3,3,71]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],416:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Relay"},f:[{t:4,f:[{p:[3,3,55],t:7,e:"h2",f:["NETWORK BUFFERS OVERLOADED"]}," ",{p:[4,3,93],t:7,e:"h3",f:["Overload Recovery Mode"]}," ",{p:[5,3,127],t:7,e:"i",f:["This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue."]}," ",{p:[6,3,479],t:7,e:"h3",f:["ADMINISTRATIVE OVERRIDE"]}," ",{p:[7,3,514],t:7,e:"b",f:["CAUTION - Data loss may occur"]}," ",{p:[8,3,555],t:7,e:"ui-button",a:{icon:"signal",action:"restart"},f:["Purge buffered traffic"]}],n:50,r:"data.dos_crashed",p:[2,2,28]},{t:4,n:51,f:[{p:[12,3,652],t:7,e:"ui-section",a:{label:"Relay status"},f:[{p:[13,4,689],t:7,e:"ui-button",a:{icon:"power-off",action:"toggle"},f:[{t:2,x:{r:["data.enabled"],s:'_0?"ENABLED":"DISABLED"'},p:[14,6,739]}]}]}," ",{p:[18,3,819],t:7,e:"ui-section",a:{label:"Network buffer status"},f:[{t:2,r:"data.dos_overload",p:[19,4,865]}," / ",{t:2,r:"data.dos_capacity",p:[19,28,889]}," GQ"]}],r:"data.dos_crashed"}]}]},e.exports=a.extend(r.exports)},{341:341}],417:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,306],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[18,3,346],t:7,e:"ui-notice",f:[{p:[19,5,362],t:7,e:"span",f:["Reconstruction in progress!"]}]}],n:50,r:"data.restoring",p:[17,1,321]},{p:[24,1,428],t:7,e:"ui-display",f:[{p:[26,1,442],t:7,e:"div",a:{"class":"item"},f:[{p:[27,3,463],t:7,e:"div",a:{"class":"itemLabel"},f:["Inserted AI:"]}," ",{p:[30,3,512],t:7,e:"div",a:{"class":"itemContent"
-},f:[{p:[31,2,539],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",state:[{t:2,x:{r:["data.nocard"],s:'_0?"disabled":null'},p:[31,52,589]}]},f:[{t:2,x:{r:["data.name"],s:'_0?_0:"---"'},p:[31,89,626]}]}]}]}," ",{t:4,f:[{p:[36,2,709],t:7,e:"b",f:["ERROR: ",{t:2,r:"data.error",p:[36,12,719]}]}],n:50,r:"data.error",p:[35,1,689]},{t:4,n:51,f:[{p:[38,2,748],t:7,e:"h2",f:["System Status"]}," ",{p:[39,2,772],t:7,e:"div",a:{"class":"item"},f:[{p:[40,3,793],t:7,e:"div",a:{"class":"itemLabel"},f:["Current AI:"]}," ",{p:[43,3,843],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.name",p:[44,4,872]}]}," ",{p:[46,3,897],t:7,e:"div",a:{"class":"itemLabel"},f:["Status:"]}," ",{p:[49,3,943],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["Nonfunctional"],n:50,r:"data.isDead",p:[50,4,972]},{t:4,n:51,f:["Functional"],r:"data.isDead"}]}," ",{p:[56,3,1059],t:7,e:"div",a:{"class":"itemLabel"},f:["System Integrity:"]}," ",{p:[59,3,1115],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[60,4,1144],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[60,37,1177]}],state:[{t:2,r:"healthState",p:[61,11,1204]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[61,28,1221]},"%"]}]}," ",{p:[63,3,1274],t:7,e:"div",a:{"class":"itemLabel"},f:["Active Laws:"]}," ",{p:[66,3,1325],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[67,4,1354],t:7,e:"table",f:[{t:4,f:[{p:[69,6,1394],t:7,e:"tr",f:[{p:[69,10,1398],t:7,e:"td",f:[{p:[69,14,1402],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[69,38,1426]}]}]}]}],n:52,r:"data.ai_laws",p:[68,5,1366]}]}]}," ",{p:[73,2,1475],t:7,e:"ui-section",a:{label:"Operations"},f:[{p:[74,3,1509],t:7,e:"ui-button",a:{icon:"plus",style:[{t:2,x:{r:["data.restoring"],s:'_0?"disabled":null'},p:[74,33,1539]}],action:"PRG_beginReconstruction"},f:["Begin Reconstruction"]}]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],418:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,1,87],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"home",params:'{"target" : "mod"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==1?"disabled":null'},p:[5,80,166]}]},f:["Access Modification"]}],n:50,r:"data.have_id_slot",p:[4,1,61]},{p:[7,1,247],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manage"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==2?"disabled":null'},p:[7,90,336]}]},f:["Job Management"]}," ",{p:[8,1,404],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manifest"}',state:[{t:2,x:{r:["data.mmode"],s:'!_0?"disabled":null'},p:[8,92,495]}]},f:["Crew Manifest"]}," ",{t:4,f:[{p:[10,1,584],t:7,e:"ui-button",a:{action:"PRG_print",icon:"print",state:[{t:2,x:{r:["data.has_id","data.mmode"],s:'!_1||_0&&_1==1?null:"disabled"'},p:[10,51,634]}]},f:["Print"]}],n:50,r:"data.have_printer",p:[9,1,558]},{t:4,f:[{p:[14,1,753],t:7,e:"div",a:{"class":"item"},f:[{p:[15,3,774],t:7,e:"h2",f:["Crew Manifest"]}," ",{p:[16,3,799],t:7,e:"br"},"Please use security record computer to modify entries.",{p:[16,61,857],t:7,e:"br"},{p:[16,65,861],t:7,e:"br"}]}," ",{t:4,f:[{p:[19,2,898],t:7,e:"div",a:{"class":"item"},f:[{t:2,r:"name",p:[20,2,918]}," - ",{t:2,r:"rank",p:[20,13,929]}]}],n:52,r:"data.manifest",p:[18,1,873]}],n:50,x:{r:["data.mmode"],s:"!_0"},p:[13,1,733]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.mmode"],s:"_0==2"},f:[{p:[25,1,984],t:7,e:"div",a:{"class":"item"},f:[{p:[26,3,1005],t:7,e:"h2",f:["Job Management"]}]}," ",{p:[28,1,1036],t:7,e:"table",f:[{p:[29,1,1044],t:7,e:"tr",f:[{p:[29,5,1048],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,27,1070],t:7,e:"b",f:["Job"]}]},{p:[29,42,1085],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,64,1107],t:7,e:"b",f:["Slots"]}]},{p:[29,81,1124],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,103,1146],t:7,e:"b",f:["Open job"]}]},{p:[29,123,1166],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,145,1188],t:7,e:"b",f:["Close job"]}]}]}," ",{t:4,f:[{p:[32,2,1238],t:7,e:"tr",f:[{p:[32,6,1242],t:7,e:"td",f:[{t:2,r:"title",p:[32,10,1246]}]},{p:[32,24,1260],t:7,e:"td",f:[{t:2,r:"current",p:[32,28,1264]},"/",{t:2,r:"total",p:[32,40,1276]}]},{p:[32,54,1290],t:7,e:"td",f:[{p:[32,58,1294],t:7,e:"ui-button",a:{action:"PRG_open_job",params:['{"target" : "',{t:2,r:"title",p:[32,112,1348]},'"}'],state:[{t:2,x:{r:["status_open"],s:'_0?null:"disabled"'},p:[32,132,1368]}]},f:[{t:2,r:"desc_open",p:[32,169,1405]}]},{p:[32,194,1430],t:7,e:"br"}]},{p:[32,203,1439],t:7,e:"td",f:[{p:[32,207,1443],t:7,e:"ui-button",a:{action:"PRG_close_job",params:['{"target" : "',{t:2,r:"title",p:[32,262,1498]},'"}'],state:[{t:2,x:{r:["status_close"],s:'_0?null:"disabled"'},p:[32,282,1518]}]},f:[{t:2,r:"desc_close",p:[32,320,1556]}]}]}]}],n:52,r:"data.slots",p:[30,1,1215]}]}]},{t:4,n:50,x:{r:["data.mmode"],s:"!(_0==2)"},f:[" ",{p:[40,1,1626],t:7,e:"div",a:{"class":"item"},f:[{p:[41,3,1647],t:7,e:"h2",f:["Access Modification"]}]}," ",{t:4,f:[{p:[45,3,1707],t:7,e:"span",a:{"class":"alert"},f:[{p:[45,23,1727],t:7,e:"i",f:["Please insert the ID into the terminal to proceed."]}]},{p:[45,87,1791],t:7,e:"br"}],n:50,x:{r:["data.has_id"],s:"!_0"},p:[44,1,1684]},{p:[48,1,1805],t:7,e:"div",a:{"class":"item"},f:[{p:[49,3,1826],t:7,e:"div",a:{"class":"itemLabel"},f:["Target Identity:"]}," ",{p:[52,3,1879],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[53,2,1906],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "id"}'},f:[{t:2,r:"data.id_name",p:[53,72,1976]}]}]}]}," ",{p:[56,1,2021],t:7,e:"div",a:{"class":"item"},f:[{p:[57,3,2042],t:7,e:"div",a:{"class":"itemLabel"},f:["Auth Identity:"]}," ",{p:[60,3,2093],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[61,2,2120],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "auth"}'},f:[{t:2,r:"data.auth_name",p:[61,74,2192]}]}]}]}," ",{p:[64,1,2239],t:7,e:"hr"}," ",{t:4,f:[{t:4,f:[{p:[68,2,2295],t:7,e:"div",a:{"class":"item"},f:[{p:[69,4,2317],t:7,e:"h2",f:["Details"]}]}," ",{t:4,f:[{p:[73,2,2364],t:7,e:"div",a:{"class":"item"},f:[{p:[74,4,2386],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[77,4,2442],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_owner",p:[78,3,2470]}]}]}," ",{p:[81,2,2507],t:7,e:"div",a:{"class":"item"},f:[{p:[82,4,2529],t:7,e:"div",a:{"class":"itemLabel"},f:["Rank:"]}," ",{p:[85,4,2574],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_rank",p:[86,3,2602]}]}]}," ",{p:[89,2,2638],t:7,e:"div",a:{"class":"item"},f:[{p:[90,4,2660],t:7,e:"div",a:{"class":"itemLabel"},f:["Demote:"]}," ",{p:[93,4,2707],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[94,3,2735],t:7,e:"ui-button",a:{action:"PRG_terminate",icon:"gear",state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Unassigned"?"disabled":null'},p:[94,56,2788]}]},f:["Demote ",{t:2,r:"data.id_owner",p:[94,117,2849]}]}]}]}],n:50,r:"data.minor",p:[72,2,2344]},{t:4,n:51,f:[{p:[99,2,2909],t:7,e:"div",a:{"class":"item"},f:[{p:[100,4,2931],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[103,4,2987],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[104,3,3015],t:7,e:"ui-button",a:{action:"PRG_edit",icon:"pencil",params:'{"name" : "1"}'},f:[{t:2,r:"data.id_owner",p:[104,70,3082]}]}]}]}," ",{p:[108,2,3132],t:7,e:"div",a:{"class":"item"},f:[{p:[109,4,3154],t:7,e:"h2",f:["Assignment"]}]}," ",{p:[111,3,3184],t:7,e:"ui-button",a:{action:"PRG_togglea",icon:"gear"},f:[{t:2,x:{r:["data.assignments"],s:'_0?"Hide assignments":"Show assignments"'},p:[111,47,3228]}]}," ",{p:[112,2,3304],t:7,e:"div",a:{"class":"item"},f:[{p:[113,4,3326],t:7,e:"span",a:{id:"allvalue.jobsslot"},f:[]}]}," ",{p:[117,2,3379],t:7,e:"div",a:{"class":"item"},f:[{t:4,f:[{p:[119,4,3429],t:7,e:"div",a:{id:"all-value.jobs"},f:[{p:[120,3,3457],t:7,e:"table",f:[{p:[121,5,3469],t:7,e:"tr",f:[{p:[122,4,3477],t:7,e:"th",f:["Command"]}," ",{p:[123,4,3497],t:7,e:"td",f:[{p:[124,6,3507],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Captain"}',state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Captain"?"selected":null'},p:[124,83,3584]}]},f:["Captain"]}]}]}," ",{p:[127,5,3678],t:7,e:"tr",f:[{p:[128,4,3686],t:7,e:"th",f:["Special"]}," ",{p:[129,4,3706],t:7,e:"td",f:[{p:[130,6,3716],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Custom"}'},f:["Custom"]}]}]}," ",{p:[133,5,3827],t:7,e:"tr",f:[{p:[134,4,3835],t:7,e:"th",a:{style:"color: '#FFA500';"},f:["Engineering"]}," ",{p:[135,4,3885],t:7,e:"td",f:[{t:4,f:[{p:[137,5,3931],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[137,64,3990]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[137,82,4008]}]},f:[{t:2,r:"display_name",p:[137,127,4053]}]}],n:52,r:"data.engineering_jobs",p:[136,6,3895]}]}]}," ",{p:[141,5,4120],t:7,e:"tr",f:[{p:[142,4,4128],t:7,e:"th",a:{style:"color: '#008000';"},f:["Medical"]}," ",{p:[143,4,4174],t:7,e:"td",f:[{t:4,f:[{p:[145,5,4216],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[145,64,4275]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[145,82,4293]}]},f:[{t:2,r:"display_name",p:[145,127,4338]}]}],n:52,r:"data.medical_jobs",p:[144,6,4184]}]}]}," ",{p:[149,5,4405],t:7,e:"tr",f:[{p:[150,4,4413],t:7,e:"th",a:{style:"color: '#800080';"},f:["Science"]}," ",{p:[151,4,4459],t:7,e:"td",f:[{t:4,f:[{p:[153,5,4501],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[153,64,4560]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[153,82,4578]}]},f:[{t:2,r:"display_name",p:[153,127,4623]}]}],n:52,r:"data.science_jobs",p:[152,6,4469]}]}]}," ",{p:[157,5,4690],t:7,e:"tr",f:[{p:[158,4,4698],t:7,e:"th",a:{style:"color: '#DD0000';"},f:["Security"]}," ",{p:[159,4,4745],t:7,e:"td",f:[{t:4,f:[{p:[161,5,4788],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[161,64,4847]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[161,82,4865]}]},f:[{t:2,r:"display_name",p:[161,127,4910]}]}],n:52,r:"data.security_jobs",p:[160,6,4755]}]}]}," ",{p:[165,5,4977],t:7,e:"tr",f:[{p:[166,4,4985],t:7,e:"th",a:{style:"color: '#cc6600';"},f:["Cargo"]}," ",{p:[167,4,5029],t:7,e:"td",f:[{t:4,f:[{p:[169,5,5069],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[169,64,5128]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[169,82,5146]}]},f:[{t:2,r:"display_name",p:[169,127,5191]}]}],n:52,r:"data.cargo_jobs",p:[168,6,5039]}]}]}," ",{p:[173,5,5258],t:7,e:"tr",f:[{p:[174,4,5266],t:7,e:"th",a:{style:"color: '#808080';"},f:["Civilian"]}," ",{p:[175,4,5313],t:7,e:"td",f:[{t:4,f:[{p:[177,5,5356],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[177,64,5415]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[177,82,5433]}]},f:[{t:2,r:"display_name",p:[177,127,5478]}]}],n:52,r:"data.civilian_jobs",p:[176,6,5323]}]}]}," ",{t:4,f:[{p:[182,4,5576],t:7,e:"tr",f:[{p:[183,6,5586],t:7,e:"th",a:{style:"color: '#A52A2A';"},f:["CentCom"]}," ",{p:[184,6,5634],t:7,e:"td",f:[{t:4,f:[{p:[186,7,5677],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[186,66,5736]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[186,84,5754]}]},f:[{t:2,r:"display_name",p:[186,129,5799]}]}],n:52,r:"data.centcom_jobs",p:[185,5,5643]}]}]}],n:50,r:"data.centcom_access",p:[181,5,5545]}]}]}],n:50,r:"data.assignments",p:[118,4,3401]}]}],r:"data.minor"}," ",{t:4,f:[{p:[198,4,5956],t:7,e:"div",a:{"class":"item"},f:[{p:[199,3,5977],t:7,e:"h2",f:["Central Command"]}]}," ",{p:[201,4,6015],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[203,5,6094],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[204,5,6128],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[204,64,6187]},'", "allowed" : "',{t:2,r:"allowed",p:[204,87,6210]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[204,109,6232]}]},f:[{t:2,r:"desc",p:[204,140,6263]}]}]}],n:52,r:"data.all_centcom_access",p:[202,3,6056]}]}],n:50,r:"data.centcom_access",p:[197,2,5925]},{t:4,n:51,f:[{p:[209,4,6330],t:7,e:"div",a:{"class":"item"},f:[{p:[210,3,6351],t:7,e:"h2",f:[{t:2,r:"data.station_name",p:[210,7,6355]}]}]}," ",{p:[212,4,6395],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[214,5,6463],t:7,e:"div",a:{style:"float: left; width: 175px; min-height: 250px"},f:[{p:[215,4,6525],t:7,e:"div",a:{"class":"average"},f:[{p:[215,25,6546],t:7,e:"ui-button",a:{action:"PRG_regsel",state:[{t:2,x:{r:["selected"],s:'_0?"toggle":null'},p:[215,63,6584]}],params:['{"region" : "',{t:2,r:"regid",p:[215,116,6637]},'"}']},f:[{p:[215,129,6650],t:7,e:"b",f:[{t:2,r:"name",p:[215,132,6653]}]}]}]}," ",{p:[216,4,6687],t:7,e:"br"}," ",{t:4,f:[{p:[218,6,6721],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[219,5,6755],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[219,64,6814]},'", "allowed" : "',{t:2,r:"allowed",p:[219,87,6837]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[219,109,6859]}]},f:[{t:2,r:"desc",p:[219,140,6890]}]}]}],n:52,r:"accesses",p:[217,6,6697]}]}],n:52,r:"data.regions",p:[213,3,6436]}]}],r:"data.centcom_access"}],n:50,r:"data.has_id",p:[67,3,2274]}],n:50,r:"data.authenticated",p:[66,1,2245]}]}],x:{r:["data.mmode"],s:"!_0"}}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],419:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargeState:function(t){var e=this.get("data.battery.max");return t>e/2?"good":t>e/4?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,297],t:7,e:"ntosheader"}," ",{p:[17,1,312],t:7,e:"ui-display",f:[{p:[18,2,326],t:7,e:"i",f:["Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device."]},{p:[18,137,461],t:7,e:"hr"}," ",{p:[19,2,467],t:7,e:"ui-display",a:{title:"Power Supply"},f:[{p:[20,3,503],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"data.power_usage",p:[21,4,539]},"W"]}," ",{t:4,f:[{p:[25,4,606],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Active"]}," ",{p:[28,4,674],t:7,e:"ui-section",a:{label:"Battery Rating"},f:[{t:2,r:"data.battery.max",p:[29,5,714]}]}," ",{p:[31,4,755],t:7,e:"ui-section",a:{label:"Battery Charge"},f:[{p:[32,5,795],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.battery.max",p:[32,26,816]}],value:[{t:2,r:"adata.battery.charge",p:[32,56,846]}],state:[{t:2,x:{r:["chargeState","adata.battery.charge"],s:"_0(_1)"},p:[32,89,879]}]},f:[{t:2,x:{r:["adata.battery.charge"],s:"Math.round(_0)"},p:[32,128,918]},"/",{t:2,r:"adata.battery.max",p:[32,165,955]}]}]}],n:50,r:"data.battery",p:[24,3,582]},{t:4,n:51,f:[{p:[35,4,1017],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Not Available"]}],r:"data.battery"}]}," ",{p:[41,2,1116],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,3,1151],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,4,1189],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,25,1210]}],value:[{t:2,r:"adata.disk_used",p:[43,53,1238]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,87,1272]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,123,1308]},"GQ"]}]}]}," ",{p:[47,2,1373],t:7,e:"ui-display",a:{title:"Computer Components"},f:[{t:4,f:[{p:[49,4,1443],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[49,26,1465]}]},f:[{p:[50,5,1480],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"desc",p:[50,59,1534]}]}," ",{p:[52,5,1554],t:7,e:"ui-section",a:{label:"State"},f:[{p:[53,6,1586],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["critical"],s:'_0?"disabled":null'},p:[53,24,1604]}],action:"PC_toggle_component",params:['{"name": "',{t:2,r:"name",p:[53,105,1685]},'"}']},f:[{t:2,x:{r:["enabled"],s:'_0?"Enabled":"Disabled"'},p:[54,7,1704]}]}]}," ",{t:4,f:[{p:[59,6,1810],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"powerusage",p:[60,7,1849]},"W"]}],n:50,r:"powerusage",p:[58,5,1786]}]}," ",{p:[64,4,1922],t:7,e:"br"}],n:52,r:"data.hardware",p:[48,3,1416]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],420:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{p:[4,1,61],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,3,97],t:7,e:"h2",f:["An error has occurred and this program can not continue."]}," Additional information: ",{t:2,r:"data.error",p:[8,27,189]},{p:[8,41,203],t:7,e:"br"}," ",{p:[9,3,210],t:7,e:"i",f:["Please try again. If the problem persists contact your system administrator for assistance."]}," ",{p:[10,3,311],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["Restart program"]}],n:50,r:"data.error",p:[6,2,76]},{t:4,n:51,f:[{t:4,f:[{p:[13,4,410],t:7,e:"h2",f:["Viewing file ",{t:2,r:"data.filename",p:[13,21,427]}]}," ",{p:[14,4,453],t:7,e:"div",a:{"class":"item"},f:[{p:[15,4,475],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["CLOSE"]}," ",{p:[16,4,530],t:7,e:"ui-button",a:{action:"PRG_edit"},f:["EDIT"]}," ",{p:[17,4,579],t:7,e:"ui-button",a:{action:"PRG_printfile"},f:["PRINT"]}," "]},{p:[18,10,640],t:7,e:"hr"}," ",{t:3,r:"data.filedata",p:[19,4,648]}],n:50,r:"data.filename",p:[12,3,385]},{t:4,n:51,f:[{p:[21,4,682],t:7,e:"h2",f:["Available files (local):"]}," ",{p:[22,4,719],t:7,e:"table",f:[{p:[23,5,731],t:7,e:"tr",f:[{p:[24,6,741],t:7,e:"th",f:["File name"]}," ",{p:[25,6,765],t:7,e:"th",f:["File type"]}," ",{p:[26,6,789],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[27,6,818],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[30,6,878],t:7,e:"tr",f:[{p:[31,7,889],t:7,e:"td",f:[{t:2,r:"name",p:[31,11,893]}]}," ",{p:[32,7,913],t:7,e:"td",f:[".",{t:2,r:"type",p:[32,12,918]}]}," ",{p:[33,7,938],t:7,e:"td",f:[{t:2,r:"size",p:[33,11,942]},"GQ"]}," ",{p:[34,7,964],t:7,e:"td",f:[{p:[35,8,976],t:7,e:"ui-button",a:{action:"PRG_openfile",params:['{"name": "',{t:2,r:"name",p:[35,59,1027]},'"}']},f:["VIEW"]}," ",{p:[36,8,1063],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[36,26,1081]}],action:"PRG_deletefile",params:['{"name": "',{t:2,r:"name",p:[36,105,1160]},'"}']},f:["DELETE"]}," ",{p:[37,8,1198],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[37,26,1216]}],action:"PRG_rename",params:['{"name": "',{t:2,r:"name",p:[37,101,1291]},'"}']},f:["RENAME"]}," ",{p:[38,8,1329],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[38,26,1347]}],action:"PRG_clone",params:['{"name": "',{t:2,r:"name",p:[38,100,1421]},'"}']},f:["CLONE"]}," ",{t:4,f:[{p:[40,9,1492],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[40,27,1510]}],action:"PRG_copytousb",params:['{"name": "',{t:2,r:"name",p:[40,105,1588]},'"}']},f:["EXPORT"]}],n:50,r:"data.usbconnected",p:[39,8,1458]}]}]}],n:52,r:"data.files",p:[29,5,852]}]}," ",{t:4,f:[{p:[47,4,1715],t:7,e:"h2",f:["Available files (portable device):"]}," ",{p:[48,4,1762],t:7,e:"table",f:[{p:[49,5,1774],t:7,e:"tr",f:[{p:[50,6,1784],t:7,e:"th",f:["File name"]}," ",{p:[51,6,1808],t:7,e:"th",f:["File type"]}," ",{p:[52,6,1832],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[53,6,1861],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[56,6,1924],t:7,e:"tr",f:[{p:[57,7,1935],t:7,e:"td",f:[{t:2,r:"name",p:[57,11,1939]}]}," ",{p:[58,7,1959],t:7,e:"td",f:[".",{t:2,r:"type",p:[58,12,1964]}]}," ",{p:[59,7,1984],t:7,e:"td",f:[{t:2,r:"size",p:[59,11,1988]},"GQ"]}," ",{p:[60,7,2010],t:7,e:"td",f:[{p:[61,8,2022],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[61,26,2040]}],action:"PRG_usbdeletefile",params:['{"name": "',{t:2,r:"name",p:[61,108,2122]},'"}']},f:["DELETE"]}," ",{t:4,f:[{p:[63,9,2194],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[63,27,2212]}],action:"PRG_copyfromusb",params:['{"name": "',{t:2,r:"name",p:[63,107,2292]},'"}']},f:["IMPORT"]}],n:50,r:"data.usbconnected",p:[62,8,2160]}]}]}],n:52,r:"data.usbfiles",p:[55,5,1895]}]}],n:50,r:"data.usbconnected",p:[46,4,1686]}," ",{p:[70,4,2401],t:7,e:"ui-button",a:{action:"PRG_newtextfile"},f:["NEW DATA FILE"]}],r:"data.filename"}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],421:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{p:[4,1,61],t:7,e:"ui-display",f:[{p:[5,2,75],t:7,e:"i",f:["No program loaded. Please select program from list below."]}," ",{p:[6,2,141],t:7,e:"table",f:[{t:4,f:[{p:[8,4,178],t:7,e:"tr",f:[{p:[8,8,182],t:7,e:"td",f:[{p:[8,12,186],t:7,e:"ui-button",a:{action:"PC_runprogram",params:['{"name": "',{t:2,r:"name",p:[8,64,238]},'"}']},f:[{t:2,r:"desc",p:[9,5,255]}]}]},{p:[11,4,283],t:7,e:"td",f:[{p:[11,8,287],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["running"],s:'_0?null:"disabled"'},p:[11,26,305]}],icon:"close",action:"PC_killprogram",params:['{"name": "',{t:2,r:"name",p:[11,114,393]},'"}']}}]}]}],n:52,r:"data.programs",p:[7,3,151]}]}," ",{p:[14,2,441],t:7,e:"br"},{p:[14,6,445],t:7,e:"br"}," ",{t:4,f:[{p:[16,3,476],t:7,e:"ui-button",a:{action:"PC_toggle_light",style:[{t:2,x:{r:["data.light_on"],s:'_0?"selected":null'},p:[16,46,519]}]},f:["Toggle Flashlight"]},{p:[16,114,587],t:7,e:"br"}," ",{p:[17,3,594],t:7,e:"ui-button",a:{action:"PC_light_color"},f:["Change Flashlight Color ",{p:[17,62,653],t:7,e:"span",a:{style:["border:1px solid #161616; background-color: ",{t:2,r:"data.comp_light_color",p:[17,119,710]},";"]},f:[" "]}]}],n:50,r:"data.has_light",p:[15,2,451]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],422:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{p:[4,1,61],t:7,e:"ui-display",f:[{t:4,f:[{p:[6,3,100],t:7,e:"h1",f:["ADMINISTRATIVE MODE"]}],n:50,r:"data.adminmode",p:[5,2,75]}," ",{t:4,f:[{p:[10,3,161],t:7,e:"div",a:{"class":"itemLabel"},f:["Current channel:"]}," ",{p:[13,3,217],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.title",p:[14,4,246]}]}," ",{p:[16,3,272],t:7,e:"div",a:{"class":"itemLabel"},f:["Operator access:"]}," ",{p:[19,3,328],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:[{p:[21,5,386],t:7,e:"b",f:["Enabled"]}],n:50,r:"data.is_operator",p:[20,4,357]},{t:4,n:51,f:[{p:[23,5,417],t:7,e:"b",f:["Disabled"]}],r:"data.is_operator"}]}," ",{p:[26,3,455],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[29,3,504],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[30,4,533],t:7,e:"table",f:[{p:[31,5,545],t:7,e:"tr",f:[{p:[31,9,549],t:7,e:"td",f:[{p:[31,13,553],t:7,e:"ui-button",a:{action:"PRG_speak"},f:["Send message"]}]}]},{p:[32,5,612],t:7,e:"tr",f:[{p:[32,9,616],t:7,e:"td",f:[{p:[32,13,620],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[33,5,687],t:7,e:"tr",f:[{p:[33,9,691],t:7,e:"td",f:[{p:[33,13,695],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]},{p:[34,5,774],t:7,e:"tr",f:[{p:[34,9,778],t:7,e:"td",f:[{p:[34,13,782],t:7,e:"ui-button",a:{action:"PRG_leavechannel"},f:["Leave channel"]}]}]},{p:[35,5,849],t:7,e:"tr",f:[{p:[35,9,853],t:7,e:"td",f:[{p:[35,13,857],t:7,e:"ui-button",a:{action:"PRG_savelog"},f:["Save log to local drive"]}," ",{t:4,f:[{p:[37,6,959],t:7,e:"tr",f:[{p:[37,10,963],t:7,e:"td",f:[{p:[37,14,967],t:7,e:"ui-button",a:{action:"PRG_renamechannel"},f:["Rename channel"]}]}]},{p:[38,6,1037],t:7,e:"tr",f:[{p:[38,10,1041],t:7,e:"td",f:[{p:[38,14,1045],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}]}]},{p:[39,6,1111],t:7,e:"tr",f:[{p:[39,10,1115],t:7,e:"td",f:[{p:[39,14,1119],t:7,e:"ui-button",a:{action:"PRG_deletechannel"},f:["Delete channel"]}]}]}],n:50,r:"data.is_operator",p:[36,5,929]}]}]}]}]}," ",{p:[43,3,1221],t:7,e:"b",f:["Chat Window"]}," ",{p:[44,4,1243],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[45,4,1298],t:7,e:"div",a:{"class":"item"},f:[{p:[46,5,1321],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"msg",p:[48,7,1403]},{p:[48,14,1410],t:7,e:"br"}],n:52,r:"data.messages",p:[47,6,1373]}]}]}]}," ",{p:[53,3,1464],t:7,e:"b",f:["Connected Users"]},{p:[53,25,1486],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"name",p:[55,4,1519]},{p:[55,12,1527],t:7,e:"br"}],n:52,r:"data.clients",p:[54,3,1493]}],n:50,r:"data.title",p:[9,2,140]},{t:4,n:51,f:[{p:[58,3,1556],t:7,e:"b",f:["Controls:"]}," ",{p:[59,3,1575],t:7,e:"table",f:[{p:[60,4,1586],t:7,e:"tr",f:[{p:[60,8,1590],t:7,e:"td",f:[{p:[60,12,1594],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[61,4,1660],t:7,e:"tr",f:[{p:[61,8,1664],t:7,e:"td",f:[{p:[61,12,1668],t:7,e:"ui-button",a:{action:"PRG_newchannel"},f:["New Channel"]}]}]},{p:[62,4,1730],t:7,e:"tr",f:[{p:[62,8,1734],t:7,e:"td",f:[{p:[62,12,1738],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]}]}," ",{p:[64,3,1826],t:7,e:"b",f:["Available channels:"]}," ",{p:[65,3,1855],t:7,e:"table",f:[{t:4,f:[{p:[67,4,1898],t:7,e:"tr",f:[{p:[67,8,1902],t:7,e:"td",f:[{p:[67,12,1906],t:7,e:"ui-button",a:{action:"PRG_joinchannel",params:['{"id": "',{t:2,r:"id",p:[67,64,1958]},'"}']},f:[{t:2,r:"chan",p:[67,74,1968]}]},{p:[67,94,1988],t:7,e:"br"}]}]}],n:52,r:"data.all_channels",p:[66,3,1865]}]}],r:"data.title"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],423:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{p:[4,1,61],t:7,e:"ui-display",f:[{t:4,f:["##SYSTEM ERROR: ",{t:2,r:"data.error",p:[6,19,112]},{p:[6,33,126],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["RESET"]}],n:50,r:"data.error",p:[5,2,75]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.target"],s:"_0"},f:["##DoS traffic generator active. Tx: ",{t:2,r:"data.speed",p:[8,39,236]},"GQ/s",{p:[8,57,254],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"nums",p:[10,4,291]},{p:[10,12,299],t:7,e:"br"}],n:52,r:"data.dos_strings",p:[9,3,261]}," ",{p:[12,3,318],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["ABORT"]}]},{t:4,n:50,x:{r:["data.target"],s:"!(_0)"},f:[" ##DoS traffic generator ready. Select target device.",{p:[14,55,430],t:7,e:"br"}," ",{t:4,f:["Targeted device ID: ",{t:2,r:"data.focus",p:[16,24,479]}],n:50,r:"data.focus",p:[15,3,437]},{t:4,n:51,f:["Targeted device ID: None"],r:"data.focus"}," ",{p:[20,3,545],t:7,e:"ui-button",a:{action:"PRG_execute"},f:["EXECUTE"]},{p:[20,54,596],t:7,e:"div",a:{style:"clear:both"}}," Detected devices on network:",{p:[21,31,657],t:7,e:"br"}," ",{t:4,f:[{p:[23,4,689],t:7,e:"ui-button",a:{action:"PRG_target_relay",params:['{"targid": "',{t:2,r:"id",p:[23,61,746]},'"}']},f:[{t:2,r:"id",p:[23,71,756]}]}],n:52,r:"data.relays",p:[22,3,664]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],424:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{p:[4,1,61],t:7,e:"ui-display",f:[{p:[5,2,75],t:7,e:"i",f:["Welcome to software download utility. Please select which software you wish to download."]},{p:[5,97,170],t:7,e:"hr"}," ",{t:4,f:[{p:[7,3,197],t:7,e:"ui-display",a:{title:"Download Error"},f:[{p:[8,4,236],t:7,e:"ui-section",a:{label:"Information"},f:[{t:2,r:"data.error",p:[9,5,273]}]}," ",{p:[11,4,308],t:7,e:"ui-section",a:{label:"Reset Program"},f:[{p:[12,5,347],t:7,e:"ui-button",a:{icon:"times",action:"PRG_reseterror"},f:["RESET"]}]}]}],n:50,r:"data.error",p:[6,2,176]},{t:4,n:51,f:[{t:4,f:[{p:[19,4,498],t:7,e:"ui-display",a:{title:"Download Running"},f:[{p:[20,5,540],t:7,e:"i",f:["Please wait..."]}," ",{p:[21,5,566],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"data.downloadname",p:[22,6,602]}]}," ",{p:[24,5,646],t:7,e:"ui-section",a:{label:"File description"},f:[{t:2,r:"data.downloaddesc",p:[25,6,689]}]}," ",{p:[27,5,733],t:7,e:"ui-section",a:{label:"File size"},f:[{t:2,r:"data.downloadsize",p:[28,6,769]},"GQ"]}," ",{p:[30,5,815],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{t:2,r:"data.downloadspeed",p:[31,6,855]}," GQ/s"]}," ",{p:[33,5,905],t:7,e:"ui-section",a:{label:"Download progress"},f:[{p:[34,6,949],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.downloadsize",p:[34,27,970]}],value:[{t:2,r:"adata.downloadcompletion",p:[34,58,1001]}],state:"good"},f:[{t:2,x:{r:["adata.downloadcompletion"],s:"Math.round(_0)"},p:[34,101,1044]},"GQ / ",{t:2,r:"adata.downloadsize",p:[34,146,1089]},"GQ"]}]}]}],n:50,r:"data.downloadname",p:[18,3,469]}],r:"data.error"}," ",{t:4,f:[{t:4,f:[{p:[41,4,1230],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,5,1267],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,6,1307],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,27,1328]}],value:[{t:2,r:"adata.disk_used",p:[43,55,1356]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,89,1390]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,125,1426]},"GQ"]}]}]}," ",{p:[47,4,1499],t:7,e:"ui-display",a:{title:"Primary Software Repository"},f:[{t:4,f:[{p:[49,6,1594],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[49,28,1616]}]},f:[{p:[50,7,1637],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[50,61,1691]}]}," ",{p:[52,7,1723],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[53,8,1761]}," (",{t:2,r:"size",p:[53,22,1775]}," GQ)"]}," ",{p:[55,7,1814],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[56,8,1856]}]}," ",{p:[58,7,1900],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[58,80,1973]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[62,6,2052],t:7,e:"br"}],n:52,r:"data.downloadable_programs",p:[48,5,1552]}]}," ",{t:4,f:[{p:[67,5,2128],t:7,e:"ui-display",a:{title:"UNKNOWN Software Repository"},f:[{p:[68,6,2182],t:7,e:"i",f:["Please note that Nanotrasen does not recommend download of software from non-official servers."]}," ",{t:4,f:[{p:[70,7,2326],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[70,29,2348]}]},f:[{p:[71,8,2370],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[71,62,2424]}]}," ",{p:[73,8,2458],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[74,9,2497]}," (",{t:2,r:"size",p:[74,23,2511]}," GQ)"]}," ",{p:[76,8,2552],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[77,9,2595]}]}," ",{p:[79,8,2641],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[79,81,2714]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[83,7,2797],t:7,e:"br"}],n:52,r:"data.hacked_programs",p:[69,6,2289]}]}],n:50,r:"data.hackedavailable",p:[66,4,2095]}],n:50,x:{r:["data.error"],s:"!_0"},p:[40,3,1207]}],n:50,x:{r:["data.downloadname"],s:"!_0"},p:[39,2,1178]}," ",{p:[89,2,2866],t:7,e:"br"},{p:[89,6,2870],t:7,e:"br"},{p:[89,10,2874],t:7,e:"hr"},{p:[89,14,2878],t:7,e:"i",f:["NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559"]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],
-425:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{p:[4,1,61],t:7,e:"ui-display",f:[{p:[6,2,76],t:7,e:"ui-display",a:{title:"WIRELESS CONNECTIVITY"},f:[{p:[8,3,122],t:7,e:"ui-section",a:{label:"Active NTNetRelays"},f:[{p:[9,4,165],t:7,e:"b",f:[{t:2,r:"data.ntnetrelays",p:[9,7,168]}]}]}," ",{t:4,f:[{p:[12,4,239],t:7,e:"ui-section",a:{label:"System status"},f:[{p:[13,6,279],t:7,e:"b",f:[{t:2,x:{r:["data.ntnetstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[13,9,282]}]}]}," ",{p:[15,4,352],t:7,e:"ui-section",a:{label:"Control"},f:[{p:[17,4,385],t:7,e:"ui-button",a:{icon:"plus",action:"toggleWireless"},f:["TOGGLE"]}]}," ",{p:[21,4,480],t:7,e:"br"},{p:[21,8,484],t:7,e:"br"}," ",{p:[22,4,492],t:7,e:"i",f:["Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again!"]}],n:50,r:"data.ntnetrelays",p:[11,3,211]},{t:4,n:51,f:[{p:[24,4,627],t:7,e:"br"},{p:[24,8,631],t:7,e:"p",f:["Wireless coverage unavailable, no relays are connected."]}],r:"data.ntnetrelays"}]}," ",{p:[29,2,722],t:7,e:"ui-display",a:{title:"FIREWALL CONFIGURATION"},f:[{p:[31,2,768],t:7,e:"table",f:[{p:[32,3,778],t:7,e:"tr",f:[{p:[33,4,786],t:7,e:"th",f:["PROTOCOL"]},{p:[34,4,802],t:7,e:"th",f:["STATUS"]},{p:[35,4,816],t:7,e:"th",f:["CONTROL"]}]},{p:[36,3,830],t:7,e:"tr",f:[" ",{p:[37,4,838],t:7,e:"td",f:["Software Downloads"]},{p:[38,4,864],t:7,e:"td",f:[{t:2,x:{r:["data.config_softwaredownload"],s:'_0?"ENABLED":"DISABLED"'},p:[38,8,868]}]},{p:[39,4,929],t:7,e:"td",f:[" ",{p:[39,9,934],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "1"}'},f:["TOGGLE"]}]}]},{p:[40,3,1012],t:7,e:"tr",f:[" ",{p:[41,4,1020],t:7,e:"td",f:["Peer to Peer Traffic"]},{p:[42,4,1048],t:7,e:"td",f:[{t:2,x:{r:["data.config_peertopeer"],s:'_0?"ENABLED":"DISABLED"'},p:[42,8,1052]}]},{p:[43,4,1107],t:7,e:"td",f:[{p:[43,8,1111],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "2"}'},f:["TOGGLE"]}]}]},{p:[44,3,1189],t:7,e:"tr",f:[" ",{p:[45,4,1197],t:7,e:"td",f:["Communication Systems"]},{p:[46,4,1226],t:7,e:"td",f:[{t:2,x:{r:["data.config_communication"],s:'_0?"ENABLED":"DISABLED"'},p:[46,8,1230]}]},{p:[47,4,1288],t:7,e:"td",f:[{p:[47,8,1292],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "3"}'},f:["TOGGLE"]}]}]},{p:[48,3,1370],t:7,e:"tr",f:[" ",{p:[49,4,1378],t:7,e:"td",f:["Remote System Control"]},{p:[50,4,1407],t:7,e:"td",f:[{t:2,x:{r:["data.config_systemcontrol"],s:'_0?"ENABLED":"DISABLED"'},p:[50,8,1411]}]},{p:[51,4,1469],t:7,e:"td",f:[{p:[51,8,1473],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "4"}'},f:["TOGGLE"]}]}]}]}]}," ",{p:[55,2,1576],t:7,e:"ui-display",a:{title:"SECURITY SYSTEMS"},f:[{t:4,f:[{p:[58,4,1642],t:7,e:"ui-notice",f:[{p:[59,5,1658],t:7,e:"h1",f:["NETWORK INCURSION DETECTED"]}]}," ",{p:[61,5,1714],t:7,e:"i",f:["An abnormal activity has been detected in the network. Please verify system logs for more information"]}],n:50,r:"data.idsalarm",p:[57,3,1617]}," ",{p:[64,3,1839],t:7,e:"ui-section",a:{label:"Intrusion Detection System"},f:[{p:[65,4,1890],t:7,e:"b",f:[{t:2,x:{r:["data.idsstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[65,7,1893]}]}]}," ",{p:[68,3,1962],t:7,e:"ui-section",a:{label:"Maximal Log Count"},f:[{p:[69,4,2004],t:7,e:"b",f:[{t:2,r:"data.ntnetmaxlogs",p:[69,7,2007]}]}]}," ",{p:[72,3,2054],t:7,e:"ui-section",a:{label:"Controls"},f:[]}," ",{p:[74,4,2103],t:7,e:"table",f:[{p:[75,4,2114],t:7,e:"tr",f:[{p:[75,8,2118],t:7,e:"td",f:[{p:[75,12,2122],t:7,e:"ui-button",a:{action:"resetIDS"},f:["RESET IDS"]}]}]},{p:[76,4,2176],t:7,e:"tr",f:[{p:[76,8,2180],t:7,e:"td",f:[{p:[76,12,2184],t:7,e:"ui-button",a:{action:"toggleIDS"},f:["TOGGLE IDS"]}]}]},{p:[77,4,2240],t:7,e:"tr",f:[{p:[77,8,2244],t:7,e:"td",f:[{p:[77,12,2248],t:7,e:"ui-button",a:{action:"updatemaxlogs"},f:["SET LOG LIMIT"]}]}]},{p:[78,4,2311],t:7,e:"tr",f:[{p:[78,8,2315],t:7,e:"td",f:[{p:[78,12,2319],t:7,e:"ui-button",a:{action:"purgelogs"},f:["PURGE LOGS"]}]}]}]}," ",{p:[81,3,2387],t:7,e:"ui-subdisplay",a:{title:"System Logs"},f:[{p:[82,3,2425],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[83,3,2479],t:7,e:"div",a:{"class":"item"},f:[{p:[84,4,2501],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"entry",p:[86,6,2582]},{p:[86,15,2591],t:7,e:"br"}],n:52,r:"data.ntnetlogs",p:[85,5,2552]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],426:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{p:[4,1,61],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,2,96],t:7,e:"div",a:{"class":"item"},f:[{p:[8,3,117],t:7,e:"h2",f:["An error has occurred during operation..."]}," ",{p:[9,3,170],t:7,e:"b",f:["Additional information:"]},{t:2,r:"data.error",p:[9,34,201]},{p:[9,48,215],t:7,e:"br"}," ",{p:[10,3,222],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Clear"]}]}],n:50,r:"data.error",p:[6,2,76]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.downloading"],s:"_0"},f:[{p:[13,3,309],t:7,e:"h2",f:["Download in progress..."]}," ",{p:[14,3,344],t:7,e:"div",a:{"class":"itemLabel"},f:["Downloaded file:"]}," ",{p:[17,3,400],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_name",p:[18,4,429]}]}," ",{p:[20,3,464],t:7,e:"div",a:{"class":"itemLabel"},f:["Download progress:"]}," ",{p:[23,3,522],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_progress",p:[24,4,551]}," / ",{t:2,r:"data.download_size",p:[24,33,580]}," GQ"]}," ",{p:[26,3,617],t:7,e:"div",a:{"class":"itemLabel"},f:["Transfer speed:"]}," ",{p:[29,3,672],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_netspeed",p:[30,4,701]},"GQ/s"]}," ",{p:[32,3,743],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[35,3,792],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[36,4,821],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Abort download"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading"],s:"(!(_0))&&(_1)"},f:[" ",{p:[39,3,916],t:7,e:"h2",f:["Server enabled"]}," ",{p:[40,3,942],t:7,e:"div",a:{"class":"itemLabel"},f:["Connected clients:"]}," ",{p:[43,3,1e3],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_clients",p:[44,4,1029]}]}," ",{p:[46,3,1064],t:7,e:"div",a:{"class":"itemLabel"},f:["Provided file:"]}," ",{p:[49,3,1118],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_filename",p:[50,4,1147]}]}," ",{p:[52,3,1183],t:7,e:"div",a:{"class":"itemLabel"},f:["Server password:"]}," ",{p:[55,3,1239],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ENABLED"],n:50,r:"data.upload_haspassword",p:[56,4,1268]},{t:4,n:51,f:["DISABLED"],r:"data.upload_haspassword"}]}," ",{p:[62,3,1359],t:7,e:"div",a:{"class":"itemLabel"},f:["Commands:"]}," ",{p:[65,3,1408],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[66,4,1437],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[67,4,1501],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Exit server"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(_2))"},f:[" ",{p:[70,3,1599],t:7,e:"h2",f:["File transfer server ready. Select file to upload:"]}," ",{p:[71,3,1662],t:7,e:"table",f:[{p:[72,3,1672],t:7,e:"tr",f:[{p:[72,7,1676],t:7,e:"th",f:["File name"]},{p:[72,20,1689],t:7,e:"th",f:["File size"]},{p:[72,33,1702],t:7,e:"th",f:["Controls ",{t:4,f:[{p:[74,4,1751],t:7,e:"tr",f:[{p:[74,8,1755],t:7,e:"td",f:[{t:2,r:"filename",p:[74,12,1759]}]},{p:[75,4,1775],t:7,e:"td",f:[{t:2,r:"size",p:[75,8,1779]},"GQ"]},{p:[76,4,1793],t:7,e:"td",f:[{p:[76,8,1797],t:7,e:"ui-button",a:{action:"PRG_uploadfile",params:['{"id": "',{t:2,r:"uid",p:[76,59,1848]},'"}']},f:["Select"]}]}]}],n:52,r:"data.upload_filelist",p:[73,3,1717]}]}]}]}," ",{p:[79,3,1903],t:7,e:"hr"}," ",{p:[80,3,1910],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[81,3,1973],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Return"]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(!(_2)))"},f:[" ",{p:[83,3,2034],t:7,e:"h2",f:["Available files:"]}," ",{p:[84,3,2062],t:7,e:"table",a:{border:"1",style:"border-collapse: collapse"},f:[{p:[84,55,2114],t:7,e:"tr",f:[{p:[84,59,2118],t:7,e:"th",f:["Server UID"]},{p:[84,73,2132],t:7,e:"th",f:["File Name"]},{p:[84,86,2145],t:7,e:"th",f:["File Size"]},{p:[84,99,2158],t:7,e:"th",f:["Password Protection"]},{p:[84,122,2181],t:7,e:"th",f:["Operations ",{t:4,f:[{p:[86,5,2226],t:7,e:"tr",f:[{p:[86,9,2230],t:7,e:"td",f:[{t:2,r:"uid",p:[86,13,2234]}]},{p:[87,5,2246],t:7,e:"td",f:[{t:2,r:"filename",p:[87,9,2250]}]},{p:[88,5,2267],t:7,e:"td",f:[{t:2,r:"size",p:[88,9,2271]},"GQ ",{t:4,f:[{p:[90,6,2311],t:7,e:"td",f:["Enabled"]}],n:50,r:"haspassword",p:[89,5,2286]}," ",{t:4,f:[{p:[93,6,2365],t:7,e:"td",f:["Disabled"]}],n:50,x:{r:["haspassword"],s:"!_0"},p:[92,5,2339]}]},{p:[96,5,2399],t:7,e:"td",f:[{p:[96,9,2403],t:7,e:"ui-button",a:{action:"PRG_downloadfile",params:['{"id": "',{t:2,r:"uid",p:[96,62,2456]},'"}']},f:["Download"]}]}]}],n:52,r:"data.servers",p:[85,4,2199]}]}]}]}," ",{p:[99,3,2514],t:7,e:"hr"}," ",{p:[100,3,2521],t:7,e:"ui-button",a:{action:"PRG_uploadmenu"},f:["Send file"]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],427:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[43,1,1040],t:7,e:"ntosheader"}," ",{p:[45,1,1055],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[47,5,1111],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[47,27,1133]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[49,38,1283]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[50,15,1338]}],yinc:"9"}}],n:50,r:"config.fancy",p:[46,3,1086]},{t:4,n:51,f:[{p:[52,5,1386],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[53,7,1423],t:7,e:"span",f:[{t:2,r:"data.supply",p:[53,13,1429]}]}]}," ",{p:[55,5,1474],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[56,9,1508],t:7,e:"span",f:[{t:2,r:"data.demand",p:[56,15,1514]}]}]}],r:"config.fancy"}]}," ",{p:[60,1,1579],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[61,3,1608],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[62,5,1632],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[63,5,1668],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[64,5,1706],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[65,5,1742],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[66,5,1780],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[67,5,1821],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[68,5,1861],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[71,5,1943],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[71,24,1962]}],nowrap:0},f:[{p:[72,7,1986],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[72,28,2007]}," %"]}," ",{p:[73,7,2064],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[73,28,2085]}]}," ",{p:[74,7,2126],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2147],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[74,41,2160]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[74,70,2189]}]}]}," ",{p:[75,7,2235],t:7,e:"div",a:{"class":"content"},f:[{p:[75,28,2256],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[75,41,2269]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[75,64,2292]}," [",{p:[75,87,2315],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[75,93,2321]}]},"]"]}]}," ",{p:[76,7,2369],t:7,e:"div",a:{"class":"content"},f:[{p:[76,28,2390],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[76,41,2403]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[76,64,2426]}," [",{p:[76,87,2449],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[76,93,2455]}]},"]"]}]}," ",{p:[77,7,2503],t:7,e:"div",a:{"class":"content"},f:[{p:[77,28,2524],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[77,41,2537]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[77,64,2560]}," [",{p:[77,87,2583],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[77,93,2589]}]},"]"]}]}]}],n:52,r:"data.areas",p:[70,3,1918]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],428:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{p:[4,1,61],t:7,e:"ui-display",f:[{p:[5,2,75],t:7,e:"div",a:{"class":"item"},f:[{p:[6,3,96],t:7,e:"div",a:{"class":"itemLabel"},f:["Payload status:"]}," ",{p:[9,3,150],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ARMED"],n:50,r:"data.armed",p:[10,4,179]},{t:4,n:51,f:["DISARMED"],r:"data.armed"}]}," ",{p:[16,3,255],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[19,3,303],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[20,4,332],t:7,e:"table",f:[{p:[21,4,343],t:7,e:"tr",f:[{p:[21,8,347],t:7,e:"td",f:[{p:[21,12,351],t:7,e:"ui-button",a:{action:"PRG_obfuscate"},f:["OBFUSCATE PROGRAM NAME"]}]}]},{p:[22,4,423],t:7,e:"tr",f:[{p:[22,8,427],t:7,e:"td",f:[{p:[22,12,431],t:7,e:"ui-button",a:{action:"PRG_arm",state:[{t:2,x:{r:["data.armed"],s:'_0?"danger":null'},p:[22,47,466]}]},f:[{t:2,x:{r:["data.armed"],s:'_0?"DISARM":"ARM"'},p:[22,81,500]}]}," ",{p:[23,4,549],t:7,e:"ui-button",a:{icon:"radiation",state:[{t:2,x:{r:["data.armed"],s:'_0?null:"disabled"'},p:[23,39,584]}],action:"PRG_activate"},f:["ACTIVATE"]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],429:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,46],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,3,91],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[5,22,110]}," Alarms"]},f:[{p:[6,5,133],t:7,e:"ul",f:[{t:4,f:[{p:[8,9,164],t:7,e:"li",f:[{t:2,r:".",p:[8,13,168]}]}],n:52,r:".",p:[7,7,144]},{t:4,n:51,f:[{p:[10,9,202],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[4,1,61]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],430:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{integState:function(t){var e=100;return t==e?"good":t>e/2?"average":"bad"},bigState:function(t,e,n){return charge>n?"bad":t>e?"average":"good"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[23,1,399],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[27,2,436],t:7,e:"ui-button",a:{action:"PRG_clear"},f:["Back to Menu"]},{p:[27,56,490],t:7,e:"br"}," ",{p:[28,3,497],t:7,e:"ui-display",a:{title:"Supermatter Status:"},f:[{p:[29,3,540],t:7,e:"ui-section",a:{label:"Core Integrity"},f:[{p:[30,5,580],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"adata.SM_integrity",p:[30,38,613]}],state:[{t:2,x:{r:["integState","adata.SM_integrity"],s:"_0(_1)"},p:[30,69,644]}]},f:[{t:2,r:"data.SM_integrity",p:[30,105,680]},"%"]}]}," ",{p:[32,3,730],t:7,e:"ui-section",a:{label:"Relative EER"},f:[{p:[33,5,768],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_power"],s:"_0(_1,150,300)"},p:[33,18,781]}]},f:[{t:2,r:"data.SM_power",p:[33,55,818]}," MeV/cm3"]}]}," ",{p:[35,3,869],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[36,5,906],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambienttemp"],s:"_0(_1,4000,5000)"},p:[36,18,919]}]},f:[{t:2,r:"data.SM_ambienttemp",p:[36,63,964]}," K"]}]}," ",{p:[38,3,1015],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[39,5,1049],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambientpressure"],s:"_0(_1,5000,10000)"},p:[39,18,1062]}]},f:[{t:2,r:"data.SM_ambientpressure",p:[39,68,1112]}," kPa"]}]}]}," ",{p:[42,3,1186],t:7,e:"hr"},{p:[42,7,1190],t:7,e:"br"}," ",{p:[43,3,1197],t:7,e:"ui-display",a:{title:"Gas Composition:"},f:[{t:4,f:[{p:[45,5,1263],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[45,24,1282]}]},f:[{t:2,r:"amount",p:[46,6,1298]}," %"]}],n:52,r:"data.gases",p:[44,4,1238]}]}],n:50,r:"data.active",p:[26,1,415]},{t:4,n:51,f:[{p:[51,2,1368],t:7,e:"ui-button",a:{action:"PRG_refresh"},f:["Refresh"]},{p:[51,53,1419],t:7,e:"br"}," ",{p:[52,2,1425],t:7,e:"ui-display",a:{title:"Detected Supermatters"},f:[{t:4,f:[{p:[54,3,1499],t:7,e:"ui-section",a:{label:"Area"},f:[{t:2,r:"area_name",p:[55,5,1529]}," - (#",{t:2,r:"uid",p:[55,23,1547]},")"]}," ",{p:[57,3,1574],t:7,e:"ui-section",a:{label:"Integrity"},f:[{t:2,r:"integrity",p:[58,5,1609]}," %"]}," ",{p:[60,3,1643],t:7,e:"ui-section",a:{label:"Options"},f:[{p:[61,5,1676],t:7,e:"ui-button",a:{action:"PRG_set",params:['{"target" : "',{t:2,r:"uid",p:[61,54,1725]},'"}']},f:["View Details"]}]}],n:52,r:"data.supermatters",p:[53,2,1469]}]}],r:"data.active"}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],431:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"item",style:"float: left"},f:[{p:[2,2,40],t:7,e:"table",f:[{p:[2,9,47],t:7,e:"tr",f:[{t:4,f:[{p:[4,3,110],t:7,e:"td",f:[{p:[4,7,114],t:7,e:"img",a:{src:[{t:2,r:"data.PC_batteryicon",p:[4,17,124]}]}}]}],n:50,x:{r:["data.PC_batteryicon","data.PC_showbatteryicon"],s:"_0&&_1"},p:[3,2,53]}," ",{t:4,f:[{p:[7,3,220],t:7,e:"td",f:[{p:[7,7,224],t:7,e:"b",f:[{t:2,r:"data.PC_batterypercent",p:[7,10,227]}]}]}],n:50,x:{r:["data.PC_batterypercent","data.PC_showbatteryicon"],s:"_0&&_1"},p:[6,2,160]}," ",{t:4,f:[{p:[10,3,296],t:7,e:"td",f:[{p:[10,7,300],t:7,e:"img",a:{src:[{t:2,r:"data.PC_ntneticon",p:[10,17,310]}]}}]}],n:50,r:"data.PC_ntneticon",p:[9,2,268]}," ",{t:4,f:[{p:[13,3,374],t:7,e:"td",f:[{p:[13,7,378],t:7,e:"img",a:{src:[{t:2,r:"data.PC_apclinkicon",p:[13,17,388]}]}}]}],n:50,r:"data.PC_apclinkicon",p:[12,2,344]}," ",{t:4,f:[{p:[16,3,454],t:7,e:"td",f:[{p:[16,7,458],t:7,e:"b",f:[{t:2,r:"data.PC_stationtime",p:[16,10,461]}]}]}],n:50,r:"data.PC_stationtime",p:[15,2,424]}," ",{t:4,f:[{p:[19,3,534],t:7,e:"td",f:[{p:[19,7,538],t:7,e:"img",a:{src:[{t:2,r:"icon",p:[19,17,548]}]}}]}],n:52,r:"data.PC_programheaders",p:[18,2,499]}]}]}]}," ",{p:[23,1,587],t:7,e:"div",a:{style:"float: right; margin-top: 5px"},f:[{p:[24,2,632],t:7,e:"ui-button",a:{action:"PC_shutdown"},f:["Shutdown"]}," ",{t:4,f:[{p:[26,3,720],t:7,e:"ui-button",a:{action:"PC_exit"},f:["EXIT PROGRAM"]}," ",{p:[27,3,775],t:7,e:"ui-button",a:{action:"PC_minimize"},f:["Minimize Program"]}],n:50,r:"data.PC_showexitprogram",p:[25,2,686]}]}," ",{p:[30,1,852],t:7,e:"div",a:{style:"clear: both"}}]},e.exports=a.extend(r.exports)},{341:341}],432:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Auth. Disk:"},f:[{t:4,f:[{p:[3,7,67],t:7,e:"ui-button",a:{icon:"eject",style:"selected",action:"eject_disk"},f:["++++++++++"]}],n:50,r:"data.disk_present",p:[2,3,35]},{t:4,n:51,f:[{p:[5,7,168],t:7,e:"ui-button",a:{icon:"plus",action:"insert_disk"},f:["----------"]}],r:"data.disk_present"}]}," ",{p:[8,1,259],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[9,3,289],t:7,e:"span",f:[{t:2,r:"data.status1",p:[9,9,295]},"-",{t:2,r:"data.status2",p:[9,26,312]}]}]}," ",{p:[11,1,350],t:7,e:"ui-display",a:{title:"Timer"},f:[{p:[12,3,379],t:7,e:"ui-section",a:{label:"Time to Detonation"},f:[{p:[13,5,423],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[13,11,429]}]}]}," ",{t:4,f:[{p:[16,5,525],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[17,7,565],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_default"],s:'_0&&_1&&_2?null:"disabled"'},p:[17,40,598]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[19,7,768],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_min"],s:'_0&&_1&&_2?null:"disabled"'},p:[19,38,799]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[21,7,971],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[21,39,1003]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[22,7,1134],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_max"],s:'_0&&_1&&_2?null:"disabled"'},p:[22,37,1164]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[15,3,504]}," ",{p:[26,3,1369],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[27,5,1400],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[27,38,1433]}],action:"toggle_timer",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.safety"],s:'_0&&_1&&!_2?null:"disabled"'},p:[29,14,1514]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[30,7,1602]}]}]}]}," ",{p:[34,1,1680],t:7,e:"ui-display",a:{title:"Anchoring"},f:[{p:[35,3,1713],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[36,12,1735]}],icon:[{t:2,x:{r:["data.anchored"],s:'_0?"lock":"unlock"'},p:[37,11,1810]}],style:[{t:2,x:{r:["data.anchored"],s:'_0?null:"caution"'},p:[38,12,1860]}],action:"anchor"},f:[{t:2,x:{r:["data.anchored"],s:'_0?"Engaged":"Off"'},p:[39,21,1918]}]}]}," ",{p:[41,1,1982],t:7,e:"ui-display",a:{title:"Safety"},f:[{p:[42,3,2012],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[43,12,2034]}],icon:[{t:2,x:{r:["data.safety"],s:'_0?"lock":"unlock"'},p:[44,11,2109]}],action:"safety",style:[{t:2,x:{r:["data.safety"],s:'_0?"caution":"danger"'},p:[45,12,2173]}]},f:[{p:[46,7,2220],t:7,e:"span",f:[{t:2,x:{r:["data.safety"],s:'_0?"On":"Off"'},p:[46,13,2226]}]}]}]}," ",{p:[49,1,2293],t:7,e:"ui-display",a:{title:"Code"},f:[{p:[50,3,2321],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.message",p:[50,31,2349]}]}," ",{p:[51,3,2381],t:7,e:"ui-section",a:{label:"Keypad"},f:[{p:[52,5,2413],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[52,39,2447]}],params:'{"digit":"1"}'},f:["1"]}," ",{p:[53,5,2531],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[53,39,2565]}],params:'{"digit":"2"}'},f:["2"]}," ",{p:[54,5,2649],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[54,39,2683]}],params:'{"digit":"3"}'},f:["3"]}," ",{p:[55,5,2767],t:7,e:"br"}," ",{p:[56,5,2776],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[56,39,2810]}],params:'{"digit":"4"}'},f:["4"]}," ",{p:[57,5,2894],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[57,39,2928]}],params:'{"digit":"5"}'},f:["5"]}," ",{p:[58,5,3012],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[58,39,3046]}],params:'{"digit":"6"}'},f:["6"]}," ",{p:[59,5,3130],t:7,e:"br"}," ",{p:[60,5,3139],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[60,39,3173]}],params:'{"digit":"7"}'},f:["7"]}," ",{p:[61,5,3257],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[61,39,3291]}],params:'{"digit":"8"}'},f:["8"]}," ",{p:[62,5,3375],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[62,39,3409]}],params:'{"digit":"9"}'},f:["9"]}," ",{p:[63,5,3493],t:7,e:"br"}," ",{p:[64,5,3502],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[64,39,3536]}],params:'{"digit":"R"}'},f:["R"]}," ",{p:[65,5,3620],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[65,39,3654]}],params:'{"digit":"0"}'},f:["0"]}," ",{p:[66,5,3738],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[66,39,3772]}],params:'{"digit":"E"}'},f:["E"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],433:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,24],t:7,e:"ui-button",a:{icon:"undo",action:"change_menu",params:'{"menu": "1"}'},f:["Return"]}," ",{p:[3,2,111],t:7,e:"ui-display",a:{title:"Advanced Surgery Procedures"},f:[{p:[4,3,162],t:7,e:"ui-button",a:{icon:"download",action:"sync"},f:["Sync with research database"]}," ",{t:4,f:[{p:[6,4,273],t:7,e:"ui-display",f:[{p:[7,6,291],t:7,e:"ui-section",f:[{p:[7,18,303],t:7,e:"b",f:[{t:2,r:"name",p:[7,21,306]}]}]}," ",{p:[8,6,337],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[8,18,349]}]}]}],n:52,r:"data.surgeries",p:[5,3,245]}]}],n:50,x:{r:["data.menu"],s:"_0==2"},p:[1,1,0]},{t:4,n:51,f:[{p:[13,2,425],t:7,e:"ui-button",a:{action:"change_menu",params:'{"menu": "2"}'},f:["View Surgery Procedures"]}," ",{t:4,f:[{p:[15,3,542],t:7,e:"ui-notice",f:["No table detected!"]}],n:51,r:"data.table",p:[14,2,517]}," ",{p:[19,2,605],t:7,e:"ui-display",f:[{p:[20,3,620],t:7,e:"ui-display",a:{title:"Patient State"},f:[{t:4,f:[{p:[22,5,683],t:7,e:"ui-section",a:{label:"State"},f:[{p:[23,6,715],t:7,e:"span",a:{"class":[{t:2,r:"data.patient.statstate",p:[23,19,728]}]},f:[{t:2,r:"data.patient.stat",p:[23,47,756]}]}]}," ",{p:[25,5,807],t:7,e:"ui-section",a:{label:"Blood Type"},f:[{p:[26,6,844],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.patient.blood_type",p:[26,28,866]}]}]}," ",{p:[28,5,923],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[29,6,956],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.patient.minHealth",p:[29,19,969]}],max:[{t:2,r:"data.patient.maxHealth",p:[29,52,1002]}],value:[{t:2,r:"data.patient.health",p:[29,87,1037]}],state:[{t:2,x:{r:["data.patient.health"],s:'_0>=0?"good":"average"'},p:[30,13,1074]}]},f:[{t:2,x:{r:["adata.patient.health"],s:"Math.round(_0)"},p:[30,64,1125]}]}]}," ",{t:4,f:[{p:[33,6,1357],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[33,25,1376]}]},f:[{p:[34,7,1394],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.patient.maxHealth",p:[34,28,1415]}],value:[{t:2,rx:{r:"data.patient",m:[{t:30,n:"type"}]},p:[34,63,1450]}],state:"bad"},f:[{t:2,x:{r:["type","adata.patient"],s:"Math.round(_1[_0])"},p:[34,99,1486]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"},{label:"Toxin",type:"toxLoss"},{label:"Respiratory",type:"oxyLoss"}]'},p:[32,5,1193]}],n:50,r:"data.patient",p:[21,4,658]},{t:4,n:51,f:["No patient detected."],r:"data.patient"}]}," ",{p:[41,3,1630],t:7,e:"ui-display",a:{title:"Initiated Procedures"},f:[{t:4,f:[{t:4,f:[{p:[44,6,1734],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[44,28,1756]}]},f:[{p:[45,7,1773],t:7,e:"ui-section",a:{label:"Next Step"},f:[{p:[46,8,1811],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"next_step",p:[46,30,1833]}]}," ",{t:4,f:[{p:[48,9,1890],t:7,e:"span",a:{"class":"content"},f:[{p:[48,31,1912],t:7,e:"b",f:["Required chemicals:"]},{p:[48,57,1938],t:7,e:"br"}," ",{t:2,r:"chems_needed",p:[48,62,1943]}]}],n:50,r:"chems_needed",p:[47,8,1861]}]}," ",{t:4,f:[{p:[52,8,2040],t:7,e:"ui-section",a:{label:"Alternative Step"},f:[{p:[53,9,2086],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"alternative_step",p:[53,31,2108]}]}," ",{t:4,f:[{p:[55,10,2178],t:7,e:"span",a:{"class":"content"},f:[{p:[55,32,2200],t:7,e:"b",f:["Required chemicals:"]},{p:[55,58,2226],t:7,e:"br"}," ",{t:2,r:"chems_needed",p:[55,63,2231]}]}],n:50,r:"alt_chems_needed",p:[54,9,2144]}]}],n:50,r:"alternative_step",p:[51,7,2008]}]}],n:52,r:"data.procedures",p:[43,5,1703]}],n:50,r:"data.procedures",p:[42,4,1675]},{t:4,n:51,f:["No active procedures."],r:"data.procedures"}]}]}],x:{r:["data.menu"],s:"_0==2"}}]},e.exports=a.extend(r.exports)},{341:341}],434:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",f:["This machine only accepts ore. Gibtonite and Slag are not accepted."]}," ",{p:[5,2,117],t:7,e:"ui-section",f:["Current unclaimed credits: ",{t:2,r:"data.unclaimedPoints",p:[6,30,160]}," ",{p:[7,4,189],t:7,e:"ui-button",a:{action:"Claim"},f:["Claim"]}]}]}," ",{p:[12,1,276],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,3,315],t:7,e:"ui-section",f:[{p:[15,4,332],t:7,e:"ui-button",a:{action:"diskEject",icon:"eject"},f:["Eject Disk"]}]}," ",{t:4,f:[{p:[20,4,460],t:7,e:"ui-section",a:{"class":"candystripe"},f:[{p:[21,5,496],t:7,e:"ui-button",a:{action:"diskUpload",state:[{t:2,x:{r:["canupload"],s:'(_0)?null:"disabled"'},p:[21,42,533]}],icon:"upload",align:"right",params:['{ "design" : "',{t:2,r:"index",p:[21,129,620]},'" }']},f:["Upload"]}," File ",{t:2,r:"index",p:[24,10,676]},": ",{t:2,r:"name",p:[24,21,687]}]}],n:52,r:"data.diskDesigns",p:[19,3,429]}],n:50,r:"data.hasDisk",p:[13,2,291]},{t:4,n:51,f:[{p:[28,3,741],t:7,e:"ui-section",f:[{p:[29,4,758],t:7,e:"ui-button",a:{action:"diskInsert",icon:"floppy-o"},f:["Insert Disk"]}]}],r:"data.hasDisk"}]}," ",{t:4,f:[{p:[36,2,911],t:7,e:"ui-display",f:[{p:[37,3,927],t:7,e:"ui-section",f:[{p:[38,4,944],t:7,e:"b",f:["Warning"]},": ",{t:2,r:"data.disconnected",p:[38,20,960]},". Please contact the quartermaster."]}]}],n:50,r:"data.disconnected",p:[35,1,883]},{t:4,f:[{p:[43,2,1100],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[44,3,1133],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[45,5,1168],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[48,5,1226],t:7,e:"section",a:{"class":"cell"},f:["Sheets"]}," ",{p:[51,5,1283],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[53,5,1327],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[55,5,1371],t:7,e:"section",a:{"class":"cell"},f:["Ore Value"]}]}," ",{t:4,f:[{p:[60,4,1473],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[61,5,1508],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[62,6,1537]}]}," ",{p:[64,5,1567],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[65,6,1610]}]}," ",{p:[67,5,1642],t:7,e:"section",a:{"class":"cell"},f:[{p:[68,6,1671],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[68,19,1684]}],placeholder:"###","class":"number"}}]}," ",{p:[70,5,1751],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[71,6,1794],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[71,60,1848]}],params:['{ "id" : ',{t:2,r:"id",p:[71,115,1903]},', "sheets" : ',{t:2,r:"sheets",p:[71,134,1922]}," }"]},f:["Release"]}]}," ",{p:[75,5,1993],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"value",p:[76,6,2036]}]}]}],n:52,r:"data.materials",p:[59,3,1444]}," ",{t:4,f:[{p:[81,4,2119],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[82,5,2154],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[83,6,2183]}]}," ",{p:[85,5,2213],t:7,e:"section",a:{"class":"cell",align:"right"
-},f:[{t:2,r:"amount",p:[86,6,2256]}]}," ",{p:[88,5,2288],t:7,e:"section",a:{"class":"cell"},f:[{p:[89,6,2317],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[89,19,2330]}],placeholder:"###","class":"number"}}]}," ",{p:[91,5,2397],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[92,6,2440],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Smelt",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[92,58,2492]}],params:['{ "id" : ',{t:2,r:"id",p:[92,114,2548]},', "sheets" : ',{t:2,r:"sheets",p:[92,133,2567]}," }"]},f:["Smelt"]}]}," ",{p:[96,5,2635],t:7,e:"section",a:{"class":"cell",align:"right"},f:[]}]}],n:52,r:"data.alloys",p:[80,3,2093]}]}],n:50,x:{r:["data.materials","data.alloys"],s:"_0||_1"},p:[42,1,1060]}]},e.exports=a.extend(r.exports)},{341:341}],435:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,4,84],t:7,e:"ui-button",a:{icon:"remove",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[4,36,116]}],action:"empty_eject_beaker"},f:["Empty and eject"]}," ",{p:[7,4,225],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[7,35,256]}],action:"empty_beaker"},f:["Empty"]}," ",{p:[10,4,349],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[10,35,380]}],action:"eject_beaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{t:4,f:[{p:[15,4,514],t:7,e:"ui-section",f:[{t:4,f:[{p:[17,6,562],t:7,e:"span",a:{"class":"bad"},f:["The beaker is empty!"]}],n:50,r:"data.beaker_empty",p:[16,5,531]},{t:4,n:51,f:[{p:[19,6,626],t:7,e:"ui-subdisplay",a:{title:"Blood"},f:[{t:4,f:[{p:[21,8,692],t:7,e:"ui-section",a:{label:"Blood DNA"},f:[{t:2,r:"data.blood.dna",p:[21,38,722]}]}," ",{p:[22,8,761],t:7,e:"ui-section",a:{label:"Blood type"},f:[{t:2,r:"data.blood.type",p:[22,39,792]}]}],n:50,r:"data.has_blood",p:[20,7,662]},{t:4,n:51,f:[{p:[24,8,847],t:7,e:"ui-section",f:[{p:[25,9,868],t:7,e:"span",a:{"class":"average"},f:["No blood sample detected."]}]}],r:"data.has_blood"}]}],r:"data.beaker_empty"}]}],n:50,r:"data.has_beaker",p:[14,3,487]},{t:4,n:51,f:[{p:[32,4,1023],t:7,e:"ui-section",f:[{p:[33,5,1040],t:7,e:"span",a:{"class":"bad"},f:["No beaker loaded."]}]}],r:"data.has_beaker"}]}," ",{t:4,f:[{p:[38,3,1151],t:7,e:"ui-display",a:{title:"Diseases"},f:[{t:4,f:[{p:{button:[{t:4,f:[{p:[43,8,1301],t:7,e:"ui-button",a:{icon:"pencil",action:"rename_disease",state:[{t:2,x:{r:["can_rename"],s:'_0?"":"disabled"'},p:[43,64,1357]}],params:['{"index": ',{t:2,r:"index",p:[43,116,1409]},"}"]},f:["Name advanced disease"]}],n:50,r:"is_adv",p:[42,7,1279]}," ",{p:[47,7,1492],t:7,e:"ui-button",a:{icon:"flask",action:"create_culture_bottle",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[47,69,1554]}],params:['{"index": ',{t:2,r:"index",p:[47,124,1609]},"}"]},f:["Create virus culture bottle"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[40,24,1230]}],button:0},f:[" ",{p:[51,6,1699],t:7,e:"ui-section",a:{label:"Disease agent"},f:[{t:2,r:"agent",p:[51,40,1733]}]}," ",{p:[52,6,1761],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[52,38,1793]}]}," ",{p:[53,6,1827],t:7,e:"ui-section",a:{label:"Spread"},f:[{t:2,r:"spread",p:[53,33,1854]}]}," ",{p:[54,6,1883],t:7,e:"ui-section",a:{label:"Possible cure"},f:[{t:2,r:"cure",p:[54,40,1917]}]}," ",{t:4,f:[{p:[56,7,1966],t:7,e:"ui-section",a:{label:"Symptoms"},f:[{t:4,f:[{p:[58,9,2030],t:7,e:"ui-button",a:{action:"symptom_details",state:"",params:['{"picked_symptom": ',{t:2,r:"sym_index",p:[58,81,2102]},', "index": ',{t:2,r:"index",p:[58,105,2126]},"}"]},f:[{t:2,r:"name",p:[59,10,2148]}," "]},{p:[60,21,2177],t:7,e:"br"}],n:52,r:"symptoms",p:[57,8,2003]}]}," ",{p:[63,7,2227],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[63,38,2258]}]}," ",{p:[64,7,2292],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[64,35,2320]}]}," ",{p:[65,7,2351],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[65,39,2383]}]}," ",{p:[66,7,2418],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[66,44,2455]}]}],n:50,r:"is_adv",p:[55,6,1945]}]}],n:52,r:"data.viruses",p:[39,4,1184]},{t:4,n:51,f:[{p:[70,5,2532],t:7,e:"ui-section",f:[{p:[71,6,2550],t:7,e:"span",a:{"class":"average"},f:["No detectable virus in the blood sample."]}]}],r:"data.viruses"}]}," ",{p:[75,3,2669],t:7,e:"ui-display",a:{title:"Antibodies"},f:[{t:4,f:[{p:[77,5,2735],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[77,24,2754]}]},f:[{p:[78,7,2771],t:7,e:"ui-button",a:{icon:"eyedropper",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[78,43,2807]}],action:"create_vaccine_bottle",params:['{"index": ',{t:2,r:"id",p:[78,129,2893]},"}"]},f:["Create vaccine bottle"]}]}],n:52,r:"data.resistances",p:[76,4,2704]},{t:4,n:51,f:[{p:[83,5,2985],t:7,e:"ui-section",f:[{p:[84,6,3003],t:7,e:"span",a:{"class":"average"},f:["No antibodies detected in the blood sample."]}]}],r:"data.resistances"}]}],n:50,r:"data.has_blood",p:[37,2,1126]}],n:50,x:{r:["data.mode"],s:"_0==1"},p:[1,1,0]},{t:4,n:51,f:[{p:[90,2,3142],t:7,e:"ui-button",a:{icon:"undo",state:"",action:"back"},f:["Back"]}," ",{t:4,f:[{p:[94,4,3237],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[94,23,3256]}]},f:[{p:[95,4,3270],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[96,5,3287]}," ",{t:4,f:[{p:[98,5,3320],t:7,e:"br"}," ",{p:[99,5,3330],t:7,e:"b",f:["This symptom has been neutered, and has no effect. It will still affect the virus' statistics."]}],n:50,r:"neutered",p:[97,4,3299]}]}," ",{p:[102,4,3463],t:7,e:"ui-section",f:[{p:[103,5,3480],t:7,e:"ui-section",a:{label:"Level"},f:[{t:2,r:"level",p:[103,31,3506]}]}," ",{p:[104,5,3533],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[104,36,3564]}]}," ",{p:[105,5,3596],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[105,33,3624]}]}," ",{p:[106,5,3653],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[106,37,3685]}]}," ",{p:[107,5,3718],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[107,42,3755]}]}]}," ",{p:[109,4,3805],t:7,e:"ui-subdisplay",a:{title:"Effect Thresholds"},f:[{p:[110,5,3851],t:7,e:"ui-section",f:[{t:3,r:"threshold_desc",p:[110,17,3863]}]}]}]}],n:53,r:"data.symptom",p:[93,2,3211]}],x:{r:["data.mode"],s:"_0==1"}}]},e.exports=a.extend(r.exports)},{341:341}],436:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(484);e.exports={data:{filter:"",tooltiptext:function(t,e,n){var a="";return t&&(a+="REQUIREMENTS: "+t+" "),e&&(a+="CATALYSTS: "+e+" "),n&&(a+="TOOLS: "+n),a}},oninit:function(){var t=this;this.on({hover:function(t){this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}}),this.observe("filter",function(e,a,r){var i=null;i=t.get("data.display_compact")?t.findAll(".section"):t.findAll(".display:not(:first-child)"),(0,n.filterMulti)(i,t.get("filter").toLowerCase())},{init:!1})}}}(r),r.exports.template={v:3,t:[" ",{p:[48,1,1295],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[48,20,1314]},{t:4,f:[" : ",{t:2,r:"data.subcategory",p:[48,64,1358]}],n:50,r:"data.subcategory",p:[48,37,1331]}]},f:[{t:4,f:[{p:[50,3,1410],t:7,e:"ui-section",f:["Crafting... ",{p:[51,16,1438],t:7,e:"i",a:{"class":"fa-spin fa fa-spinner"}}]}],n:50,r:"data.busy",p:[49,2,1390]},{t:4,n:51,f:[{p:[54,3,1504],t:7,e:"ui-section",f:[{p:[55,4,1520],t:7,e:"table",a:{style:"width:100%"},f:[{p:[56,5,1551],t:7,e:"tr",f:[{p:[57,6,1561],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[58,7,1602],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardCat"},f:[{t:2,r:"data.prev_cat",p:[59,8,1660]}]}]}," ",{p:[62,6,1713],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[63,7,1754],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardCat"},f:[{t:2,r:"data.next_cat",p:[64,7,1811]}]}]}," ",{p:[67,6,1864],t:7,e:"td",a:{style:"float:right!important"},f:[{t:4,f:[{p:[69,7,1946],t:7,e:"ui-button",a:{icon:"lock",action:"toggle_recipes"},f:["Showing Craftable Recipes"]}],n:50,r:"data.display_craftable_only",p:[68,6,1904]},{t:4,n:51,f:[{p:[73,7,2066],t:7,e:"ui-button",a:{icon:"unlock",action:"toggle_recipes"},f:["Showing All Recipes"]}],r:"data.display_craftable_only"}]}," ",{p:[78,6,2191],t:7,e:"td",a:{style:"float:right!important"},f:[{p:[79,7,2232],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.display_compact"],s:'_0?"check-square-o":"square-o"'},p:[79,24,2249]}],action:"toggle_compact"},f:["Compact"]}]}]}," ",{p:[84,5,2391],t:7,e:"tr",f:[{t:4,f:[{p:[86,6,2430],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[87,7,2471],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardSubCat"},f:[{t:2,r:"data.prev_subcat",p:[88,8,2532]}]}]}," ",{p:[91,6,2588],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[92,7,2629],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardSubCat"},f:[{t:2,r:"data.next_subcat",p:[93,8,2690]}]}]}],n:50,r:"data.subcategory",p:[85,5,2400]}]}]}," ",{t:4,f:[{t:4,f:[" ",{p:[101,6,2892],t:7,e:"ui-input",a:{value:[{t:2,r:"filter",p:[101,23,2909]}],placeholder:"Filter.."}}],n:51,r:"data.display_compact",p:[100,5,2803]}],n:50,r:"config.fancy",p:[99,4,2778]}]}," ",{t:4,f:[{p:[106,5,3039],t:7,e:"ui-display",f:[{t:4,f:[{p:[108,6,3086],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[108,25,3105]}]},f:[{p:[109,7,3122],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[109,27,3142]}],"tooltip-side":"right",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[109,135,3250]},'"}'],icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.can_craft",p:[107,5,3056]}," ",{t:4,f:[{t:4,f:[{p:[116,7,3452],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[116,26,3471]}]},f:[{p:[117,8,3489],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[117,28,3509]}],"tooltip-side":"right",state:"disabled",icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.cant_craft",p:[115,6,3420]}],n:51,r:"data.display_craftable_only",p:[114,5,3382]}]}],n:50,r:"data.display_compact",p:[105,4,3006]},{t:4,n:51,f:[{t:4,f:[{p:[126,6,3822],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[126,25,3841]}]},f:[{t:4,f:[{p:[128,8,3882],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[129,9,3924]}]}],n:50,r:"req_text",p:[127,7,3858]}," ",{t:4,f:[{p:[133,8,4007],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[134,9,4046]}]}],n:50,r:"catalyst_text",p:[132,7,3978]}," ",{t:4,f:[{p:[138,8,4130],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[139,9,4165]}]}],n:50,r:"tool_text",p:[137,7,4105]}," ",{p:[142,7,4220],t:7,e:"ui-section",f:[{p:[143,8,4240],t:7,e:"ui-button",a:{icon:"gears",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[143,66,4298]},'"}']},f:["Craft"]}]}]}],n:52,r:"data.can_craft",p:[125,5,3792]}," ",{t:4,f:[{t:4,f:[{p:[151,7,4471],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[151,26,4490]}]},f:[{t:4,f:[{p:[153,9,4533],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[154,10,4576]}]}],n:50,r:"req_text",p:[152,8,4508]}," ",{t:4,f:[{p:[158,9,4663],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[159,10,4703]}]}],n:50,r:"catalyst_text",p:[157,8,4633]}," ",{t:4,f:[{p:[163,9,4791],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[164,10,4827]}]}],n:50,r:"tool_text",p:[162,8,4765]}]}],n:52,r:"data.cant_craft",p:[150,6,4439]}],n:51,r:"data.display_craftable_only",p:[149,5,4401]}],r:"data.display_compact"}],r:"data.busy"}]}]},e.exports=a.extend(r.exports)},{341:341,484:484}],437:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,14],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,34]}," connected to a tank."]}]}," ",{p:[4,1,110],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,147],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,181],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,187]}," kPa"]}]}," ",{p:[8,3,247],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,277],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,290]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,331]}]}]}]}," ",{p:[12,1,419],t:7,e:"ui-display",a:{title:"Pump"},f:[{p:[13,3,447],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,478],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,495]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,545]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,601]}]}]}," ",{p:[18,3,658],t:7,e:"ui-section",a:{label:"Direction"},f:[{p:[19,5,693],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"sign-out":"sign-in"'},p:[19,22,710]}],action:"direction"},f:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"Out":"In"'},p:[20,26,789]}]}]}," ",{p:[22,3,862],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,5,903],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.min_pressure",p:[23,18,916]}],max:[{t:2,r:"data.max_pressure",p:[23,46,944]}],value:[{t:2,r:"data.target_pressure",p:[24,14,980]}]},f:[{t:2,x:{r:["adata.target_pressure"],s:"Math.round(_0)"},p:[24,40,1006]}," kPa"]}]}," ",{p:[26,3,1075],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,1119],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.target_pressure","data.default_pressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,1152]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1300],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.target_pressure","data.min_pressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1331]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1470],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1564],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.target_pressure","data.max_pressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1594]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}," ",{p:{button:[{t:4,f:[{p:[39,7,1853],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[39,38,1884]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[38,5,1826]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[43,3,2e3],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[44,4,2030]}]}," ",{p:[46,3,2070],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[47,4,2103]}," kPa"]}],n:50,r:"data.holding",p:[42,3,1977]},{t:4,n:51,f:[{p:[50,3,2174],t:7,e:"ui-section",f:[{p:[51,4,2190],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{341:341}],438:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[3,1,69],t:7,e:"ui-notice",f:[{p:[4,3,84],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[4,23,104]}," connected to a tank."]}]}," ",{p:[6,1,182],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[7,3,220],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[8,5,255],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[8,11,261]}," kPa"]}]}," ",{p:[10,3,323],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[11,5,354],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[11,18,367]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[11,59,408]}]}]}]}," ",{p:[14,1,499],t:7,e:"ui-display",a:{title:"Filter"},f:[{p:[15,3,530],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[16,5,562],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[16,22,579]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[17,14,630]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[18,22,687]}]}]}]}," ",{p:{button:[{t:4,f:[{p:[24,7,856],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[24,38,887]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[23,5,828]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[28,3,1007],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[29,4,1038]}]}," ",{p:[31,3,1080],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[32,4,1114]}," kPa"]}],n:50,r:"data.holding",p:[27,3,983]},{t:4,n:51,f:[{p:[35,3,1188],t:7,e:"ui-section",f:[{p:[36,4,1205],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}," ",{p:[40,1,1293],t:7,e:"ui-display",a:{title:"Filters"},f:[{t:4,f:[{p:[42,5,1345],t:7,e:"filters"}],n:53,r:"data",p:[41,3,1325]}]}]},r.exports.components=r.exports.components||{};var i={filters:t(457)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,457:457}],439:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" ",{p:[42,1,1035],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[44,5,1093],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[44,27,1115]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[46,38,1267]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[47,15,1323]}],yinc:"9"}}],n:50,r:"config.fancy",p:[43,3,1067]},{t:4,n:51,f:[{p:[49,5,1373],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[50,7,1411],t:7,e:"span",f:[{t:2,r:"data.supply",p:[50,13,1417]}]}]}," ",{p:[52,5,1464],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[53,9,1499],t:7,e:"span",f:[{t:2,r:"data.demand",p:[53,15,1505]}]}]}],r:"config.fancy"}]}," ",{p:[57,1,1574],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[58,3,1604],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[59,5,1629],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[60,5,1666],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[61,5,1705],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[62,5,1742],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[63,5,1781],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[64,5,1823],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[65,5,1864],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[68,5,1949],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[68,24,1968]}],nowrap:0},f:[{p:[69,7,1993],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[69,28,2014]}," %"]}," ",{p:[70,7,2072],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[70,28,2093]}]}," ",{p:[71,7,2135],t:7,e:"div",a:{"class":"content"},f:[{p:[71,28,2156],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[71,41,2169]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[71,70,2198]}]}]}," ",{p:[72,7,2245],t:7,e:"div",a:{"class":"content"},f:[{p:[72,28,2266],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[72,41,2279]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[72,64,2302]}," [",{p:[72,87,2325],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[72,93,2331]}]},"]"]}]}," ",{p:[73,7,2380],t:7,e:"div",a:{"class":"content"},f:[{p:[73,28,2401],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[73,41,2414]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[73,64,2437]}," [",{p:[73,87,2460],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[73,93,2466]}]},"]"]}]}," ",{p:[74,7,2515],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2536],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[74,41,2549]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[74,64,2572]}," [",{p:[74,87,2595],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[74,93,2601]}]},"]"]}]}]}],n:52,r:"data.areas",p:[67,3,1923]}]}]},e.exports=a.extend(r.exports)},{341:341}],440:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{readableFrequency:function(){return Math.round(this.get("adata.frequency"))/10}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,167],t:7,e:"ui-display",a:{title:"Settings"},f:[{t:4,f:[{p:[13,5,224],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,7,257],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[14,24,274]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[14,75,325]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"On":"Off"'},p:[16,9,398]}]}]}],n:50,r:"data.headset",p:[12,3,199]},{t:4,n:51,f:[{p:[19,5,476],t:7,e:"ui-section",a:{label:"Microphone"},f:[{p:[20,7,514],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.broadcasting"],s:'_0?"power-off":"close"'},p:[20,24,531]}],style:[{t:2,x:{r:["data.broadcasting"],s:'_0?"selected":null'},p:[20,78,585]}],action:"broadcast"},f:[{t:2,x:{r:["data.broadcasting"],s:'_0?"Engaged":"Disengaged"'},p:[22,9,664]}]}]}," ",{p:[24,5,746],t:7,e:"ui-section",a:{label:"Speaker"},f:[{p:[25,7,781],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[25,24,798]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[25,75,849]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"Engaged":"Disengaged"'},p:[27,9,922]}]}]}],r:"data.headset"}," ",{t:4,f:[{p:[31,5,1034],t:7,e:"ui-section",a:{label:"High Volume"},f:[{p:[32,7,1073],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.useCommand"],s:'_0?"power-off":"close"'},p:[32,24,1090]}],style:[{t:2,x:{r:["data.useCommand"],s:'_0?"selected":null'},p:[32,76,1142]}],action:"command"},f:[{t:2,x:{r:["data.useCommand"],s:'_0?"On":"Off"'},p:[34,9,1217]}]}]}],n:50,r:"data.command",p:[30,3,1009]}]}," ",{p:[38,1,1305],t:7,e:"ui-display",a:{title:"Channel"},f:[{p:[39,3,1336],t:7,e:"ui-section",a:{label:"Frequency"},f:[{t:4,f:[{p:[41,7,1399],t:7,e:"span",f:[{t:2,r:"readableFrequency",p:[41,13,1405]}]}],n:50,r:"data.freqlock",p:[40,5,1371]},{t:4,n:51,f:[{p:[43,7,1453],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[43,46,1492]}],action:"frequency",params:'{"adjust": -1}'}}," ",{p:[44,7,1603],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[44,41,1637]}],action:"frequency",params:'{"adjust": -.2}'}}," ",{p:[45,7,1749],t:7,e:"ui-button",a:{icon:"pencil",action:"frequency",params:'{"tune": "input"}'},f:[{t:2,r:"readableFrequency",p:[45,78,1820]}]}," ",{p:[46,7,1860],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[46,40,1893]}],action:"frequency",params:'{"adjust": .2}'}}," ",{p:[47,7,2004],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[47,45,2042]}],action:"frequency",params:'{"adjust": 1}'}}],r:"data.freqlock"}]}," ",{t:4,f:[{p:[51,5,2212],t:7,e:"ui-section",a:{label:"Subspace Transmission"},f:[{p:[52,7,2261],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.subspace"],s:'_0?"power-off":"close"'},p:[52,24,2278]}],style:[{t:2,x:{r:["data.subspace"],s:'_0?"selected":null'},p:[52,74,2328]}],action:"subspace"},f:[{t:2,x:{r:["data.subspace"],s:'_0?"Active":"Inactive"'},p:[53,29,2395]}]}]}],n:50,r:"data.subspaceSwitchable",p:[50,3,2176]}," ",{t:4,f:[{p:[57,5,2522],t:7,e:"ui-section",a:{label:"Channels"},f:[{t:4,f:[{p:[59,9,2598],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["."],s:'_0?"check-square-o":"square-o"'},p:[59,26,2615]}],style:[{t:2,x:{r:["."],s:'_0?"selected":null'},p:[60,18,2671]}],action:"channel",params:['{"channel": "',{t:2,r:"channel",p:[61,49,2746]},'"}']},f:[{t:2,r:"channel",p:[62,11,2772]}]},{p:[62,34,2795],t:7,e:"br"}],n:52,i:"channel",r:"data.channels",p:[58,7,2558]}]}],n:50,x:{r:["data.subspace","data.channels"],s:"_0&&_1"},p:[56,3,2479]}]}]},e.exports=a.extend(r.exports)},{341:341}],441:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," "," "," "," "," "," ",{p:[11,1,550],t:7,e:"rdheader"}," ",{t:4,f:[{p:[13,2,583],t:7,e:"ui-display",a:{title:"CONSOLE LOCKED"},f:[{p:[14,3,621],t:7,e:"ui-button",a:{action:"Unlock"},f:["Unlock"]}]}],n:50,r:"data.locked",p:[12,1,562]},{t:4,f:[{p:[18,2,712],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[18,17,727]}]},f:[{p:[19,3,745],t:7,e:"tab",a:{name:"Technology"},f:[{p:[20,4,772],t:7,e:"techweb"}]}," ",{p:[22,3,794],t:7,e:"tab",a:{name:"View Node"},f:[{p:[23,4,820],t:7,e:"nodeview"}]}," ",{p:[25,3,843],t:7,e:"tab",a:{name:"View Design"},f:[{p:[26,4,871],t:7,e:"designview"}]}," ",{p:[28,3,896],t:7,e:"tab",a:{name:"Disk Operations - Design"},f:[{p:[29,4,937],t:7,e:"diskopsdesign"}]}," ",{p:[31,3,965],t:7,e:"tab",a:{name:"Disk Operations - Technology"},f:[{p:[32,4,1010],t:7,e:"diskopstech"}]}," ",{p:[34,3,1036],t:7,e:"tab",a:{name:"Deconstructive Analyzer"},f:[{p:[35,4,1076],t:7,e:"destruct"}]}," ",{p:[37,3,1099],t:7,e:"tab",a:{name:"Protolathe"},f:[{p:[38,4,1126],t:7,e:"protolathe"}]}," ",{p:[40,3,1151],t:7,e:"tab",a:{name:"Circuit Imprinter"},f:[{p:[41,4,1185],t:7,e:"circuit"}]}," ",{p:[43,3,1207],t:7,e:"tab",a:{name:"Settings"},f:[{p:[44,4,1232],t:7,e:"settings"}]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[17,1,690]}]},r.exports.components=r.exports.components||{};var i={settings:t(450),circuit:t(442),protolathe:t(448),destruct:t(444),diskopsdesign:t(445),diskopstech:t(446),designview:t(443),nodeview:t(447),techweb:t(451),rdheader:t(449)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,442:442,443:443,444:444,445:445,446:446,447:447,448:448,449:449,450:450,451:451}],442:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[3,3,56],t:7,e:"ui-display",a:{title:"Circuit Imprinter Busy!"}}],n:50,r:"data.circuitbusy",p:[2,2,29]},{t:4,n:51,f:[{p:[5,3,126],t:7,e:"ui-display",f:[{p:[6,4,142],t:7,e:"ui-section",f:["Search Available Designs: ",{p:[7,4,183],t:7,e:"input",a:{value:[{t:2,r:"textsearch",p:[7,17,196]}],placeholder:"Type Here","class":"text"}}," ",{p:[8,5,254],t:7,e:"ui-button",a:{action:"textSearch",params:['{"latheType" : "circuit", "inputText" : ',{t:2,r:"textsearch",p:[8,84,333]},"}"]},f:["Search"]}]}," ",{p:[10,4,389],t:7,e:"ui-section",f:["Materials: ",{t:2,r:"data.circuitmats",p:[10,27,412]}," / ",{t:2,r:"data.circuitmaxmats",p:[10,50,435]}]}," ",{p:[11,4,475],t:7,e:"ui-section",f:["Reagents: ",{t:2,r:"data.circuitchems",p:[11,26,497]}," / ",{t:2,r:"data.circuitmaxchems",p:[11,50,521]}]}," ",{p:[12,3,561],t:7,e:"ui-display",f:[{p:[14,3,577],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.lathe_tabs",p:[14,18,592]}]},f:[{p:[15,4,617],t:7,e:"tab",a:{name:"Category List"},f:[{t:4,f:[{p:[17,6,680],t:7,e:"ui-button",a:{action:"switchcat",state:[{t:2,x:{r:["data.circuitcat"],s:'_0=="{{name}}"?"selected":null'},p:[17,43,717]}],params:['{"type" : "circuit", "cat" : "',{t:2,r:"name",p:[17,135,809]},'"}']},f:[{t:2,r:"name",p:[17,147,821]}]}],n:52,r:"data.circuitcats",p:[16,5,648]}]}," ",{p:[20,4,869],t:7,e:"tab",a:{name:"Selected Category"},f:[{t:4,f:[{p:[22,6,935],t:7,e:"ui-section",f:[{t:2,r:"name",p:[22,18,947]},{t:2,r:"matstring",p:[22,26,955]}," ",{p:[23,7,975],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[23,40,1008]}],params:['{"latheType" : "circuit", "id" : "',{t:2,r:"id",p:[23,119,1087]},'"}']},f:["Print"]}]}],n:52,r:"data.circuitdes",p:[21,5,904]}]}," ",{p:[27,4,1161],t:7,e:"tab",a:{name:"Search Results"},f:[{t:4,f:[{p:[29,6,1226],t:7,e:"ui-section",f:[{t:2,r:"name",p:[29,18,1238]},{t:2,r:"matstring",p:[29,26,1246]}," ",{p:[30,7,1266],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[30,40,1299]}],params:['{"latheType" : "circuit", "id" : "',{t:2,r:"id",p:[30,119,1378]},'"}']},f:["Print"]}]}],n:52,r:"data.circuitmatch",p:[28,5,1193]}]}," ",{p:[34,4,1452],t:7,e:"tab",a:{name:"Materials"},f:[{t:4,f:[{p:[36,6,1515],t:7,e:"ui-section",f:[{t:2,r:"name",p:[36,18,1527]}," : ",{t:2,r:"amount",p:[36,29,1538]}," cm3 - ",{t:4,f:[{p:[38,7,1586],t:7,e:"input",a:{value:[{t:2,r:"number",p:[38,20,1599]}],placeholder:["1-",{t:2,r:"sheets",p:[38,46,1625]}],"class":"number"}}," ",{p:[39,7,1660],t:7,e:"ui-button",a:{action:"releasemats",params:['{"latheType" : "circuit", "mat_id" : ',{t:2,r:"mat_id",p:[39,84,1737]},', "sheets" : ',{t:2,r:"number",p:[39,107,1760]},"}"]},f:["Release"]}],n:50,x:{r:["sheets"],s:"_0>0"},p:[37,6,1561]}]}],n:52,r:"data.circuitmat_list",p:[35,5,1479]}]}," ",{p:[44,4,1852],t:7,e:"tab",a:{name:"Chemicals"},f:[{t:4,f:[{p:[46,6,1916],t:7,e:"ui-section",f:[{t:2,r:"name",p:[46,18,1928]}," : ",{t:2,r:"amount",p:[46,29,1939]}," - ",{p:[47,7,1959],t:7,e:"ui-button",a:{action:"purgechem",params:['{"latheType" : "circuit", "name" : ',{t:2,r:"name",p:[47,80,2032]},', "id" : ',{t:2,r:"reagentid",p:[47,97,2049]},"}"]},f:["Purge"]}]}],n:52,r:"data.circuitchem_list",p:[45,5,1879]}]}]}]}]}],r:"data.circuitbusy"}],n:50,r:"data.circuit_linked",p:[1,1,0]},{t:4,n:51,f:[{p:[55,2,2162],t:7,e:"ui-display",a:{title:"No Linked Circuit Imprinter"}}],r:"data.circuit_linked"}]},e.exports=a.extend(r.exports)},{341:341}],443:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,30],t:7,e:"ui-display",a:{title:[{t:2,r:"data.sdesign_name",p:[2,21,49]}]},f:[{p:[3,3,75],t:7,e:"ui-section",a:{title:"Description"},f:[{t:2,r:"data.sdesign_desc",p:[3,35,107]}]}]}," ",{p:[5,2,158],t:7,e:"ui-display",a:{title:"Lathe Types"},f:[{t:4,f:[{p:[7,4,233],t:7,e:"ui-section",a:{title:"Circuit Imprinter"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&1"},p:[6,3,193]}," ",{t:4,f:[{p:[10,4,337],t:7,e:"ui-section",a:{title:"Protolathe"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&2"},p:[9,3,297]}," ",{t:4,f:[{p:[13,4,434],t:7,e:"ui-section",a:{title:"Autolathe"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&4"},p:[12,3,394]}," ",{t:4,f:[{p:[16,4,530],t:7,e:"ui-section",a:{title:"Crafting Fabricator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&8"},p:[15,3,490]}," ",{t:4,f:[{p:[19,4,637],t:7,e:"ui-section",a:{title:"Exosuit Fabricator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&16"},p:[18,3,596]}," ",{t:4,f:[{p:[22,4,743],t:7,e:"ui-section",a:{title:"Biogenerator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&32"},p:[21,3,702]}," ",{t:4,f:[{p:[25,4,843],t:7,e:"ui-section",a:{title:"Limb Grower"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&64"},p:[24,3,802]}," ",{t:4,f:[{p:[28,4,943],t:7,e:"ui-section",a:{title:"Ore Smelter"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&128"},p:[27,3,901]}]}," ",{p:[31,2,1015],t:7,e:"ui-display",a:{title:"Materials"},f:[{t:4,f:[{p:[33,4,1084],t:7,e:"ui-section",a:{title:[{t:2,r:"matname",p:[33,23,1103]}]},f:[{t:2,r:"matamt",p:[33,36,1116]}," cm^3"]}],n:52,r:"data.sdesign_materials",p:[32,3,1048]}]}],n:50,r:"data.design_selected",p:[1,1,0]},{t:4,f:[{p:[38,2,1211],t:7,e:"ui-display",a:{title:"No Design Selected."}}],n:50,x:{r:["data.design_selected"],s:"!_0"},p:[37,1,1180]}]},e.exports=a.extend(r.exports)},{341:341}],444:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[4,3,57],t:7,e:"ui-display",a:{title:"Destructive Analyzer Busy!"
-}}],n:50,r:"data.destroybusy",p:[3,2,30]},{t:4,n:51,f:[{t:4,f:[{p:[7,4,162],t:7,e:"ui-display",a:{title:"Destructive Analyzer Unloaded"}}],n:50,x:{r:["data.destroy_loaded"],s:"!_0"},p:[6,3,130]},{t:4,n:51,f:[{p:[9,4,240],t:7,e:"ui-display",a:{title:"Loaded Item"},f:[{p:[10,4,276],t:7,e:"ui-section",a:{title:"Name"},f:[{t:2,r:"data.destroy_name",p:[10,29,301]}]}]}," ",{p:[12,4,356],t:7,e:"ui-display",a:{title:"Boost Nodes"},f:[{t:4,f:[{p:[14,6,425],t:7,e:"ui-section",a:{title:[{t:2,r:"name",p:[14,25,444]}," | ",{t:2,r:"value",p:[14,36,455]}]},f:[{p:[15,7,473],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["allow"],s:'_0?null:"disabled"'},p:[15,25,491]}],action:"deconstruct",params:['{"id":',{t:2,r:"id",p:[15,90,556]},"}"]},f:["Deconstruct and Boost"]}]}],n:52,r:"data.boost_paths",p:[13,5,393]}]}," ",{p:[19,4,652],t:7,e:"ui-button",a:{action:"eject_da"},f:["Eject Item"]}],x:{r:["data.destroy_loaded"],s:"!_0"}}],r:"data.destroybusy"}],n:50,r:"data.destroy_linked",p:[2,1,1]},{t:4,n:51,f:[{p:[23,2,733],t:7,e:"ui-display",a:{title:"No Linked Destructive Analyzer"}}],r:"data.destroy_linked"}]},e.exports=a.extend(r.exports)},{341:341}],445:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[3,2,22],t:7,e:"ui-display",a:{title:"No Design Disk Loaded"}}],n:50,x:{r:["data.ddisk"],s:"!_0"},p:[2,1,1]},{t:4,n:51,f:[{t:4,f:[{p:[6,3,116],t:7,e:"ui-display",a:{title:"Design Disk Updating"}}],n:50,r:"data.ddisk_update",p:[5,2,88]},{t:4,n:51,f:[{t:4,f:[{p:[9,4,213],t:7,e:"ui-display",a:{title:"Design Disk"},f:[{p:[10,5,250],t:7,e:"ui-section",a:{title:"Disk Space"},f:["Disk Capacity: ",{t:2,r:"data.ddisk_size",p:[10,51,296]}," blueprints."]}," ",{p:[11,5,345],t:7,e:"ui-section",a:{title:"Disk IO"},f:[{p:[11,33,373],t:7,e:"ui-button",a:{action:"ddisk_upall"},f:["Upload all designs"]}]}," ",{p:[12,5,453],t:7,e:"ui-section",a:{title:"Clear Disk"},f:[{p:[12,36,484],t:7,e:"ui-button",a:{action:"clear_designdisk",style:"danger"},f:["WIPE ALL DATA"]}]}," ",{p:[13,5,579],t:7,e:"ui-section",a:{title:"Eject Disk"},f:[{p:[13,36,610],t:7,e:"ui-button",a:{action:"eject_designdisk"},f:["Eject Disk"]}]}]}," ",{p:[15,4,703],t:7,e:"ui-display",a:{title:"Disk Contents"},f:[{t:4,f:[{p:[17,6,776],t:7,e:"ui-section",a:{title:"Number"},f:["#",{t:2,r:"pos",p:[17,34,804]},": ",{t:4,f:[{p:[19,8,848],t:7,e:"ui-button",a:{action:"upload_empty_ddisk_slot",params:['{"slot": "',{t:2,r:"pos",p:[19,70,910]},'"}']},f:["Upload to Empty Slot"]}],n:50,x:{r:["id"],s:'_0=="null"'},p:[18,7,820]},{t:4,n:51,f:[{p:[21,8,976],t:7,e:"ui-button",a:{action:"select_design",params:['{"id": "',{t:2,r:"id",p:[21,58,1026]},'"}'],state:[{t:2,x:{r:["data.sdesign_id","id"],s:'_0==_1?"selected":null'},p:[21,75,1043]}]},f:[{t:2,r:"name",p:[21,122,1090]}]}," ",{p:[22,8,1118],t:7,e:"ui-button",a:{action:"ddisk_erasepos",style:"danger",params:['{"id": "',{t:2,r:"id",p:[22,74,1184]},'"}'],state:[{t:2,x:{r:["id"],s:'_0=="null"?"disabled":null'},p:[22,91,1201]}]},f:["Delete Slot"]}],x:{r:["id"],s:'_0=="null"'}}]}],n:52,r:"data.ddisk_designs",p:[16,5,742]}]}],n:50,x:{r:["data.ddisk_upload"],s:"!_0"},p:[8,3,183]},{t:4,n:51,f:[{p:[28,4,1340],t:7,e:"ui-display",a:{title:"Upload Design to Disk"},f:[{p:[28,46,1382],t:7,e:"ui-section",f:["Available Designs:"]}]}," ",{t:4,f:[{p:[30,5,1484],t:7,e:"ui-section",f:[{p:[30,17,1496],t:7,e:"ui-button",a:{action:"ddisk_uploaddesign",params:['{"id": "',{t:2,r:"id",p:[30,72,1551]},'"}']},f:[{t:2,r:"name",p:[30,82,1561]}]}]}],n:52,r:"data.ddisk_possible_designs",p:[29,4,1442]}],x:{r:["data.ddisk_upload"],s:"!_0"}}],r:"data.ddisk_update"}],x:{r:["data.ddisk"],s:"!_0"}}]},e.exports=a.extend(r.exports)},{341:341}],446:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[3,2,22],t:7,e:"ui-display",a:{title:"No Technology Disk Loaded"}}],n:50,x:{r:["data.tdisk"],s:"!_0"},p:[2,1,1]},{t:4,n:51,f:[{t:4,f:[{p:[6,3,120],t:7,e:"ui-display",a:{title:"Technology Disk Updating"}}],n:50,r:"data.tdisk_update",p:[5,2,92]},{t:4,n:51,f:[{p:[8,3,191],t:7,e:"ui-display",a:{title:"Technology Disk"},f:[{p:[9,4,231],t:7,e:"ui-section",a:{title:"Disk IO"},f:[{p:[9,32,259],t:7,e:"ui-button",a:{action:"tdisk_down"},f:["Download Research to Disk"]},{p:[9,100,327],t:7,e:"ui-button",a:{action:"tdisk_up"},f:["Upload Research from Disk"]}," ",{p:[10,4,397],t:7,e:"ui-section",a:{title:"Clear Disk"},f:[{p:[10,35,428],t:7,e:"ui-button",a:{action:"clear_techdisk",style:"danger"},f:["WIPE ALL DATA"]}]}," ",{p:[11,4,520],t:7,e:"ui-section",a:{title:"Eject Disk"},f:[{p:[11,35,551],t:7,e:"ui-button",a:{action:"eject_techdisk"},f:["Eject Disk"]}]}]}]}," ",{p:[13,3,640],t:7,e:"ui-display",a:{title:"Disk Contents"},f:[{t:4,f:[{p:[15,5,709],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[15,53,757]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[15,70,774]}]},f:[{t:2,r:"display_name",p:[15,115,819]}]}],n:52,r:"data.tdisk_nodes",p:[14,4,678]}]}],r:"data.tdisk_update"}],x:{r:["data.tdisk"],s:"!_0"}}]},e.exports=a.extend(r.exports)},{341:341}],447:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,28],t:7,e:"ui-display",a:{title:[{t:2,r:"data.snode_name",p:[2,21,47]}]},f:[{p:[3,3,71],t:7,e:"ui-section",a:{title:"Description"},f:["Description: ",{t:2,r:"data.snode_desc",p:[3,48,116]}]}," ",{p:[4,3,151],t:7,e:"ui-section",a:{title:"Point Cost"},f:["Point Cost: ",{t:2,r:"data.snode_cost",p:[4,46,194]}]}," ",{p:[5,3,229],t:7,e:"ui-section",a:{title:"Export Price"},f:["Export Price: ",{t:2,r:"data.snode_export",p:[5,50,276]}]}," ",{p:[6,3,313],t:7,e:"ui-button",a:{action:"research_node",params:['{"id"="',{t:2,r:"id",p:[6,52,362]},'"}'],state:[{t:2,x:{r:["data.snode_researched"],s:'_0?"disabled":null'},p:[6,69,379]}]},f:[{t:2,x:{r:["data.snode_researched"],s:'_0?"Researched":"Research Node"'},p:[6,115,425]}]}]}," ",{p:[8,2,511],t:7,e:"ui-display",a:{title:"Prerequisites"},f:[{t:4,f:[{p:[10,4,579],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[10,52,627]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[10,69,644]}]},f:[{t:2,r:"display_name",p:[10,114,689]}]}],n:52,r:"data.node_prereqs",p:[9,3,548]}]}," ",{p:[13,2,747],t:7,e:"ui-display",a:{title:"Unlocks"},f:[{t:4,f:[{p:[15,4,809],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[15,52,857]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[15,69,874]}]},f:[{t:2,r:"display_name",p:[15,114,919]}]}],n:52,r:"data.node_unlocks",p:[14,3,778]}]}," ",{p:[18,2,977],t:7,e:"ui-display",a:{title:"Designs"},f:[{t:4,f:[{p:[20,4,1039],t:7,e:"ui-button",a:{action:"select_design",params:['{"id": "',{t:2,r:"id",p:[20,54,1089]},'"}'],state:[{t:2,x:{r:["data.sdesign_id","id"],s:'_0==_1?"selected":null'},p:[20,71,1106]}]},f:[{t:2,r:"name",p:[20,118,1153]}]}],n:52,r:"data.node_designs",p:[19,3,1008]}]}],n:50,r:"data.node_selected",p:[1,1,0]},{t:4,f:[{p:[25,2,1239],t:7,e:"ui-display",a:{title:"No Node Selected."}}],n:50,x:{r:["data.node_selected"],s:"!_0"},p:[24,1,1210]}]},e.exports=a.extend(r.exports)},{341:341}],448:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[3,3,57],t:7,e:"ui-display",a:{title:"Protolathe Busy!"}}],n:50,r:"data.protobusy",p:[2,2,32]},{t:4,n:51,f:[{p:[5,3,120],t:7,e:"ui-display",f:[{p:[6,4,136],t:7,e:"ui-section",f:["Search Available Designs: ",{p:[7,4,177],t:7,e:"input",a:{value:[{t:2,r:"textsearch",p:[7,17,190]}],placeholder:"Type Here","class":"text"}}," ",{p:[8,5,248],t:7,e:"ui-button",a:{action:"textSearch",params:['{"latheType" : "proto", "inputText" : ',{t:2,r:"textsearch",p:[8,82,325]},"}"]},f:["Search"]}]}," ",{p:[10,4,381],t:7,e:"ui-section",f:["Materials: ",{t:2,r:"data.protomats",p:[10,27,404]}," / ",{t:2,r:"data.protomaxmats",p:[10,48,425]}]}," ",{p:[11,4,463],t:7,e:"ui-section",f:["Reagents: ",{t:2,r:"data.protochems",p:[11,26,485]}," / ",{t:2,r:"data.protomaxchems",p:[11,48,507]}]}," ",{p:[12,3,545],t:7,e:"ui-display",f:[{p:[14,3,561],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.lathe_tabs",p:[14,18,576]}]},f:[{p:[15,4,601],t:7,e:"tab",a:{name:"Category List"},f:[{t:4,f:[{p:[17,6,662],t:7,e:"ui-button",a:{action:"switchcat",state:[{t:2,x:{r:["data.protocat","name"],s:'_0==_1?"selected":null'},p:[17,43,699]}],params:['{"type" : "proto", "cat" : "',{t:2,r:"name",p:[17,125,781]},'"}']},f:[{t:2,r:"name",p:[17,137,793]}]}],n:52,r:"data.protocats",p:[16,5,632]}]}," ",{p:[20,4,841],t:7,e:"tab",a:{name:"Selected Category"},f:[{t:4,f:[{p:[22,6,905],t:7,e:"ui-section",f:[{t:2,r:"name",p:[22,18,917]},{t:2,r:"matstring",p:[22,26,925]}," ",{t:4,f:[{p:[24,8,973],t:7,e:"input",a:{value:[{t:2,r:"number",p:[24,21,986]}],placeholder:["1-",{t:2,x:{r:["canprint"],s:"_0>10?10:_0"},p:[24,47,1012]}],"class":"number"}}],n:50,x:{r:["canprint"],s:"_0>1"},p:[23,7,945]}," ",{p:[26,7,1083],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[26,40,1116]}],params:['{"latheType" : "proto", "id" : "',{t:2,r:"id",p:[26,117,1193]},'", "amount" : "',{t:2,r:"number",p:[26,138,1214]},'"}']},f:["Print"]}]}],n:52,r:"data.protodes",p:[21,5,876]}]}," ",{p:[30,4,1292],t:7,e:"tab",a:{name:"Search Results"},f:[{t:4,f:[{p:[32,6,1355],t:7,e:"ui-section",f:[{t:2,r:"name",p:[32,18,1367]},{t:2,r:"matstring",p:[32,26,1375]}," ",{t:4,f:[{p:[34,8,1423],t:7,e:"input",a:{value:[{t:2,r:"number",p:[34,21,1436]}],placeholder:["1-",{t:2,x:{r:["canprint"],s:"_0>10?10:_0"},p:[34,47,1462]}],"class":"number"}}],n:50,x:{r:["canprint"],s:"_0>1"},p:[33,7,1395]}," ",{p:[36,7,1533],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[36,40,1566]}],params:['{"latheType" : "proto", "id" : "',{t:2,r:"id",p:[36,117,1643]},'", "amount" : "',{t:2,r:"number",p:[36,138,1664]},'"}']},f:["Print"]}]}],n:52,r:"data.protomatch",p:[31,5,1324]}]}," ",{p:[40,4,1742],t:7,e:"tab",a:{name:"Materials"},f:[{t:4,f:[{p:[42,6,1803],t:7,e:"ui-section",f:[{t:2,r:"name",p:[42,18,1815]}," : ",{t:2,r:"amount",p:[42,29,1826]}," cm3 - ",{t:4,f:[{p:[44,7,1874],t:7,e:"input",a:{value:[{t:2,r:"number",p:[44,20,1887]}],placeholder:["1-",{t:2,r:"sheets",p:[44,46,1913]}],"class":"number"}}," ",{p:[45,7,1948],t:7,e:"ui-button",a:{action:"releasemats",params:['{"latheType" : "proto", "mat_id" : ',{t:2,r:"mat_id",p:[45,82,2023]},', "sheets" : ',{t:2,r:"number",p:[45,105,2046]},"}"]},f:["Release"]}],n:50,x:{r:["sheets"],s:"_0>0"},p:[43,6,1849]}]}],n:52,r:"data.protomat_list",p:[41,5,1769]}]}," ",{p:[50,4,2138],t:7,e:"tab",a:{name:"Chemicals"},f:[{t:4,f:[{p:[52,6,2200],t:7,e:"ui-section",f:[{t:2,r:"name",p:[52,18,2212]}," : ",{t:2,r:"amount",p:[52,29,2223]}," - ",{p:[53,7,2243],t:7,e:"ui-button",a:{action:"purgechem",params:['{"latheType" : "proto", "name" : ',{t:2,r:"name",p:[53,78,2314]},', "id" : ',{t:2,r:"reagentid",p:[53,95,2331]},"}"]},f:["Purge"]}]}],n:52,r:"data.protochem_list",p:[51,5,2165]}]}]}]}]}],r:"data.protobusy"}],n:50,r:"data.protolathe_linked",p:[1,1,0]},{t:4,n:51,f:[{p:[61,2,2444],t:7,e:"ui-display",a:{title:"No Linked Protolathe"}}],r:"data.protolathe_linked"}]},e.exports=a.extend(r.exports)},{341:341}],449:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,1,13],t:7,e:"span",a:{"class":"memoedit"},f:["Nanotrasen R&D Console"]},{p:[2,53,65],t:7,e:"br"}," Available Points: ",{p:[3,19,89],t:7,e:"ui-section",a:{title:"Research Points"},f:[{t:2,r:"data.research_points_stored",p:[3,55,125]}]}," ",{p:[4,1,170],t:7,e:"ui-section",a:{title:["Page Selection - ",{t:2,r:"page",p:[4,37,206]}]},f:[{p:[4,47,216],t:7,e:"input",a:{value:[{t:2,r:"pageselect",p:[4,60,229]}],placeholder:"1","class":"number"}}," Select Page: ",{p:[5,14,290],t:7,e:"ui-button",a:{action:"page",params:['{"num" : "',{t:2,r:"pageselect",p:[5,57,333]},'"}']},f:["[Go]"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],450:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"span",a:{"class":"bad"},f:["Settings"]},{p:[1,34,33],t:7,e:"br"},{p:[1,39,38],t:7,e:"br"}," ",{p:[2,1,44],t:7,e:"ui-button",a:{action:"Resync"},f:["RESYNC MACHINERY"]},{p:[2,56,99],t:7,e:"br"}," ",{p:[3,1,105],t:7,e:"ui-button",a:{action:"Lock"},f:["LOCK"]}," ",{p:[4,1,147],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "destroy"}',state:[{t:2,x:{r:["data.destroy_linked"],s:'_0?null:"disabled"'},p:[4,71,217]}]},f:["Disconnect Destructive Analyzer"]}," ",{p:[5,1,305],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "lathe"}',state:[{t:2,x:{r:["data.protolathe_linked"],s:'_0?null:"disabled"'},p:[5,69,373]}]},f:["Disconnect Protolathe"]}," ",{p:[6,1,454],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "imprinter"}',state:[{t:2,x:{r:["data.circuit_linked"],s:'_0?null:"disabled"'},p:[6,73,526]}]},f:["Disconnect Circuit Imprinter"]}]},e.exports=a.extend(r.exports)},{341:341}],451:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Available for Research"},f:[{t:4,f:[{p:[3,3,76],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[3,51,124]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[3,68,141]}]},f:[{t:2,r:"display_name",p:[3,113,186]}]}],n:52,r:"data.techweb_avail",p:[2,2,45]}]}," ",{p:[6,1,240],t:7,e:"ui-display",a:{title:"Locked Nodes"},f:[{t:4,f:[{p:[8,3,307],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[8,51,355]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[8,68,372]}]},f:[{t:2,r:"display_name",p:[8,113,417]}]}],n:52,r:"data.techweb_locked",p:[7,2,275]}]}," ",{p:[11,1,472],t:7,e:"ui-display",a:{title:"Researched Nodes"},f:[{t:4,f:[{p:[13,3,547],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[13,51,595]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[13,68,612]}]},f:[{t:2,r:"display_name",p:[13,113,657]}]}],n:52,r:"data.techweb_researched",p:[12,2,511]}]}]},e.exports=a.extend(r.exports)},{341:341}],452:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,24],t:7,e:"ui-notice",f:[{p:[3,3,38],t:7,e:"span",f:["The grinder is currently processing and cannot be used."]}]}],n:50,r:"data.processing",p:[1,1,0]},{p:{button:[{p:[8,5,201],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[8,36,232]}],action:"eject"},f:["Eject Contents"]}]},t:7,e:"ui-display",a:{title:"Processing Chamber",button:0},f:[" ",{p:[10,3,355],t:7,e:"ui-section",a:{label:"Grinding"},f:[{p:[11,5,389],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.operating"],s:'_0?"average":"good"'},p:[11,18,402]}]},f:[{t:2,x:{r:["data.operating"],s:'_0?"Busy":"Ready"'},p:[11,59,443]}]}," ",{p:[12,2,489],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[12,35,522]}],action:"grind"},f:["Activate"]}]}," ",{p:[14,3,640],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[17,9,739],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:["The ",{t:2,r:"name",p:[17,56,786]}]},{p:[17,71,801],t:7,e:"br"}],n:52,r:"adata.contentslist",p:[16,7,702]},{t:4,n:51,f:[{p:[19,9,830],t:7,e:"span",f:["No Contents"]}],r:"adata.contentslist"}],n:50,r:"data.contents",p:[15,5,674]},{t:4,n:51,f:[{p:[22,7,890],t:7,e:"span",f:["No Contents"]}],r:"data.contents"}]}]}," ",{p:{button:[{p:[28,5,1020],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.isBeakerLoaded"],s:'(_0==0)&&_1?null:"disabled"'},p:[28,36,1051]}],action:"detach"},f:["Detach"]}]},t:7,e:"ui-display",a:{title:"Container",button:0},f:[" ",{p:[30,3,1173],t:7,e:"ui-section",a:{label:"Reagents"},f:[{t:4,f:[{p:[32,7,1241],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[32,13,1247]},"/",{t:2,r:"data.beakerMaxVolume",p:[32,55,1289]}," Units"]}," ",{p:[33,7,1333],t:7,e:"br"}," ",{t:4,f:[{p:[35,9,1384],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[35,52,1427]}," units of ",{t:2,r:"name",p:[35,87,1462]}]},{p:[35,102,1477],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[34,7,1345]},{t:4,n:51,f:[{p:[37,9,1506],t:7,e:"span",a:{"class":"bad"},f:["Container Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[31,5,1207]},{t:4,n:51,f:[{p:[40,7,1582],t:7,e:"span",a:{"class":"average"},f:["No Container"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],453:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,62],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,101],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,119]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,190]},', "flipped": ',{t:2,r:"flipped",p:[6,42,210]},"}"]},f:[{p:[6,56,224],t:7,e:"span",a:{"class":["pipes32x32 ",{t:2,r:"dir",p:[6,80,248]},"-",{t:2,r:"icon_state",p:[6,88,256]}],title:[{t:2,r:"dir_name",p:[6,111,279]}]}}]}],n:52,r:"previews",p:[4,4,78]}]}],n:52,r:"data.preview_rows",p:[2,2,32]}]}," ",{t:4,f:[{p:[12,2,395],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[14,4,455],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["@key","data.selected_color"],s:'_0==_1?"selected":null'},p:[14,22,473]}],action:"color",params:['{"paint_color": ',{t:2,r:"@key",p:[15,44,569]},"}"]},f:[{t:2,r:"@key",p:[15,55,580]}]}],n:52,r:"data.paint_colors",p:[13,3,424]}]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[11,1,367]},{p:[19,1,636],t:7,e:"ui-display",a:{title:"Utilities"},f:[{p:[20,2,668],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&1?"check-square-o":"square-o"'},p:[20,19,685]}],action:"mode",params:'{"mode": 1}'},f:["Build"]}," ",{p:[22,2,792],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&2?"check-square-o":"square-o"'},p:[22,19,809]}],action:"mode",params:'{"mode": 2}'},f:["Wrench"]}," ",{p:[24,2,917],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&4?"check-square-o":"square-o"'},p:[24,19,934]}],action:"mode",params:'{"mode": 4}'},f:["Destroy"]}," ",{t:4,f:[{p:[27,3,1072],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&8?"check-square-o":"square-o"'},p:[27,20,1089]}],action:"mode",params:'{"mode": 8}'},f:["Paint"]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[26,2,1043]}]}," ",{p:[31,1,1219],t:7,e:"ui-display",a:{title:"Category"},f:[{p:[32,2,1250],t:7,e:"ui-section",f:[{p:[33,3,1265],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==0?"check-square-o":"square-o"'},p:[33,20,1282]}],state:[{t:2,x:{r:["data.category"],s:'_0<=0?"selected":null'},p:[33,83,1345]}],action:"category",params:'{"category": 0}'},f:["Atmospherics"]}," ",{p:[35,3,1462],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==1?"check-square-o":"square-o"'},p:[35,20,1479]}],state:[{t:2,x:{r:["data.category"],s:'_0==1?"selected":null'},p:[35,83,1542]}],action:"category",params:'{"category": 1}'},f:["Disposals"]}," ",{p:[37,3,1656],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==2?"check-square-o":"square-o"'},p:[37,20,1673]}],state:[{t:2,x:{r:["data.category"],s:'_0==2?"selected":null'},p:[37,83,1736]}],action:"category",params:'{"category": 2}'},f:["Transit Tubes"]}]}," ",{t:4,f:[{p:[41,3,1897],t:7,e:"ui-section",a:{label:"Piping Layer"},f:[{p:[42,4,1934],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==1?"selected":null'},p:[42,22,1952]}],action:"piping_layer",params:'{"piping_layer": 1}'},f:["1"]}," ",{p:[44,4,2072],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==2?"selected":null'},p:[44,22,2090]}],action:"piping_layer",params:'{"piping_layer": 2}'},f:["2"]}," ",{p:[46,4,2210],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==3?"selected":null'},p:[46,22,2228]}],action:"piping_layer",params:'{"piping_layer": 3}'},f:["3"]}]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[40,2,1868]}]}," ",{t:4,f:[{p:[52,2,2411],t:7,e:"ui-display",a:{title:[{t:2,r:"cat_name",p:[52,21,2430]}]},f:[{t:4,f:[{p:[54,4,2468],t:7,e:"ui-section",f:[{p:[55,5,2485],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[55,23,2503]}],action:"pipe_type",params:['{"pipe_type": ',{t:2,r:"pipe_index",p:[56,28,2583]},', "category": ',{t:2,r:"cat_name",p:[56,56,2611]},"}"]},f:[{t:2,r:"pipe_name",p:[56,71,2626]}]}]}],n:52,r:"recipes",p:[53,3,2447]}]}],n:52,r:"data.categories",p:[51,1,2384]}]},e.exports=a.extend(r.exports)},{341:341}],454:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[3,3,58],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[3,21,76]}],action:"color",params:['{"paint_color": ',{t:2,r:"color_name",p:[4,28,152]},"}"]},f:[{t:2,r:"color_name",p:[4,45,169]}]}],n:52,r:"data.paint_colors",p:[2,2,28]}]}]},e.exports=a.extend(r.exports)},{341:341}],455:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,62],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,101],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,119]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,190]},', "flipped": ',{t:2,r:"flipped",p:[6,42,210]},"}"]},f:[{p:[6,56,224],t:7,e:"img",a:{src:["pipe.",{t:2,r:"dir",p:[6,71,239]},".",{t:2,r:"icon_state",p:[6,79,247]},".png"],title:[{t:2,r:"dir_name",p:[6,106,274]}]}}]}],n:52,r:"previews",p:[4,4,78]}]}],n:52,r:"data.preview_rows",p:[2,2,32]}]}]},e.exports=a.extend(r.exports)},{341:341}],456:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,22],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,38]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,77],t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,161],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,201],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,223]}]}," ",{p:[10,9,244],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,265]}]}," ",{p:[11,9,288],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,320],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,363]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,373]}]}]}]}],n:52,r:"data.satellites",p:[7,2,132]}]}," ",{t:4,f:[{p:[18,1,511],t:7,e:"ui-display",a:{title:"Station Shield Coverage"},f:[{p:[19,3,558],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,579]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,623]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,656]}," %"]}," ",{p:[20,1,739],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,484]}]},e.exports=a.extend(r.exports)},{341:341}],457:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[2,20,42]}],style:[{t:2,x:{r:["enabled"],s:'_0?"selected":null'},p:[2,72,94]}],action:"toggle_filter",params:['{"id_tag": "',{t:2,r:"id_tag",p:[3,48,174]},'", "val": ',{t:2,r:"gas_id",p:[3,68,194]},"}"]},f:[{t:2,r:"gas_name",p:[3,81,207]}]}],n:52,r:"filter_types",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],458:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,196],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,211]}]},f:[{p:[6,2,228],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,250],t:7,e:"status"}]}," ",{p:[9,2,269],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,294],t:7,e:"templates"}]}," ",{p:[12,2,316],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,368],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,344]}," ",{t:4,f:[{p:[17,3,421],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,396]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(459),templates:t(461),status:t(460)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,459:459,460:460,461:461}],459:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,94],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,126]}]}],n:50,r:"data.selected.description",p:[2,3,56]}," ",{t:4,f:[{p:[6,5,219],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,251]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,181]}]}," ",{t:4,f:[{p:[11,3,351],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,388]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,433]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,513]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,470]}," ",{p:[16,5,565],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,633]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,319]},{t:4,f:[{p:[24,3,755],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,722]},{p:[27,1,821],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,875]},'"}']},f:["Preview"]}," ",{p:[31,1,931],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,982]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1053],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{341:341}],460:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"table",a:{width:"100%"},f:[{t:4,f:[{p:[3,3,47],t:7,e:"tr",f:[{p:[4,5,56],t:7,e:"td",f:[{p:[5,7,67],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[5,69,129]},'"}']},f:["JMP"]}]}," ",{p:[9,5,185],t:7,e:"td",f:[{p:[10,7,196],t:7,e:"ui-button",a:{action:"fly",params:['{"id": "',{t:2,r:"id",p:[10,47,236]},'"}'],state:[{t:2,x:{r:["can_fly"],s:'_0?null:"disabled"'},p:[10,64,253]}]},f:["Fly"]}]}," ",{p:[14,5,332],t:7,e:"td",f:[{t:2,r:"name",p:[15,7,343]}," (",{p:[15,17,353],t:7,e:"code",f:[{t:2,r:"id",p:[15,23,359]}]},")"]}," ",{p:[17,5,388],t:7,e:"td",f:[{t:2,r:"status",p:[18,7,399]}]}," ",{p:[20,5,424],t:7,e:"td",f:[{t:4,f:[{t:2,r:"mode",p:[22,9,456]}],n:50,r:"mode",p:[21,7,435]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[25,10,508]},") ",{p:[26,9,530],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[26,57,578]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[26,74,595]}]},f:["Fast Travel"]}],n:50,r:"timer",p:[24,7,485]}]}]}],n:52,r:"data.shuttles",p:[2,1,21]}]}]},e.exports=a.extend(r.exports)},{341:341}],461:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,72],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,83]}]},f:[{t:4,f:[{p:[5,9,131],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,150]}]},f:[{t:4,f:[{p:[7,13,203],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,235]}]}],n:50,r:"description",p:[6,11,171]}," ",{t:4,f:[{p:[10,13,324],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,356]}]}],n:50,r:"admin_notes",p:[9,11,292]}," ",{p:[13,11,414],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,486]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,523]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,614]}]}]}],n:52,r:"templates",p:[4,7,103]}]}],n:52,r:"data.templates",p:[2,3,43]}]}]},e.exports=a.extend(r.exports)},{341:341}],462:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,32],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,64],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,70]}]}]}," ",{t:4,f:[{p:[6,5,181],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,214],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,227]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,256]}]}]}," ",{p:[9,5,307],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[10,7,341],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[10,20,354]}],max:[{t:2,r:"data.occupant.maxHealth",p:[10,54,388]}],value:[{t:2,r:"data.occupant.health",p:[10,90,424]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[11,16,465]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[11,68,517]}]}]}," ",{t:4,f:[{p:[14,7,751],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[14,26,770]}]},f:[{p:[15,9,790],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[15,30,811]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[15,66,847]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[15,103,884]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[13,5,586]}," ",{t:4,f:[{p:[19,7,1002],t:7,e:"ui-section",a:{label:"Blood"},f:[{p:[20,9,1037],t:7,e:"ui-section",a:{label:"Volume"},f:[{p:[21,11,1075],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.blood.maxBloodVolume",p:[21,32,1096]}],value:[{t:2,r:"data.occupant.blood.currentBloodVolume",p:[21,79,1143]}],state:[{t:2,x:{r:["data.occupant.blood.currentBloodVolume","data.occupant.blood.dangerBloodVolume"],s:'_0<=_1?"bad":"good"'},p:[21,130,1194]}]},f:[{t:3,x:{r:["data.occupant.blood.currentBloodVolume","data.occupant.blood.dangerBloodVolume"],s:'_0<=_1?"LOW ":"OK"'},p:[21,232,1296]}," - ",{t:2,x:{r:["data.occupant.blood.currentBloodVolume"],s:"Math.round(_0)"},p:[21,342,1406]}," cl"]}]}," ",{p:[23,9,1503],t:7,e:"ui-section",a:{label:"Type"},f:[{p:[24,11,1539],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:"data.occupant.blood.bloodType",p:[24,35,1563]}]}]}]}],n:50,r:"data.occupant.blood",p:[18,5,968]}," ",{p:[28,5,1662],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[29,9,1697],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[29,22,1710]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[29,68,1756]}]}]}," ",{p:[31,5,1837],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[32,9,1872],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[32,22,1885]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[32,68,1931]}]}]}," ",{p:[34,5,2013],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[36,11,2098],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[36,54,2141]}," units of ",{t:2,r:"name",p:[36,89,2176]}]},{p:[36,104,2191],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[35,9,2054]},{t:4,n:51,f:[{p:[38,11,2224],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[5,3,155]}]}," ",{p:[43,1,2315],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[44,2,2346],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[45,5,2376],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[45,22,2393]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[45,71,2442]}]}]}," ",{p:[47,3,2505],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[49,7,2564],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],
-s:'_0&&_1?null:"disabled"'},p:[49,38,2595]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[49,122,2679]},'"}']},f:[{t:2,r:"name",p:[49,132,2689]}]},{p:[49,152,2709],t:7,e:"br"}],n:52,r:"data.chems",p:[48,5,2537]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],463:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,24],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,43]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,65]}],candystripe:0,right:0},f:[{p:[3,5,103],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,130],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,143]}]},f:[{t:2,r:"status",p:[3,132,230]}]}]}," ",{p:[4,5,265],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,291]}]}," ",{p:[5,5,324],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,353]}]}," ",{p:[7,5,380],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,404]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,464]},'"}']},f:[{t:4,f:["You Are Here"],n:50,x:{r:["occupied"],s:'_0=="owner"'},p:[10,7,482]},{t:4,n:51,f:[{t:4,f:["Occupied"],n:50,x:{r:["occupied"],s:'_0=="stranger"'},p:[13,9,554]},{t:4,n:51,f:["Swap"],x:{r:["occupied"],s:'_0=="stranger"'}}],x:{r:["occupied"],s:'_0=="owner"'}}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],464:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,23,79],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.drying"],s:'_0?"stop":"tint"'},p:[4,40,96]}],action:"Dry"},f:[{t:2,x:{r:["data.drying"],s:'_0?"Stop drying":"Dry"'},p:[4,88,144]}]}],n:50,r:"data.isdryer",p:[4,3,59]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[7,3,252],t:7,e:"ui-notice",f:[{p:[8,5,268],t:7,e:"span",f:["Unfortunately, this ",{t:2,r:"data.name",p:[8,31,294]}," is empty."]}]}],n:50,x:{r:["data.contents.length"],s:"_0==0"},p:[6,1,216]},{t:4,n:51,f:[{p:[11,1,349],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[12,2,380],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[13,4,413],t:7,e:"section",a:{"class":"cell bold"},f:["Item"]}," ",{p:[16,4,467],t:7,e:"section",a:{"class":"cell bold"},f:["Quantity"]}," ",{p:[19,4,525],t:7,e:"section",a:{"class":"cell bold",align:"center"},f:[{t:4,f:[{t:2,r:"data.verb",p:[20,22,589]}],n:50,r:"data.verb",p:[20,5,572]},{t:4,n:51,f:["Dispense"],r:"data.verb"}]}]}," ",{t:4,f:[{p:[24,3,680],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[25,4,713],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[26,5,740]}]}," ",{p:[28,4,766],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[29,5,807]}]}," ",{p:[31,4,835],t:7,e:"section",a:{"class":"table",alight:"right"},f:[{p:[32,5,878],t:7,e:"section",a:{"class":"cell"}}," ",{p:[33,5,915],t:7,e:"section",a:{"class":"cell"},f:[{p:[34,6,943],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[34,45,982]}],params:['{ "name" : ',{t:2,r:"name",p:[34,102,1039]},', "amount" : 1 }']},f:["One"]}]}," ",{p:[38,5,1114],t:7,e:"section",a:{"class":"cell"},f:[{p:[39,6,1142],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>1)?null:"disabled"'},p:[39,45,1181]}],params:['{ "name" : ',{t:2,r:"name",p:[39,101,1237]}," }"]},f:["Many"]}]}]}]}],n:52,r:"data.contents",p:[23,2,654]}]}],x:{r:["data.contents.length"],s:"_0==0"}}]}]},e.exports=a.extend(r.exports)},{341:341}],465:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,640],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,671],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,710],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,743]}],state:[{t:2,r:"capacityPercentState",p:[26,71,776]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,802]},"%"]}]}]}," ",{p:[29,1,880],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,909],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,946],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,963]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1015]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1082]}]}," [",{p:[34,6,1149],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1162]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1178]}]},"]"]}," ",{p:[36,3,1300],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1338],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1359]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1390]}]},f:[{t:2,r:"adata.inputLevel_text",p:[37,78,1411]}]}]}," ",{p:[39,3,1463],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1501],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1540]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1634],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1668]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1763],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1852],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1885]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,1996],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2034]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2159],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2192],t:7,e:"span",f:[{t:2,r:"adata.inputAvailable",p:[47,9,2198]}]}]}]}," ",{p:[50,1,2259],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2289],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2326],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2343]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2398]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2467]}]}," [",{p:[55,6,2533],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2546]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2563]}]},"]"]}," ",{p:[57,3,2668],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2707],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2728]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2760]}]},f:[{t:2,r:"adata.outputLevel_text",p:[58,80,2782]}]}]}," ",{p:[60,3,2835],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2874],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,2913]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3009],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3043]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3140],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3230],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3263]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3377],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3415]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3543],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3577],t:7,e:"span",f:[{t:2,r:"adata.outputUsed",p:[68,9,3583]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],466:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:["\ufeff",{t:4,f:[" ",{p:[2,2,32],t:7,e:"ui-display",a:{title:"Dispersal Tank"},f:[{p:[3,3,71],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[4,4,101],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.active"],s:'_0?"power-off":"close"'},p:[4,21,118]}],style:[{t:2,x:{r:["data.active"],s:'_0?"selected":null'},p:[5,12,170]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[6,12,218]}],action:"power"},f:[{t:2,x:{r:["data.active"],s:'_0?"On":"Off"'},p:[7,20,280]}]}]}," ",{p:[10,3,345],t:7,e:"ui-section",a:{label:"Smoke Radius Setting"},f:[{p:[11,5,391],t:7,e:"div",a:{"class":"content",style:"float:left"},f:[{p:[12,6,437],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=1?null:"disabled"'},p:[12,36,467]}],style:[{t:2,x:{r:["data.setting"],s:'_0==1?"selected":null'},p:[12,89,520]}],action:"setting",params:'{"amount": 1}'},f:["3"]}," ",{p:[13,6,622],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=2?null:"disabled"'},p:[13,36,652]}],style:[{t:2,x:{r:["data.setting"],s:'_0==2?"selected":null'},p:[13,89,705]}],action:"setting",params:'{"amount": 2}'},f:["6"]}," ",{p:[14,6,807],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=3?null:"disabled"'},p:[14,36,837]}],style:[{t:2,x:{r:["data.setting"],s:'_0==3?"selected":null'},p:[14,89,890]}],action:"setting",params:'{"amount": 3}'},f:["9"]}," ",{p:[15,6,992],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=4?null:"disabled"'},p:[15,36,1022]}],style:[{t:2,x:{r:["data.setting"],s:'_0==4?"selected":null'},p:[15,89,1075]}],action:"setting",params:'{"amount": 4}'},f:["12"]}," ",{p:[16,6,1178],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=5?null:"disabled"'},p:[16,36,1208]}],style:[{t:2,x:{r:["data.setting"],s:'_0==5?"selected":null'},p:[16,89,1261]}],action:"setting",params:'{"amount": 5}'},f:["15"]}]}]}," ",{p:[19,3,1392],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[21,6,1456],t:7,e:"span",f:[{t:2,x:{r:["adata.TankCurrentVolume"],s:"Math.round(_0)"},p:[21,12,1462]},"/",{t:2,r:"data.TankMaxVolume",p:[21,52,1502]}," Units"]}," ",{p:[22,6,1543],t:7,e:"br"}," ",{p:[23,5,1553],t:7,e:"br"}," ",{t:4,f:[{p:[25,7,1599],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[25,50,1642]}," units of ",{t:2,r:"name",p:[25,85,1677]}]},{p:[25,100,1692],t:7,e:"br"}],n:52,r:"adata.TankContents",p:[24,6,1564]}],n:50,r:"data.isTankLoaded",p:[20,4,1425]},{t:4,n:51,f:[{p:[28,6,1730],t:7,e:"span",a:{"class":"bad"},f:["Tank Empty"]}],r:"data.isTankLoaded"}," ",{p:[30,4,1780],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Eject":"Close"'},p:[30,21,1797]}],style:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"selected":null'},p:[31,12,1851]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[32,12,1905]}],action:"purge"},f:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Purge Contents":"No chemicals detected"'},p:[33,20,1967]}]}]}]}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,2,1]}]},e.exports=a.extend(r.exports)},{341:341}],467:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,30],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,71]},"W"]}," ",{p:[5,3,122],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,159],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,165]},"° (",{t:2,r:"data.direction",p:[6,45,199]},")"]}]}," ",{p:[8,3,244],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,282],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,378],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,467],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,554],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,673],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,705],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,743],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,774]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,889],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,922]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1039],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1072]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1239],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1276],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1282]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1326]},")"]}]}," ",{p:[27,3,1373],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1410],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1507],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1602],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1690],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1776],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1869],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2051],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2130],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2169],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2182]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2227]},"Found"]}]}," ",{p:[43,2,2296],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2332],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2345]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2389]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],468:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,84],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,115]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,60]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,220],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,251],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,268]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,318]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,358]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,422]}]}]}," ",{p:[12,3,479],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,541],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,574]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,595]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,509]},{t:4,n:51,f:[{p:[16,4,652],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,725],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,759],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,802],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,808]},"°C"]}]}," ",{p:[24,2,871],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,913],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,919]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1004],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1045],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1084]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1189],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1223]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1327],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1419],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1452]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1555],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1593]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,982]}," ",{p:[36,3,1719],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1771],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1810]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1918],t:7,e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1959]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{p:[40,7,2067],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2101]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1747]},{t:4,n:51,f:[{p:[42,4,2217],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2223]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],469:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,8,97],t:7,e:"ui-button",a:{action:"jump",params:['{"name" : ',{t:2,r:"name",p:[4,51,140]},"}"]},f:["Jump"]}," ",{p:[7,9,195],t:7,e:"ui-button",a:{action:"spawn",params:['{"name" : ',{t:2,r:"name",p:[7,53,239]},"}"]},f:["Spawn"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[2,22,46]}],button:0},f:[" ",{p:[11,3,308],t:7,e:"ui-section",a:{label:"Description"},f:[{p:[12,5,346],t:7,e:"span",f:[{t:3,r:"desc",p:[12,11,352]}]}]}," ",{p:[14,3,390],t:7,e:"ui-section",a:{label:"Spawners left"},f:[{p:[15,5,430],t:7,e:"span",f:[{t:2,r:"amount_left",p:[15,11,436]}]}]}]}],n:52,r:"data.spawners",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],470:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,30],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,49]}," Alarms"]},f:[{p:[3,5,72],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,103],t:7,e:"li",f:[{t:2,r:".",p:[5,13,107]}]}],n:52,r:".",p:[4,7,83]},{t:4,n:51,f:[{p:[7,9,141],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],471:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,41],t:7,e:"ui-notice",f:[{p:[3,5,57],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,173],t:7,e:"ui-notice",f:[{p:[8,5,189],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,148]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,357],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,374]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,425]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,339]}," ",{t:4,f:[{p:[14,27,506],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,523]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,577]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,486]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,676],t:7,e:"ui-notice",f:[{p:[18,9,696],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,650]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,773],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,811],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,828]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,875]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,970]}]}]}," ",{p:[25,9,1039],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1075],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1092]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1138]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1229]}]}]}," ",{p:[29,9,1296],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1332],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1349]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1395]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1486]}]}]}," ",{p:[33,9,1553],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1592],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1609]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1658]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1755]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1836],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1869]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{341:341}],472:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,17],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,55],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,72]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,120]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,193]},")"]}," ",{p:[5,9,243],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,260]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,308]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,381]},")"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],473:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,282],t:7,e:"ui-notice",f:[{p:[15,3,296],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,316]}," connected to a mask."]}]}," ",{p:[17,1,393],t:7,e:"ui-display",f:[{p:[18,3,408],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,449],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,483]}],state:[{t:2,r:"tankPressureState",p:[20,16,521]}]},f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[20,39,544]}," kPa"]}]}," ",{p:[22,3,610],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,652],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,665]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,699]}],value:[{t:2,r:"data.releasePressure",p:[24,14,741]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,767]}," kPa"]}]}," ",{p:[26,3,836],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,880],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,913]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1067],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1098]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1243],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1337],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1367]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],474:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,32],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,73],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,79]}," K"]}]}," ",{p:[5,5,147],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,185],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,191]}," kPa"]}]}]}," ",{p:[9,1,268],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,302],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,337],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,354]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,398]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,458]}]}]}," ",{p:[14,5,518],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,566],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,605]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,717],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,751]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,862],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,932]}]}," ",{p:[20,9,984],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1017]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1127],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1165]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],475:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 1:return"good";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,161],t:7,e:"ui-notice",f:[{p:[14,2,174],t:7,e:"ui-section",a:{label:"Reconnect"},f:[{p:[15,3,207],t:7,e:"div",a:{style:"float:right"},f:[{p:[16,4,236],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]}]}]}," ",{p:[20,1,340],t:7,e:"ui-display",a:{title:"Turbine Controller"},f:[{p:[21,2,381],t:7,e:"ui-section",a:{label:"Status"},f:[{t:4,f:[{p:[23,4,434],t:7,e:"span",a:{"class":"bad"},f:["Broken"]}],n:50,r:"data.broken",p:[22,3,411]},{t:4,n:51,f:[{p:[25,4,480],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.online"],s:"_0(_1)"},p:[25,17,493]}]},f:[{t:2,x:{r:["data.online","data.compressor_broke","data.turbine_broke"],s:'_0&&!(_1||_2)?"Online":"Offline"'},p:[25,46,522]}]}],r:"data.broken"}," ",{p:[27,3,630],t:7,e:"div",a:{style:"float:right"},f:[{p:[28,4,659],t:7,e:"ui-button",a:{icon:"power-off",action:"power-on",state:[{t:2,r:"data.broken",p:[28,57,712]}],style:[{t:2,x:{r:["data.online"],s:'_0?"selected":""'},p:[28,81,736]}]},f:["On"]}," ",{p:[29,4,789],t:7,e:"ui-button",a:{icon:"close",action:"power-off",state:[{t:2,r:"data.broken",p:[29,54,839]}],style:[{t:2,x:{r:["data.online"],s:'_0?"":"selected"'},p:[29,78,863]}]},f:["Off"]}]}," ",{t:4,f:[{p:[32,4,958],t:7,e:"br"}," [ ",{p:[33,6,968],t:7,e:"span",a:{"class":"bad"},f:["Compressor is inoperable"]}," ]"],n:50,r:"data.compressor_broke",p:[31,3,925]}," ",{t:4,f:[{p:[36,4,1062],t:7,e:"br"}," [ ",{p:[37,6,1072],t:7,e:"span",a:{"class":"bad"},f:["Turbine is inoperable"]}," ]"],n:50,r:"data.turbine_broke",p:[35,3,1032]}]}]}," ",{p:[41,1,1160],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[42,2,1189],t:7,e:"ui-section",a:{label:"Turbine Speed"},f:[{p:[43,3,1226],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.rpm"],s:'_0?"--":_1'},p:[43,9,1232]}," RPM"]}]}," ",{p:[45,2,1293],t:7,e:"ui-section",a:{label:"Internal Temp"},f:[{p:[46,3,1330],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.temp"],s:'_0?"--":_1'},p:[46,9,1336]}," K"]}]}," ",{p:[48,2,1396],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{p:[49,3,1435],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.power"],s:'_0?"--":_1'},p:[49,9,1441]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],476:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,460],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,432]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,543],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,587],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,600]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,644]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,734],t:7,e:"ui-display",f:[{p:[32,2,748],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,797]},'"}']},f:[{t:2,r:"name",p:[32,63,809]}]}," ",{t:4,f:[{p:[34,4,850],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,869]}],candystripe:0,right:0},f:[{p:[35,3,900],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,920]},": ",{t:2,r:"desc",p:[35,33,930]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,971]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1129]},'", "item": ',{t:2,r:"name",p:[37,63,1152]},', "cost": ',{t:2,r:"cost",p:[37,81,1170]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1223]}," TC"]}]}],n:52,r:"items",p:[33,2,831]}]}],n:52,r:"data.categories",p:[30,1,706]}]},e.exports=a.extend(r.exports)},{341:341}],477:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,331],t:7,e:"ui-notice",f:[{p:[17,4,347],t:7,e:"span",f:["Safety restraints disabled."]}]}],n:50,r:"data.emagged",p:[15,2,307]}," ",{t:4,f:[{p:[21,3,442],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[22,4,482],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[23,5,513]}]}," ",{p:[25,4,559],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[26,5,592]}]}," ",{p:[28,4,640],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[29,5,673],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[29,26,694]}],value:[{t:2,r:"adata.vr_avatar.health",
-p:[29,64,732]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[29,99,767]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[29,140,808]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[29,179,847]}]}]}]}],n:50,r:"data.vr_avatar",p:[20,2,416]},{t:4,n:51,f:[{p:[33,3,935],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[37,2,1031],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[38,3,1067],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[38,20,1084]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[39,4,1151]}," the VR Sleeper"]}," ",{t:4,f:[{p:[42,4,1253],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[41,3,1225]}," ",{t:4,f:[{p:[47,4,1376],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[46,3,1349]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],478:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,40],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,59]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,68]}],labelcolor:[{t:2,r:"color",p:[3,80,115]}],candystripe:0,right:0},f:[{p:[4,7,151],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,192]},'"}']},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,205]}]}," ",{p:[5,7,248],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,291]},'"}']},f:["Pulse"]}," ",{p:[6,7,328],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,372]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,385]}]}]}],n:52,r:"data.wires",p:[2,3,15]}]}," ",{t:4,f:[{p:[11,3,498],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,543],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,555]}]}],n:52,r:"data.status",p:[12,5,515]}]}],n:50,r:"data.status",p:[10,1,476]}]},e.exports=a.extend(r.exports)},{341:341}],479:[function(t,e,n){(function(e){"use strict";var n=t(341),a=e.interopRequireDefault(n);t(331),t(1),t(327),t(330);var r=t(480),i=e.interopRequireDefault(r),o=t(481),s=t(328),p=t(329),u=e.interopRequireDefault(p);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(485)),window.initialize=function(e){window.tgui=window.tgui||new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(482),text:t(486),config:n.config,data:n.data,adata:n.data}}})};var c=document.getElementById("data"),l=c.textContent,d=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(d,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var f=new u["default"]("FontAwesome");f.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,327:327,328:328,329:329,330:330,331:331,341:341,480:480,481:481,482:482,485:485,486:486,"babel/external-helpers":"babel/external-helpers"}],480:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(481),a=t(483);e.exports={components:{"ui-bar":t(342),"ui-button":t(343),"ui-display":t(344),"ui-input":t(345),"ui-linegraph":t(346),"ui-notice":t(347),"ui-section":t(349),"ui-subdisplay":t(350),"ui-tabs":t(351)},events:{enter:t(339).enter,space:t(339).space},transitions:{fade:t(340)},onconfig:function(){var e=this.get("config.interface"),n={ai_airlock:t(355),airalarm:t(356),"airalarm/back":t(357),"airalarm/modes":t(358),"airalarm/scrubbers":t(359),"airalarm/status":t(360),"airalarm/thresholds":t(361),"airalarm/vents":t(362),airlock_electronics:t(363),apc:t(364),atmos_alert:t(365),atmos_control:t(366),atmos_filter:t(367),atmos_mixer:t(368),atmos_pump:t(369),borgopanel:t(370),brig_timer:t(371),bsa:t(372),canister:t(373),cargo:t(374),cargo_express:t(375),cellular_emporium:t(376),centcom_podlauncher:t(377),chem_dispenser:t(378),chem_heater:t(379),chem_master:t(380),chem_synthesizer:t(381),clockwork_slab:t(382),codex_gigas:t(383),computer_fabricator:t(384),crayon:t(385),crew:t(386),cryo:t(387),disposal_unit:t(388),dna_vault:t(389),dogborg_sleeper:t(390),eightball:t(391),emergency_shuttle_console:t(392),engraved_message:t(393),error:t(394),"exofab - Copia":t(395),exonet_node:t(396),firealarm:t(397),gps:t(398),gulag_console:t(399),gulag_item_reclaimer:t(400),holodeck:t(401),implantchair:t(402),intellicard:t(403),keycard_auth:t(404),labor_claim_console:t(405),language_menu:t(406),launchpad_remote:t(407),mech_bay_power_console:t(408),mulebot:t(409),nanite_chamber_control:t(410),nanite_cloud_control:t(411),nanite_program_hub:t(412),nanite_programmer:t(413),nanite_remote:t(414),notificationpanel:t(415),ntnet_relay:t(416),ntos_ai_restorer:t(417),ntos_card:t(418),ntos_configuration:t(419),ntos_file_manager:t(420),ntos_main:t(421),ntos_net_chat:t(422),ntos_net_dos:t(423),ntos_net_downloader:t(424),ntos_net_monitor:t(425),ntos_net_transfer:t(426),ntos_power_monitor:t(427),ntos_revelation:t(428),ntos_station_alert:t(429),ntos_supermatter_monitor:t(430),ntosheader:t(431),nuclear_bomb:t(432),operating_computer:t(433),ore_redemption_machine:t(434),pandemic:t(435),personal_crafting:t(436),portable_pump:t(437),portable_scrubber:t(438),power_monitor:t(439),radio:t(440),rdconsole:t(441),"rdconsole/circuit":t(442),"rdconsole/designview":t(443),"rdconsole/destruct":t(444),"rdconsole/diskopsdesign":t(445),"rdconsole/diskopstech":t(446),"rdconsole/nodeview":t(447),"rdconsole/protolathe":t(448),"rdconsole/rdheader":t(449),"rdconsole/settings":t(450),"rdconsole/techweb":t(451),reagentgrinder:t(452),rpd:t(453),"rpd/colorsel":t(454),"rpd/dirsel":t(455),sat_control:t(456),scrubbing_types:t(457),shuttle_manipulator:t(458),"shuttle_manipulator/modification":t(459),"shuttle_manipulator/status":t(460),"shuttle_manipulator/templates":t(461),sleeper:t(462),slime_swap_body:t(463),smartvend:t(464),smes:t(465),smoke_machine:t(466),solar_control:t(467),space_heater:t(468),spawners_menu:t(469),station_alert:t(470),suit_storage_unit:t(471),tank_dispenser:t(472),tanks:t(473),thermomachine:t(474),turbine_computer:t(475),uplink:t(476),vr_sleeper:t(477),wires:t(478)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1819],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1829]}]}," ",{p:[57,1,1859],t:7,e:"main",f:[{p:[58,3,1868],t:7,e:"warnings"}," ",{p:[59,3,1882],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1929],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1903]}]},r.exports.components=r.exports.components||{};var i={warnings:t(354),titlebar:t(353),resize:t(348)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{339:339,340:340,341:341,342:342,343:343,344:344,345:345,346:346,347:347,348:348,349:349,350:350,351:351,353:353,354:354,355:355,356:356,357:357,358:358,359:359,360:360,361:361,362:362,363:363,364:364,365:365,366:366,367:367,368:368,369:369,370:370,371:371,372:372,373:373,374:374,375:375,376:376,377:377,378:378,379:379,380:380,381:381,382:382,383:383,384:384,385:385,386:386,387:387,388:388,389:389,390:390,391:391,392:392,393:393,394:394,395:395,396:396,397:397,398:398,399:399,400:400,401:401,402:402,403:403,404:404,405:405,406:406,407:407,408:408,409:409,410:410,411:411,412:412,413:413,414:414,415:415,416:416,417:417,418:418,419:419,420:420,421:421,422:422,423:423,424:424,425:425,426:426,427:427,428:428,429:429,430:430,431:431,432:432,433:433,434:434,435:435,436:436,437:437,438:438,439:439,440:440,441:441,442:442,443:443,444:444,445:445,446:446,447:447,448:448,449:449,450:450,451:451,452:452,453:453,454:454,455:455,456:456,457:457,458:458,459:459,460:460,461:461,462:462,463:463,464:464,465:465,466:466,467:467,468:468,469:469,470:470,471:471,472:472,473:473,474:474,475:475,476:476,477:477,478:478,481:481,483:483}],481:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],482:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],483:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(481)},{481:481}],484:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;a||p.textContent.toLowerCase().includes(e)?p.style.display="":p.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],485:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],486:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var p=Array(o),u=0;o>u;u++)p[u]=arguments[u+3];n.children=p}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(p){r("throw",p)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(p){return void n(p)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);ethis.end?(this.step&&this.step(1),this.complete&&this.complete(1),!1):(e=t-this.start,n=this.easing(e/this.duration),this.step&&this.step(n),!0):!1},stop:function(){this.abort&&this.abort(),this.running=!1}};var wf,kf,Sf,Ef,Cf,Pf,Af,Of,Tf=xf,Rf=RegExp("^-(?:"+ro.join("|")+")-"),Mf=function(t){return t.replace(Rf,"")},Lf=RegExp("^(?:"+ro.join("|")+")([A-Z])"),jf=function(t){var e;return t?(Lf.test(t)&&(t="-"+t),e=t.replace(/[A-Z]/g,function(t){return"-"+t.toLowerCase()})):""},Df={},Nf={};Xi?(kf=co("div").style,function(){void 0!==kf.transition?(Sf="transition",Ef="transitionend",Cf=!0):void 0!==kf.webkitTransition?(Sf="webkitTransition",Ef="webkitTransitionEnd",Cf=!0):Cf=!1}(),Sf&&(Pf=Sf+"Duration",Af=Sf+"Property",Of=Sf+"TimingFunction"),wf=function(t,e,n,a,r){setTimeout(function(){var i,o,s,p,u;p=function(){o&&s&&(t.root.fire(t.name+":end",t.node,t.isIntro),r())},i=(t.node.namespaceURI||"")+t.node.tagName,t.node.style[Af]=a.map(bf).map(jf).join(","),t.node.style[Of]=jf(n.easing||"linear"),t.node.style[Pf]=n.duration/1e3+"s",u=function(e){var n;n=a.indexOf(mf(Mf(e.propertyName))),-1!==n&&a.splice(n,1),a.length||(t.node.removeEventListener(Ef,u,!1),s=!0,p())},t.node.addEventListener(Ef,u,!1),setTimeout(function(){for(var r,c,l,d,f,h=a.length,g=[];h--;)d=a[h],r=i+d,Cf&&!Nf[r]&&(t.node.style[bf(d)]=e[d],Df[r]||(c=t.getStyle(d),Df[r]=t.getStyle(d)!=e[d],Nf[r]=!Df[r],Nf[r]&&(t.node.style[bf(d)]=c))),(!Cf||Nf[r])&&(void 0===c&&(c=t.getStyle(d)),l=a.indexOf(d),-1===l?m("Something very strange happened with transitions. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!",{node:t.node}):a.splice(l,1),f=/[^\d]*$/.exec(e[d])[0],g.push({name:bf(d),interpolator:Vo(parseFloat(c),parseFloat(e[d])),suffix:f}));g.length?new Tf({root:t.root,duration:n.duration,easing:mf(n.easing||""),step:function(e){var n,a;for(a=g.length;a--;)n=g[a],t.node.style[n.name]=n.interpolator(e)+n.suffix},complete:function(){o=!0,p()}}):o=!0,a.length||(t.node.removeEventListener(Ef,u,!1),s=!0,p())},0)},n.delay||0)}):wf=null;var Ff,If,Bf,Vf,qf,Uf=wf;if("undefined"!=typeof document){if(Ff="hidden",qf={},Ff in document)Bf="";else for(Vf=ro.length;Vf--;)If=ro[Vf],Ff=If+"Hidden",Ff in document&&(Bf=If);void 0!==Bf?(document.addEventListener(Bf+"visibilitychange",qa),qa()):("onfocusout"in document?(document.addEventListener("focusout",Ua),document.addEventListener("focusin",Ga)):(window.addEventListener("pagehide",Ua),window.addEventListener("blur",Ua),window.addEventListener("pageshow",Ga),window.addEventListener("focus",Ga)),qf.hidden=!1)}var Gf,zf,Wf,Hf=qf;Xi?(zf=window.getComputedStyle||Po.getComputedStyle,Gf=function(t,e,n){var a,r=this;if(4===arguments.length)throw Error("t.animateStyle() returns a promise - use .then() instead of passing a callback");if(Hf.hidden)return this.setStyle(t,e),Wf||(Wf=us.resolve());"string"==typeof t?(a={},a[t]=e):(a=t,n=e),n||(g('The "%s" transition does not supply an options object to `t.animateStyle()`. This will break in a future version of Ractive. For more info see https://github.com/RactiveJS/Ractive/issues/340',this.name),n=this);var i=new us(function(t){var e,i,o,s,p,u,c;if(!n.duration)return r.setStyle(a),void t();for(e=Object.keys(a),i=[],o=zf(r.node),p={},u=e.length;u--;)c=e[u],s=o[bf(c)],"0px"===s&&(s=0),s!=a[c]&&(i.push(c),r.node.style[bf(c)]=s);return i.length?void Uf(r,a,n,i,t):void t()});return i}):Gf=null;var Kf=Gf,Qf=function(t,e){return"number"==typeof t?t={duration:t}:"string"==typeof t?t="slow"===t?{duration:600}:"fast"===t?{duration:200}:{duration:400}:t||(t={}),r({},t,e)},Yf=za,$f=function(t,e,n){this.init(t,e,n)};$f.prototype={init:hf,start:Yf,getStyle:yf,setStyle:_f,animateStyle:Kf,processParams:Qf};var Jf,Xf,Zf=$f,th=Ha;Jf=function(){var t=this.node,e=this.fragment.toString(!1);if(window&&window.appearsToBeIELessEqual8&&(t.type="text/css"),t.styleSheet)t.styleSheet.cssText=e;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(e))}},Xf=function(){this.node.type&&"text/javascript"!==this.node.type||m("Script tag was updated. This does not cause the code to be re-evaluated!",{ractive:this.root}),this.node.text=this.fragment.toString(!1)};var eh=function(){var t,e;return this.template.y?"":(t="<"+this.template.e,t+=this.attributes.map(Xa).join("")+this.conditionalAttributes.map(Xa).join(""),"option"===this.name&&$a(this)&&(t+=" selected"),"input"===this.name&&Ja(this)&&(t+=" checked"),t+=">","textarea"===this.name&&void 0!==this.getAttribute("value")?t+=Se(this.getAttribute("value")):void 0!==this.getAttribute("contenteditable")&&(t+=this.getAttribute("value")||""),this.fragment&&(e="script"!==this.name&&"style"!==this.name,t+=this.fragment.toString(e)),ic.test(this.template.e)||(t+=""+this.template.e+">"),t)},nh=Za,ah=tr,rh=function(t){this.init(t)};rh.prototype={bubble:Tl,detach:Rl,find:Ml,findAll:Ll,findAllComponents:jl,findComponent:Dl,findNextNode:Nl,firstNode:Fl,getAttribute:Il,init:df,rebind:ff,render:th,toString:eh,unbind:nh,unrender:ah};var ih=rh,oh=/^\s*$/,sh=/^\s*/,ph=function(t){var e,n,a,r;return e=t.split("\n"),n=e[0],void 0!==n&&oh.test(n)&&e.shift(),a=D(e),void 0!==a&&oh.test(a)&&e.pop(),r=e.reduce(nr,null),r&&(t=e.map(function(t){return t.replace(r,"")}).join("\n")),t},uh=ar,ch=function(t,e){var n;return e?n=t.split("\n").map(function(t,n){return n?e+t:t}).join("\n"):t},lh='Could not find template for partial "%s"',dh=function(t){var e,n;e=this.parentFragment=t.parentFragment,this.root=e.root,this.type=Au,this.index=t.index,this.name=t.template.r,this.rendered=!1,this.fragment=this.fragmentToRender=this.fragmentToUnrender=null,Gc.init(this,t),this.keypath||((n=uh(this.root,this.name,e))?(_c.call(this),this.isNamed=!0,this.setTemplate(n)):g(lh,this.name))};dh.prototype={bubble:function(){this.parentFragment.bubble()},detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},firstNode:function(){return this.fragment.firstNode()},findNextNode:function(){return this.parentFragment.findNextNode(this)},getPartialName:function(){return this.isNamed&&this.name?this.name:void 0===this.value?this.name:this.value},getValue:function(){return this.fragment.getValue()},rebind:function(t,e){this.isNamed||Uc.call(this,t,e),this.fragment&&this.fragment.rebind(t,e)},render:function(){return this.docFrag=document.createDocumentFragment(),this.update(),this.rendered=!0,this.docFrag},resolve:Gc.resolve,setValue:function(t){var e;(void 0===t||t!==this.value)&&(void 0!==t&&(e=uh(this.root,""+t,this.parentFragment)),!e&&this.name&&(e=uh(this.root,this.name,this.parentFragment))&&(_c.call(this),this.isNamed=!0),e||g(lh,this.name,{ractive:this.root}),this.value=t,this.setTemplate(e||[]),this.bubble(),this.rendered&&bs.addView(this))},setTemplate:function(t){this.fragment&&(this.fragment.unbind(),this.rendered&&(this.fragmentToUnrender=this.fragment)),this.fragment=new rg({template:t,root:this.root,owner:this,pElement:this.parentFragment.pElement}),this.fragmentToRender=this.fragment},toString:function(t){var e,n,a,r;return e=this.fragment.toString(t),n=this.parentFragment.items[this.index-1],n&&n.type===ku?(a=n.text.split("\n").pop(),(r=/^\s+$/.exec(a))?ch(e,r[0]):e):e},unbind:function(){this.isNamed||_c.call(this),this.fragment&&this.fragment.unbind()},unrender:function(t){this.rendered&&(this.fragment&&this.fragment.unrender(t),this.rendered=!1)},update:function(){var t,e;this.fragmentToUnrender&&(this.fragmentToUnrender.unrender(!0),this.fragmentToUnrender=null),this.fragmentToRender&&(this.docFrag.appendChild(this.fragmentToRender.render()),this.fragmentToRender=null),this.rendered&&(t=this.parentFragment.getNode(),e=this.parentFragment.findNextNode(this),t.insertBefore(this.docFrag,e))}};var fh,hh,mh,gh=dh,vh=pr,bh=ur,yh=new is("detach"),_h=cr,xh=lr,wh=dr,kh=fr,Sh=hr,Eh=mr,Ch=function(t,e,n,a){var r=t.root,i=t.keypath;a?r.viewmodel.smartUpdate(i,e,a):r.viewmodel.mark(i)},Ph=[],Ah=["pop","push","reverse","shift","sort","splice","unshift"];Ah.forEach(function(t){var e=function(){for(var e=arguments.length,n=Array(e),a=0;e>a;a++)n[a]=arguments[a];var r,i,o,s;for(r=bp(this,t,n),i=Array.prototype[t].apply(this,arguments),bs.start(),this._ractive.setting=!0,s=this._ractive.wrappers.length;s--;)o=this._ractive.wrappers[s],bs.addRactive(o.root),Ch(o,this,t,r);return bs.end(),this._ractive.setting=!1,i};Eo(Ph,t,{value:e})}),fh={},fh.__proto__?(hh=function(t){t.__proto__=Ph},mh=function(t){t.__proto__=Array.prototype}):(hh=function(t){var e,n;for(e=Ah.length;e--;)n=Ah[e],Eo(t,n,{value:Ph[n],configurable:!0})},mh=function(t){var e;for(e=Ah.length;e--;)delete t[Ah[e]]}),hh.unpatch=mh;var Oh,Th,Rh,Mh=hh;Oh={filter:function(t){return i(t)&&(!t._ractive||!t._ractive.setting)},wrap:function(t,e,n){return new Th(t,e,n)}},Th=function(t,e,n){this.root=t,this.value=e,this.keypath=S(n),e._ractive||(Eo(e,"_ractive",{value:{wrappers:[],instances:[],setting:!1},configurable:!0}),Mh(e)),e._ractive.instances[t._guid]||(e._ractive.instances[t._guid]=0,e._ractive.instances.push(t)),e._ractive.instances[t._guid]+=1,e._ractive.wrappers.push(this)},Th.prototype={get:function(){return this.value},teardown:function(){var t,e,n,a,r;if(t=this.value,e=t._ractive,n=e.wrappers,a=e.instances,e.setting)return!1;if(r=n.indexOf(this),-1===r)throw Error(Rh);if(n.splice(r,1),n.length){if(a[this.root._guid]-=1,!a[this.root._guid]){if(r=a.indexOf(this.root),-1===r)throw Error(Rh);a.splice(r,1)}}else delete t._ractive,Mh.unpatch(this.value)}},Rh="Something went wrong in a rather interesting way";var Lh,jh,Dh=Oh,Nh=/^\s*[0-9]+\s*$/,Fh=function(t){return Nh.test(t)?[]:{}};try{Object.defineProperty({},"test",{value:0}),Lh={filter:function(t,e,n){var a,r;return e?(e=S(e),(a=n.viewmodel.wrapped[e.parent.str])&&!a.magic?!1:(r=n.viewmodel.get(e.parent),i(r)&&/^[0-9]+$/.test(e.lastKey)?!1:r&&("object"==typeof r||"function"==typeof r))):!1},wrap:function(t,e,n){return new jh(t,e,n)}},jh=function(t,e,n){var a,r,i;return n=S(n),this.magic=!0,this.ractive=t,this.keypath=n,this.value=e,this.prop=n.lastKey,a=n.parent,this.obj=a.isRoot?t.viewmodel.data:t.viewmodel.get(a),r=this.originalDescriptor=Object.getOwnPropertyDescriptor(this.obj,this.prop),r&&r.set&&(i=r.set._ractiveWrappers)?void(-1===i.indexOf(this)&&i.push(this)):void gr(this,e,r)},jh.prototype={get:function(){return this.value},reset:function(t){return this.updating?void 0:(this.updating=!0,this.obj[this.prop]=t,bs.addRactive(this.ractive),this.ractive.viewmodel.mark(this.keypath,{keepExistingWrapper:!0}),this.updating=!1,!0)},set:function(t,e){this.updating||(this.obj[this.prop]||(this.updating=!0,this.obj[this.prop]=Fh(t),this.updating=!1),this.obj[this.prop][t]=e)},teardown:function(){var t,e,n,a,r;return this.updating?!1:(t=Object.getOwnPropertyDescriptor(this.obj,this.prop),e=t&&t.set,void(e&&(a=e._ractiveWrappers,r=a.indexOf(this),-1!==r&&a.splice(r,1),a.length||(n=this.obj[this.prop],Object.defineProperty(this.obj,this.prop,this.originalDescriptor||{writable:!0,enumerable:!0,configurable:!0}),this.obj[this.prop]=n))))}}}catch(Ao){Lh=!1}var Ih,Bh,Vh=Lh;Vh&&(Ih={filter:function(t,e,n){return Vh.filter(t,e,n)&&Dh.filter(t)},wrap:function(t,e,n){return new Bh(t,e,n)}},Bh=function(t,e,n){this.value=e,this.magic=!0,this.magicWrapper=Vh.wrap(t,e,n),this.arrayWrapper=Dh.wrap(t,e,n)},Bh.prototype={get:function(){return this.value},teardown:function(){this.arrayWrapper.teardown(),this.magicWrapper.teardown()},reset:function(t){return this.magicWrapper.reset(t)}});var qh=Ih,Uh=vr,Gh={},zh=_r,Wh=xr,Hh=Sr,Kh=Or,Qh=Tr,Yh=function(t,e){this.computation=t,this.viewmodel=t.viewmodel,this.ref=e,this.root=this.viewmodel.ractive,this.parentFragment=this.root.component&&this.root.component.parentFragment};Yh.prototype={resolve:function(t){this.computation.softDeps.push(t),this.computation.unresolvedDeps[t.str]=null,this.viewmodel.register(t,this.computation,"computed")}};var $h=Yh,Jh=function(t,e){this.key=t,this.getter=e.getter,this.setter=e.setter,this.hardDeps=e.deps||[],this.softDeps=[],this.unresolvedDeps={},this.depValues={},this._dirty=this._firstRun=!0};Jh.prototype={constructor:Jh,init:function(t){var e,n=this;this.viewmodel=t,this.bypass=!0,e=t.get(this.key),t.clearCache(this.key.str),this.bypass=!1,this.setter&&void 0!==e&&this.set(e),this.hardDeps&&this.hardDeps.forEach(function(e){return t.register(e,n,"computed")})},invalidate:function(){this._dirty=!0},get:function(){var t,e,n=this,a=!1;if(this.getting){var r="The "+this.key.str+" computation indirectly called itself. This probably indicates a bug in the computation. It is commonly caused by `array.sort(...)` - if that's the case, clone the array first with `array.slice().sort(...)`";return h(r),this.value}if(this.getting=!0,this._dirty){if(this._firstRun||!this.hardDeps.length&&!this.softDeps.length?a=!0:[this.hardDeps,this.softDeps].forEach(function(t){var e,r,i;if(!a)for(i=t.length;i--;)if(e=t[i],r=n.viewmodel.get(e),!s(r,n.depValues[e.str]))return n.depValues[e.str]=r,void(a=!0)}),a){this.viewmodel.capture();try{this.value=this.getter()}catch(i){m('Failed to compute "%s"',this.key.str),d(i.stack||i),this.value=void 0}t=this.viewmodel.release(),e=this.updateDependencies(t),e&&[this.hardDeps,this.softDeps].forEach(function(t){t.forEach(function(t){n.depValues[t.str]=n.viewmodel.get(t)})})}this._dirty=!1}return this.getting=this._firstRun=!1,this.value},set:function(t){if(this.setting)return void(this.value=t);if(!this.setter)throw Error("Computed properties without setters are read-only. (This may change in a future version of Ractive!)");this.setter(t)},updateDependencies:function(t){var e,n,a,r,i;for(n=this.softDeps,e=n.length;e--;)a=n[e],-1===t.indexOf(a)&&(r=!0,this.viewmodel.unregister(a,this,"computed"));for(e=t.length;e--;)a=t[e],-1!==n.indexOf(a)||this.hardDeps&&-1!==this.hardDeps.indexOf(a)||(r=!0,Rr(this.viewmodel,a)&&!this.unresolvedDeps[a.str]?(i=new $h(this,a.str),t.splice(e,1),this.unresolvedDeps[a.str]=i,bs.addUnresolved(i)):this.viewmodel.register(a,this,"computed"));return r&&(this.softDeps=t.slice()),r}};var Xh=Jh,Zh=Mr,tm={FAILED_LOOKUP:!0},em=Lr,nm={},am=Dr,rm=Nr,im=function(t,e){this.localKey=t,this.keypath=e.keypath,this.origin=e.origin,this.deps=[],this.unresolved=[],this.resolved=!1};im.prototype={forceResolution:function(){this.keypath=this.localKey,this.setup()},get:function(t,e){return this.resolved?this.origin.get(this.map(t),e):void 0},getValue:function(){return this.keypath?this.origin.get(this.keypath):void 0},initViewmodel:function(t){this.local=t,this.setup()},map:function(t){return void 0===typeof this.keypath?this.localKey:t.replace(this.localKey,this.keypath)},register:function(t,e,n){this.deps.push({keypath:t,dep:e,group:n}),this.resolved&&this.origin.register(this.map(t),e,n)},resolve:function(t){void 0!==this.keypath&&this.unbind(!0),this.keypath=t,this.setup()},set:function(t,e){this.resolved||this.forceResolution(),this.origin.set(this.map(t),e)},setup:function(){var t=this;void 0!==this.keypath&&(this.resolved=!0,this.deps.length&&(this.deps.forEach(function(e){var n=t.map(e.keypath);if(t.origin.register(n,e.dep,e.group),e.dep.setValue)e.dep.setValue(t.origin.get(n));else{if(!e.dep.invalidate)throw Error("An unexpected error occurred. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");e.dep.invalidate()}}),this.origin.mark(this.keypath)))},setValue:function(t){if(!this.keypath)throw Error("Mapping does not have keypath, cannot set value. Please raise an issue at https://github.com/ractivejs/ractive/issues - thanks!");this.origin.set(this.keypath,t)},unbind:function(t){var e=this;t||delete this.local.mappings[this.localKey],this.resolved&&(this.deps.forEach(function(t){e.origin.unregister(e.map(t.keypath),t.dep,t.group)}),this.tracker&&this.origin.unregister(this.keypath,this.tracker))},unregister:function(t,e,n){var a,r;if(this.resolved){for(a=this.deps,r=a.length;r--;)if(a[r].dep===e){a.splice(r,1);break}this.origin.unregister(this.map(t),e,n)}}};var om=Fr,sm=function(t,e){var n,a,r,i;return n={},a=0,r=t.map(function(t,r){var o,s,p;s=a,p=e.length;do{if(o=e.indexOf(t,s),-1===o)return i=!0,-1;s=o+1}while(n[o]&&p>s);return o===a&&(a+=1),o!==r&&(i=!0),n[o]=!0,o})},pm=Ir,um={},cm=qr,lm=Gr,dm=zr,fm=Wr,hm=Kr,mm={implicit:!0},gm={noCascade:!0},vm=Yr,bm=$r,ym=function(t){var e,n,a=t.adapt,r=t.data,i=t.ractive,o=t.computed,s=t.mappings;this.ractive=i,this.adaptors=a,this.onchange=t.onchange,this.cache={},this.cacheMap=So(null),this.deps={computed:So(null),"default":So(null)},this.depsMap={computed:So(null),"default":So(null)},this.patternObservers=[],this.specials=So(null),this.wrapped=So(null),this.computations=So(null),this.captureGroups=[],this.unresolvedImplicitDependencies=[],this.changes=[],this.implicitChanges={},this.noCascade={},this.data=r,this.mappings=So(null);for(e in s)this.map(S(e),s[e]);if(r)for(e in r)(n=this.mappings[e])&&void 0===n.getValue()&&n.setValue(r[e]);for(e in o)s&&e in s&&l("Cannot map to a computed property ('%s')",e),this.compute(S(e),o[e]);this.ready=!0};ym.prototype={adapt:Uh,applyChanges:Hh,capture:Kh,clearCache:Qh,compute:Zh,get:em,init:am,map:rm,mark:om,merge:pm,register:cm,release:lm,reset:dm,set:fm,smartUpdate:hm,teardown:vm,unregister:bm};var _m=ym;Xr.prototype={constructor:Xr,begin:function(t){this.inProcess[t._guid]=!0},end:function(t){var e=t.parent;e&&this.inProcess[e._guid]?Zr(this.queue,e).push(t):ti(this,t),delete this.inProcess[t._guid]}};var xm=Xr,wm=ei,km=/\$\{([^\}]+)\}/g,Sm=new is("construct"),Em=new is("config"),Cm=new xm("init"),Pm=0,Am=["adaptors","components","decorators","easing","events","interpolators","partials","transitions"],Om=ii,Tm=ci;ci.prototype={bubble:function(){this.dirty||(this.dirty=!0,bs.addView(this))},update:function(){this.callback(this.fragment.getValue()),this.dirty=!1},rebind:function(t,e){this.fragment.rebind(t,e)},unbind:function(){this.fragment.unbind()}};var Rm=function(t,e,n,r,o){var s,p,u,c,l,d,f={},h={},g={},v=[];for(p=t.parentFragment,u=t.root,o=o||{},a(f,o),o.content=r||[],f[""]=o.content,e.defaults.el&&m("The <%s/> component has a default `el` property; it has been disregarded",t.name),c=p;c;){if(c.owner.type===Mu){l=c.owner.container;break}c=c.parent}return n&&Object.keys(n).forEach(function(e){var a,r,o=n[e];if("string"==typeof o)a=dc(o),h[e]=a?a.value:o;else if(0===o)h[e]=!0;else{if(!i(o))throw Error("erm wut");di(o)?(g[e]={origin:t.root.viewmodel,keypath:void 0},r=li(t,o[0],function(t){t.isSpecial?d?s.set(e,t.value):(h[e]=t.value,delete g[e]):d?s.viewmodel.mappings[e].resolve(t):g[e].keypath=t})):r=new Tm(t,o,function(t){d?s.set(e,t):h[e]=t}),v.push(r)}}),s=So(e.prototype),Om(s,{el:null,append:!0,data:h,partials:o,magic:u.magic||e.defaults.magic,modifyArrays:u.modifyArrays,adapt:u.adapt},{parent:u,component:t,container:l,mappings:g,inlinePartials:f,cssIds:p.cssIds}),d=!0,t.resolvers=v,s},Mm=fi,Lm=function(t){var e,n;for(e=t.root;e;)(n=e._liveComponentQueries["_"+t.name])&&n.push(t.instance),e=e.parent},jm=mi,Dm=gi,Nm=vi,Fm=bi,Im=yi,Bm=new is("teardown"),Vm=xi,qm=function(t,e){this.init(t,e)};qm.prototype={detach:bh,find:_h,findAll:xh,findAllComponents:wh,findComponent:kh,findNextNode:Sh,firstNode:Eh,init:jm,rebind:Dm,render:Nm,toString:Fm,unbind:Im,unrender:Vm};var Um=qm,Gm=function(t){this.type=Ou,this.value=t.template.c};Gm.prototype={detach:vc,firstNode:function(){return this.node},render:function(){return this.node||(this.node=document.createComment(this.value)),this.node},toString:function(){return""},unrender:function(t){t&&this.node.parentNode.removeChild(this.node)}};var zm=Gm,Wm=function(t){var e,n;this.type=Mu,this.container=e=t.parentFragment.root,this.component=n=e.component,this.container=e,this.containerFragment=t.parentFragment,this.parentFragment=n.parentFragment;var a=this.name=t.template.n||"",r=e._inlinePartials[a];r||(m('Could not find template for partial "'+a+'"',{ractive:t.root}),r=[]),this.fragment=new rg({owner:this,root:e.parent,template:r,pElement:this.containerFragment.pElement}),i(n.yielders[a])?n.yielders[a].push(this):n.yielders[a]=[this],bs.scheduleTask(function(){if(n.yielders[a].length>1)throw Error("A component template can only have one {{yield"+(a?" "+a:"")+"}} declaration at a time")})};Wm.prototype={detach:function(){return this.fragment.detach()},find:function(t){return this.fragment.find(t)},findAll:function(t,e){return this.fragment.findAll(t,e)},findComponent:function(t){return this.fragment.findComponent(t)},findAllComponents:function(t,e){return this.fragment.findAllComponents(t,e)},findNextNode:function(){return this.containerFragment.findNextNode(this)},firstNode:function(){return this.fragment.firstNode()},getValue:function(t){return this.fragment.getValue(t)},render:function(){return this.fragment.render()},unbind:function(){this.fragment.unbind()},unrender:function(t){this.fragment.unrender(t),N(this.component.yielders[this.name],this)},rebind:function(t,e){this.fragment.rebind(t,e)},toString:function(){return""+this.fragment}};var Hm=Wm,Km=function(t){this.declaration=t.template.a};Km.prototype={init:ko,render:ko,unrender:ko,teardown:ko,toString:function(){return""}};var Qm=Km,Ym=wi,$m=Si,Jm=Ei,Xm=Ci,Zm=Oi,tg=Ri,eg=function(t){this.init(t)};eg.prototype={bubble:cu,detach:lu,find:du,findAll:fu,findAllComponents:hu,findComponent:mu,findNextNode:gu,firstNode:vu,getArgsList:hc,getNode:mc,getValue:gc,init:Ym,rebind:$m,registerIndexRef:function(t){var e=this.registeredIndexRefs;-1===e.indexOf(t)&&e.push(t)},render:Jm,toString:Xm,unbind:Zm,unregisterIndexRef:function(t){var e=this.registeredIndexRefs;e.splice(e.indexOf(t),1)},unrender:tg};var ng,ag,rg=eg,ig=Mi,og=["template","partials","components","decorators","events"],sg=new is("reset"),pg=function(t,e){function n(e,a,r){r&&r.partials[t]||e.forEach(function(e){e.type===Au&&e.getPartialName()===t&&a.push(e),e.fragment&&n(e.fragment.items,a,r),i(e.fragments)?n(e.fragments,a,r):i(e.items)?n(e.items,a,r):e.type===Ru&&e.instance&&n(e.instance.fragment.items,a,e.instance),e.type===Pu&&(i(e.attributes)&&n(e.attributes,a,r),i(e.conditionalAttributes)&&n(e.conditionalAttributes,a,r))})}var a,r=[];return n(this.fragment.items,r),this.partials[t]=e,a=bs.start(this,!0),r.forEach(function(e){e.value=void 0,e.setValue(t)}),bs.end(),a},ug=Li,cg=_p("reverse"),lg=ji,dg=_p("shift"),fg=_p("sort"),hg=_p("splice"),mg=Ni,gg=Fi,vg=new is("teardown"),bg=Bi,yg=Vi,_g=qi,xg=new is("unrender"),wg=_p("unshift"),kg=Ui,Sg=new is("update"),Eg=Gi,Cg={add:Zo,animate:Ss,detach:Cs,find:As,findAll:Fs,findAllComponents:Is,findComponent:Bs,findContainer:Vs,findParent:qs,fire:Ws,get:Hs,insert:Qs,merge:$s,observe:lp,observeOnce:dp,off:mp,on:gp,once:vp,pop:xp,push:wp,render:Tp,reset:ig,resetPartial:pg,resetTemplate:ug,reverse:cg,set:lg,shift:dg,sort:fg,splice:hg,subtract:mg,teardown:gg,toggle:bg,toHTML:yg,toHtml:yg,unrender:_g,unshift:wg,update:kg,updateModel:Eg},Pg=function(t,e,n){return n||Wi(t,e)?function(){var n,a="_super"in this,r=this._super;return this._super=e,n=t.apply(this,arguments),a&&(this._super=r),n}:t},Ag=Hi,Og=$i,Tg=function(t){var e,n,a={};return t&&(e=t._ractive)?(a.ractive=e.root,a.keypath=e.keypath.str,a.index={},(n=Oc(e.proxy.parentFragment))&&(a.index=Oc.resolve(n)),a):a};ng=function(t){return this instanceof ng?void Om(this,t):new ng(t)},ag={DEBUG:{writable:!0,value:!0},DEBUG_PROMISES:{writable:!0,value:!0},extend:{value:Og},getNodeInfo:{value:Tg},parse:{value:Hp},Promise:{value:us},svg:{value:ao},magic:{value:eo},VERSION:{value:"0.7.3"},adaptors:{writable:!0,value:{}},components:{writable:!0,value:{}},decorators:{writable:!0,value:{}},easing:{writable:!0,value:po},events:{writable:!0,value:{}},interpolators:{writable:!0,value:Uo},partials:{writable:!0,value:{}},transitions:{writable:!0,value:{}}},Co(ng,ag),ng.prototype=a(Cg,so),ng.prototype.constructor=ng,ng.defaults=ng.prototype;var Rg="function";if(typeof Date.now!==Rg||typeof String.prototype.trim!==Rg||typeof Object.keys!==Rg||typeof Array.prototype.indexOf!==Rg||typeof Array.prototype.forEach!==Rg||typeof Array.prototype.map!==Rg||typeof Array.prototype.filter!==Rg||"undefined"!=typeof window&&typeof window.addEventListener!==Rg)throw Error("It looks like you're attempting to use Ractive.js in an older browser. You'll need to use one of the 'legacy builds' in order to continue - see http://docs.ractivejs.org/latest/legacy-builds for more information.");var Mg=ng;return Mg})},{}],342:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.observe("value",function(e,n,a){var r=t.get(),i=r.min,o=r.max,s=Math.clamp(i,o,e);t.animate("percentage",Math.round((s-i)/(o-i)*100))})}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,305],t:7,e:"div",a:{"class":"bar"},f:[{p:[14,3,326],t:7,e:"div",a:{"class":["barFill ",{t:2,r:"state",p:[14,23,346]}],style:["width: ",{t:2,r:"percentage",p:[14,48,371]},"%"]}}," ",{p:[15,3,398],t:7,e:"span",a:{"class":"barText"},f:[{t:16,p:[15,25,420]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],343:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(482),a=t(481);e.exports={computed:{clickable:function(){return!this.get("enabled")||this.get("state")&&"toggle"!=this.get("state")?!1:!0},enabled:function(){return this.get("config.status")===n.UI_INTERACTIVE?!0:!1},styles:function(){var t="";if(this.get("class")&&(t+=" "+this.get("class")),this.get("tooltip-side")&&(t=" tooltip-"+this.get("tooltip-side")),this.get("grid")&&(t+=" gridable"),this.get("enabled")){var e=this.get("state"),n=this.get("style");return e?"inactive "+e+" "+t:"active normal "+n+" "+t}return"inactive disabled "+t}},oninit:function(){var t=this;this.on("press",function(e){var n=t.get(),r=n.action,i=n.params;(0,a.act)(t.get("config.ref"),r,i),e.node.blur()})},data:{iconStackToHTML:function(t){var e="",n=t.split(",");if(n.length){e+='';for(var a=n,r=Array.isArray(a),i=0,a=r?a:a[Symbol.iterator]();;){var o;if(r){if(i>=a.length)break;o=a[i++]}else{if(i=a.next(),i.done)break;o=i.value}var s=o,p=/([\w\-]+)\s*(\dx)/g,u=p.exec(s),c=u[1],l=u[2];e+=' '}}return e&&(e+=" "),e}}}}(r),r.exports.template={v:3,t:[" ",{p:[70,1,2019],t:7,e:"span",a:{"class":["button ",{t:2,r:"styles",p:[70,21,2039]}],unselectable:"on","data-tooltip":[{t:2,r:"tooltip",p:[73,17,2124]}]},m:[{t:4,f:["tabindex='0'"],r:"clickable",p:[72,3,2075]}],v:{"mouseover-mousemove":"hover",mouseleave:"unhover","click-enter":{n:[{t:4,f:["press"],r:"clickable",p:[76,19,2217]}],d:[]}},f:[{t:4,f:[{p:[78,5,2265],t:7,e:"i",a:{"class":["fa fa-",{t:2,r:"icon",p:[78,21,2281]}]}}],n:50,r:"icon",p:[77,3,2247]}," ",{t:4,f:[{t:3,x:{r:["iconStackToHTML","icon_stack"],s:"_0(_1)"},p:[81,6,2335]}],n:50,r:"icon_stack",p:[80,3,2310]}," ",{t:16,p:[83,3,2383]}]}]},e.exports=a.extend(r.exports)},{341:341,481:481,482:482}],344:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"display"},f:[{t:4,f:[{p:[3,5,44],t:7,e:"header",f:[{p:[4,7,60],t:7,e:"h3",f:[{t:2,r:"title",p:[4,11,64]}]}," ",{t:4,f:[{p:[6,9,110],t:7,e:"div",a:{"class":"buttonRight"},f:[{t:16,n:"button",p:[6,34,135]}]}],n:50,r:"button",p:[5,7,86]}]}],n:50,r:"title",p:[2,3,25]}," ",{p:[10,3,202],t:7,e:"article",f:[{t:16,p:[11,5,217]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],345:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.on("clear",function(){t.set("value",""),t.find("input").focus()})}}}(r),r.exports.template={v:3,t:[" ",{p:[12,1,170],t:7,e:"input",a:{type:"text",value:[{t:2,r:"value",p:[12,27,196]}],placeholder:[{t:2,r:"placeholder",p:[12,51,220]}]}}," ",{p:[13,1,240],t:7,e:"ui-button",a:{icon:"refresh"},v:{press:"clear"}}]},e.exports=a.extend(r.exports)},{341:341}],346:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";e.exports={data:{graph:t(338),xaccessor:function(t){return t.x},yaccessor:function(t){return t.y}},computed:{size:function(){var t=this.get("points");return t[0].length},scale:function(){var t=this.get("points");return Math.max.apply(Math,Array.map(t,function(t){return Math.max.apply(Math,Array.map(t,function(t){return t.y}))}))},xaxis:function(){var t=this.get("xinc"),e=this.get("size");return Array.from(Array(e).keys()).filter(function(e){return e&&e%t==0})},yaxis:function(){var t=this.get("yinc"),e=this.get("scale");return Array.from(Array(t).keys()).map(function(t){return Math.round(e*(++t/100)*10)})}},oninit:function(){var t=this;this.on({enter:function(t){this.set("selected",t.index.count)},exit:function(t){this.set("selected")}}),window.addEventListener("resize",function(e){t.set("width",t.el.clientWidth)})},onrender:function(){this.set("width",this.el.clientWidth)}}}(r),r.exports.template={v:3,t:[" ",{p:[47,1,1269],t:7,e:"svg",a:{"class":"linegraph",width:"100%",height:[{t:2,x:{r:["height"],s:"_0+10"},p:[47,45,1313]}]},f:[{p:[48,3,1334],t:7,e:"g",a:{transform:"translate(0, 5)"},f:[{t:4,f:[{t:4,f:[{p:[51,9,1504],t:7,e:"line",a:{x1:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,19,1514]}],x2:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[51,38,1533]}],y1:"0",y2:[{t:2,r:"height",p:[51,64,1559]}],stroke:"darkgray"}}," ",{t:4,f:[{p:[53,11,1635],t:7,e:"text",a:{x:[{t:2,x:{r:["xscale","."],s:"_0(_1)"},p:[53,20,1644]}],y:[{t:2,x:{r:["height"],s:"_0-5"},p:[53,38,1662]}],"text-anchor":"middle",fill:"white"},f:[{t:2,x:{r:["size",".","xfactor"],s:"(_0-_1)*_2"},p:[53,88,1712]}," ",{t:2,r:"xunit",p:[53,113,1737]}]}],n:50,x:{r:["@index"],s:"_0%2==0"},p:[52,9,1600]}],n:52,r:"xaxis",p:[50,7,1479]}," ",{t:4,f:[{p:[57,9,1820],t:7,e:"line",a:{x1:"0",x2:[{t:2,r:"width",p:[57,26,1837]}],y1:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,41,1852]}],y2:[{t:2,x:{r:["yscale","."],s:"_0(_1)"},p:[57,60,1871]}],stroke:"darkgray"}}," ",{p:[58,9,1915],t:7,e:"text",a:{x:"0",y:[{t:2,x:{r:["yscale","."],s:"_0(_1)-5"},p:[58,24,1930]}],"text-anchor":"begin",fill:"white"},f:[{t:2,x:{r:[".","yfactor"],s:"_0*_1"},p:[58,76,1982]}," ",{t:2,r:"yunit",p:[58,92,1998]}]}],n:52,r:"yaxis",p:[56,7,1795]}," ",{t:4,f:[{p:[61,9,2071],t:7,e:"path",a:{d:[{t:2,x:{r:["area.path"],s:"_0.print()"},p:[61,18,2080]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[61,47,2109]}],opacity:"0.1"}}],n:52,i:"curve",r:"curves",p:[60,7,2039]}," ",{t:4,f:[{p:[64,9,2200],t:7,e:"path",a:{d:[{t:2,x:{r:["line.path"],s:"_0.print()"},p:[64,18,2209]}],stroke:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[64,49,2240]}],fill:"none"}}],n:52,
+i:"curve",r:"curves",p:[63,7,2168]}," ",{t:4,f:[{t:4,f:[{p:[68,11,2375],t:7,e:"circle",a:{transform:["translate(",{t:2,r:".",p:[68,40,2404]},")"],r:[{t:2,x:{r:["selected","count"],s:"_0==_1?10:4"},p:[68,51,2415]}],fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[68,89,2453]}]},v:{mouseenter:"enter",mouseleave:"exit"}}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[67,9,2329]}],n:52,i:"curve",r:"curves",p:[66,7,2297]}," ",{t:4,f:[{t:4,f:[{t:4,f:[{p:[74,13,2678],t:7,e:"text",a:{transform:["translate(",{t:2,r:".",p:[74,40,2705]},") ",{t:2,x:{r:["count","size"],s:'_0<=_1/2?"translate(15, 4)":"translate(-15, 4)"'},p:[74,47,2712]}],"text-anchor":[{t:2,x:{r:["count","size"],s:'_0<=_1/2?"start":"end"'},p:[74,126,2791]}],fill:"white"},f:[{t:2,x:{r:["count","item","yfactor"],s:"_1[_0].y*_2"},p:[75,15,2861]}," ",{t:2,r:"yunit",p:[75,43,2889]}," @ ",{t:2,x:{r:["size","count","item","xfactor"],s:"(_0-_2[_1].x)*_3"},p:[75,55,2901]}," ",{t:2,r:"xunit",p:[75,92,2938]}]}],n:50,x:{r:["selected","count"],s:"_0==_1"},p:[73,11,2638]}],n:52,i:"count",x:{r:["line.path"],s:"_0.points()"},p:[72,9,2592]}],n:52,i:"curve",r:"curves",p:[71,7,2560]}," ",{t:4,f:[{p:[81,9,3063],t:7,e:"g",a:{transform:["translate(",{t:2,x:{r:["width","curves.length","@index"],s:"(_0/(_1+1))*(_2+1)"},p:[81,33,3087]},", 10)"]},f:[{p:[82,11,3154],t:7,e:"circle",a:{r:"4",fill:[{t:2,rx:{r:"colors",m:[{t:30,n:"curve"}]},p:[82,31,3174]}]}}," ",{p:[83,11,3206],t:7,e:"text",a:{x:"8",y:"4",fill:"white"},f:[{t:2,rx:{r:"legend",m:[{t:30,n:"curve"}]},p:[83,42,3237]}]}]}],n:52,i:"curve",r:"curves",p:[80,7,3031]}],x:{r:["graph","points","xaccessor","yaccessor","width","height"],s:"_0({data:_1,xaccessor:_2,yaccessor:_3,width:_4,height:_5})"},p:[49,5,1371]}]}]}]},e.exports=a.extend(r.exports)},{338:338,341:341}],347:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"notice"},f:[{t:16,p:[2,3,24]}]}]},e.exports=a.extend(r.exports)},{341:341}],348:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(481),a=t(483);e.exports={oninit:function(){var t=this,e=a.resize.bind(this),r=function(){return t.set({resize:!1,x:null,y:null})};this.observe("config.fancy",function(a,i,o){(0,n.winset)(t.get("config.window"),"can-resize",!a),a?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",r)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",r))}),this.on("resize",function(){return t.toggle("resize")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[28,3,766],t:7,e:"div",a:{"class":"resize"},v:{mousedown:"resize"}}],n:50,r:"config.fancy",p:[27,1,742]}]},e.exports=a.extend(r.exports)},{341:341,481:481,483:483}],349:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"section",a:{"class":[{t:4,f:["candystripe"],r:"candystripe",p:[1,17,16]}]},f:[{t:4,f:[{p:[3,5,84],t:7,e:"span",a:{"class":"label",style:[{t:4,f:["color:",{t:2,r:"labelcolor",p:[3,53,132]}],r:"labelcolor",p:[3,32,111]}]},f:[{t:2,r:"label",p:[3,84,163]},":"]}],n:50,r:"label",p:[2,3,65]}," ",{t:4,f:[{t:16,p:[6,5,215]}],n:50,r:"nowrap",p:[5,3,195]},{t:4,n:51,f:[{p:[8,5,242],t:7,e:"div",a:{"class":"content",style:[{t:4,f:["float:right;"],r:"right",p:[8,33,270]}]},f:[{t:16,p:[9,7,312]}]}],r:"nowrap"}]}]},e.exports=a.extend(r.exports)},{341:341}],350:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"subdisplay"},f:[{t:4,f:[{p:[3,5,47],t:7,e:"header",f:[{p:[4,7,63],t:7,e:"h4",f:[{t:2,r:"title",p:[4,11,67]}]}," ",{t:4,f:[{t:16,n:"button",p:[5,21,103]}],n:50,r:"button",p:[5,7,89]}]}],n:50,r:"title",p:[2,3,28]}," ",{p:[8,3,156],t:7,e:"article",f:[{t:16,p:[9,5,171]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],351:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={oninit:function(){var t=this;this.set("active",this.findComponent("tab").get("name")),this.on("switch",function(e){t.set("active",e.node.textContent.trim())}),this.observe("active",function(e,n,a){for(var r=t.findAllComponents("tab"),i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;p.set("shown",p.get("name")===e)}})}}}(r),r.exports.template={v:3,t:[" "," ",{p:[20,1,524],t:7,e:"header",f:[{t:4,f:[{p:[22,5,556],t:7,e:"ui-button",a:{pane:[{t:2,r:".",p:[22,22,573]}]},v:{press:"switch"},f:[{t:2,r:".",p:[22,47,598]}]}],n:52,r:"tabs",p:[21,3,536]}]}," ",{p:[25,1,641],t:7,e:"ui-display",f:[{t:8,r:"content",p:[26,3,657]}]}]},r.exports.components=r.exports.components||{};var i={tab:t(352)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,352:352}],352:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:16,p:[2,3,17]}],n:50,r:"shown",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],353:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(482),a=t(481),r=t(483);e.exports={computed:{visualStatus:function(){switch(this.get("config.status")){case n.UI_INTERACTIVE:return"good";case n.UI_UPDATE:return"average";case n.UI_DISABLED:return"bad";default:return"bad"}}},oninit:function(){var t=this,e=r.drag.bind(this),n=function(e){return t.set({drag:!1,x:null,y:null})};this.observe("config.fancy",function(r,i,o){(0,a.winset)(t.get("config.window"),"titlebar",!r&&t.get("config.titlebar")),r?(document.addEventListener("mousemove",e),document.addEventListener("mouseup",n)):(document.removeEventListener("mousemove",e),document.removeEventListener("mouseup",n))}),this.on({drag:function(){this.toggle("drag")},close:function(){(0,a.winset)(this.get("config.window"),"is-visible",!1),window.location.href=(0,a.href)({command:"uiclose "+this.get("config.ref")},"winset")},minimize:function(){(0,a.winset)(this.get("config.window"),"is-minimized",!0)}})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[50,3,1440],t:7,e:"header",a:{"class":"titlebar"},v:{mousedown:"drag"},f:[{p:[51,5,1491],t:7,e:"i",a:{"class":["statusicon fa fa-eye fa-2x ",{t:2,r:"visualStatus",p:[51,42,1528]}]}}," ",{p:[52,5,1556],t:7,e:"span",a:{"class":"title"},f:[{t:16,p:[52,25,1576]}]}," ",{t:4,f:[{p:[54,7,1626],t:7,e:"i",a:{"class":"minimize fa fa-minus fa-2x"},v:{click:"minimize"}}," ",{p:[55,7,1696],t:7,e:"i",a:{"class":"close fa fa-close fa-2x"},v:{click:"close"}}],n:50,r:"config.fancy",p:[53,5,1598]}]}],n:50,r:"config.titlebar",p:[49,1,1413]}]},e.exports=a.extend(r.exports)},{341:341,481:481,482:482,483:483}],354:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";var e=[11,10,9,8];t.exports={data:{userAgent:navigator.userAgent},computed:{ie:function(){if(document.documentMode)return document.documentMode;for(var t in e){var n=document.createElement("div");if(n.innerHTML="",n.getElementsByTagName("span").length)return t}}},oninit:function(){var t=this;this.on("debug",function(){return t.toggle("debug")})}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[27,3,662],t:7,e:"ui-notice",f:[{p:[28,5,679],t:7,e:"span",f:["You have an old (IE",{t:2,r:"ie",p:[28,30,704]},"), end-of-life (click 'EOL Info' for more information) version of Internet Explorer installed."]},{p:[28,137,811],t:7,e:"br"}," ",{p:[29,5,822],t:7,e:"span",f:["To upgrade, click 'Upgrade IE' to download IE11 from Microsoft."]},{p:[29,81,898],t:7,e:"br"}," ",{p:[30,5,909],t:7,e:"span",f:["If you are unable to upgrade directly, click 'IE VMs' to download a VM with IE11 or Edge from Microsoft."]},{p:[30,122,1026],t:7,e:"br"}," ",{p:[31,5,1037],t:7,e:"span",f:["Otherwise, click 'No Frills' below to disable potentially incompatible features (and this message)."]}," ",{p:[32,5,1155],t:7,e:"hr"}," ",{p:[33,5,1166],t:7,e:"ui-button",a:{icon:"close",action:"tgui:nofrills"},f:["No Frills"]}," ",{p:[34,5,1240],t:7,e:"ui-button",a:{icon:"internet-explorer",action:"tgui:link",params:'{"url": "http://windows.microsoft.com/en-us/internet-explorer/download-ie"}'},f:["Upgrade IE"]}," ",{p:[36,5,1416],t:7,e:"ui-button",a:{icon:"edge",action:"tgui:link",params:'{"url": "https://dev.windows.com/en-us/microsoft-edge/tools/vms"}'},f:["IE VMs"]}," ",{p:[38,5,1565],t:7,e:"ui-button",a:{icon:"info",action:"tgui:link",params:'{"url": "https://support.microsoft.com/en-us/lifecycle#gp/Microsoft-Internet-Explorer"}'},f:["EOL Info"]}," ",{p:[40,5,1738],t:7,e:"ui-button",a:{icon:"bug"},v:{press:"debug"},f:["Debug Info"]}," ",{t:4,f:[{p:[42,7,1826],t:7,e:"hr"}," ",{p:[43,7,1839],t:7,e:"span",f:["Detected: IE",{t:2,r:"ie",p:[43,25,1857]}]},{p:[43,38,1870],t:7,e:"br"}," ",{p:[44,7,1883],t:7,e:"span",f:["User Agent: ",{t:2,r:"userAgent",p:[44,25,1901]}]}],n:50,r:"debug",p:[41,5,1805]}]}],n:50,x:{r:["config.fancy","ie"],s:"_0&&_1&&_1<11"},p:[26,1,621]}]},e.exports=a.extend(r.exports)},{341:341}],355:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},shockState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[22,1,348],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[23,2,384],t:7,e:"ui-section",a:{label:"Main"},f:[{p:[24,3,413],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.main"],s:"_0(_1)"},p:[24,16,426]}]},f:[{t:2,x:{r:["data.power.main"],s:'_0?"Online":"Offline"'},p:[24,49,459]}]}," ",{t:4,f:["[ ",{p:[26,6,567],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"},p:[25,3,512]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.main_timeleft",p:[29,7,674]}," seconds left ]"],n:50,x:{r:["data.power.main_timeleft"],s:"_0>0"},p:[28,4,630]}],x:{r:["data.wires.main_1","data.wires.main_2"],s:"!_0||!_1"}}," ",{p:[32,3,744],t:7,e:"div",a:{style:"float:right"},f:[{p:[33,4,774],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-main",state:[{t:2,x:{r:["data.power.main"],s:'_0?null:"disabled"'},p:[33,63,833]}]},f:["Disrupt"]}]}]}," ",{p:[36,2,922],t:7,e:"ui-section",a:{label:"Backup"},f:[{p:[37,3,953],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.power.backup"],s:"_0(_1)"},p:[37,16,966]}]},f:[{t:2,x:{r:["data.power.backup"],s:'_0?"Online":"Offline"'},p:[37,51,1001]}]}," ",{t:4,f:["[ ",{p:[39,6,1115],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"},p:[38,3,1056]},{t:4,n:51,f:[{t:4,f:["[ ",{t:2,r:"data.power.backup_timeleft",p:[42,7,1224]}," seconds left ]"],n:50,x:{r:["data.power.backup_timeleft"],s:"_0>0"},p:[41,4,1178]}],x:{r:["data.wires.backup_1","data.wires.backup_2"],s:"!_0||!_1"}}," ",{p:[45,3,1296],t:7,e:"div",a:{style:"float:right"},f:[{p:[46,4,1326],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"disrupt-backup",state:[{t:2,x:{r:["data.power.backup"],s:'_0?null:"disabled"'},p:[46,65,1387]}]},f:["Disrupt"]}]}]}," ",{p:[49,2,1478],t:7,e:"ui-section",a:{label:"Electrify"},f:[{p:[50,3,1512],t:7,e:"span",a:{"class":[{t:2,x:{r:["shockState","data.shock"],s:"_0(_1)"},p:[50,16,1525]}]},f:[{t:2,x:{r:["data.shock"],s:'_0==2?"Safe":"Electrified"'},p:[50,44,1553]}]}," ",{t:4,f:["[ ",{p:[52,6,1640],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.shock"],s:"!_0"},p:[51,3,1608]},{t:4,n:51,f:[{t:4,f:["[ ",{p:[55,7,1742],t:7,e:"span",a:{"class":"bad"},f:[{t:2,r:"data.shock_timeleft",p:[55,25,1760]}," seconds left"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0>0"},p:[54,4,1703]}," ",{t:4,f:["[ ",{p:[58,7,1863],t:7,e:"span",a:{"class":"bad"},f:["Permanent"]}," ]"],n:50,x:{r:["data.shock_timeleft"],s:"_0==-1"},p:[57,4,1822]}],x:{r:["data.wires.shock"],s:"!_0"}}," ",{p:[61,3,1926],t:7,e:"div",a:{style:"float:right"},f:[{p:[62,4,1956],t:7,e:"ui-button",a:{icon:"wrench",action:"shock-restore",state:[{t:2,x:{r:["data.wires.shock","data.shock"],s:'_0&&_1==0?null:"disabled"'},p:[62,59,2011]}]},f:["Restore"]}," ",{p:[63,4,2094],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-temp",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[63,54,2144]}]},f:["Set (Temporary)"]}," ",{p:[64,4,2199],t:7,e:"ui-button",a:{icon:"bolt",action:"shock-perm",state:[{t:2,x:{r:["data.wires.shock"],s:"!_0"},p:[64,53,2248]}]},f:["Set (Permanent)"]}]}]}]}," ",{p:[68,1,2341],t:7,e:"ui-display",a:{title:"Access & Door Control"},f:[{p:[69,2,2386],t:7,e:"ui-section",a:{label:"ID Scan"},f:[{t:4,f:["[ ",{p:[71,6,2455],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[70,3,2418]}," ",{p:[73,3,2516],t:7,e:"div",a:{style:"float:right"},f:[{p:[74,4,2546],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[74,22,2564]}],icon:"power-off",action:"idscan-on",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"selected":""'},p:[74,93,2635]}]},f:["Enabled"]}," ",{p:[75,4,2698],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.id_scanner"],s:"!_0"},p:[75,22,2716]}],icon:"close",action:"idscan-off",style:[{t:2,x:{r:["data.id_scanner"],s:'_0?"":"selected"'},p:[75,90,2784]}]},f:["Disabled"]}]}]}," ",{p:[78,2,2872],t:7,e:"ui-section",a:{label:"Emergency Access"},f:[{p:[79,3,2913],t:7,e:"div",a:{style:"float:right"},f:[{p:[80,4,2943],t:7,e:"ui-button",a:{icon:"power-off",action:"emergency-on",style:[{t:2,x:{r:["data.emergency"],s:'_0?"selected":""'},p:[80,61,3e3]}]},f:["Enabled"]}," ",{p:[81,4,3062],t:7,e:"ui-button",a:{icon:"close",action:"emergency-off",style:[{t:2,x:{r:["data.emergency"],s:'_0?"":"selected"'},p:[81,58,3116]}]},f:["Disabled"]}]}]}," ",{p:[84,2,3203],t:7,e:"br"}," ",{p:[85,2,3212],t:7,e:"ui-section",a:{label:"Door bolts"},f:[{t:4,f:["[ ",{p:[87,6,3279],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.bolts"],s:"!_0"},p:[86,3,3247]}," ",{p:[89,3,3340],t:7,e:"div",a:{style:"float:right"},f:[{p:[90,4,3370],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[90,22,3388]}],icon:"unlock",action:"bolt-raise",style:[{t:2,x:{r:["data.locked"],s:'_0?"":"selected"'},p:[90,85,3451]}]},f:["Raised"]}," ",{p:[91,4,3509],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.bolts"],s:"!_0"},p:[91,22,3527]}],icon:"lock",action:"bolt-drop",style:[{t:2,x:{r:["data.locked"],s:'_0?"selected":""'},p:[91,82,3587]}]},f:["Dropped"]}]}]}," ",{p:[94,2,3670],t:7,e:"ui-section",a:{label:"Door bolt lights"},f:[{t:4,f:["[ ",{p:[96,6,3744],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.lights"],s:"!_0"},p:[95,3,3711]}," ",{p:[98,3,3805],t:7,e:"div",a:{style:"float:right"},f:[{p:[99,4,3835],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[99,22,3853]}],icon:"power-off",action:"light-on",style:[{t:2,x:{r:["data.lights"],s:'_0?"selected":""'},p:[99,88,3919]}]},f:["Enabled"]}," ",{p:[100,4,3978],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.lights"],s:"!_0"},p:[100,22,3996]}],icon:"close",action:"light-off",style:[{t:2,x:{r:["data.lights"],s:'_0?"":"selected"'},p:[100,85,4059]}]},f:["Disabled"]}]}]}," ",{p:[103,2,4143],t:7,e:"ui-section",a:{label:"Door force sensors"},f:[{t:4,f:["[ ",{p:[105,6,4217],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.safe"],s:"!_0"},p:[104,3,4186]}," ",{p:[107,3,4278],t:7,e:"div",a:{style:"float:right"},f:[{p:[108,4,4308],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[108,22,4326]}],icon:"power-off",action:"safe-on",style:[{t:2,x:{r:["data.safe"],s:'_0?"selected":""'},p:[108,85,4389]}]},f:["Enabled"]}," ",{p:[109,4,4446],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.safe"],s:"!_0"},p:[109,22,4464]}],icon:"close",action:"safe-off",style:[{t:2,x:{r:["data.safe"],s:'_0?"":"selected"'},p:[109,82,4524]}]},f:["Disabled"]}]}]}," ",{p:[112,2,4606],t:7,e:"ui-section",a:{label:"Door timing safety"},f:[{t:4,f:["[ ",{p:[114,6,4682],t:7,e:"span",a:{"class":"bad"},f:["Wires have been cut"]}," ]"],n:50,x:{r:["data.wires.timing"],s:"!_0"},p:[113,3,4649]}," ",{p:[116,3,4743],t:7,e:"div",a:{style:"float:right"},f:[{p:[117,4,4773],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[117,22,4791]}],icon:"power-off",action:"speed-on",style:[{t:2,x:{r:["data.speed"],s:'_0?"selected":""'},p:[117,88,4857]}]},f:["Enabled"]}," ",{p:[118,4,4915],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.wires.timing"],s:"!_0"},p:[118,22,4933]}],icon:"close",action:"speed-off",style:[{t:2,x:{r:["data.speed"],s:'_0?"":"selected"'},p:[118,85,4996]}]},f:["Disabled"]}]}]}," ",{p:[121,2,5079],t:7,e:"br"}," ",{p:[122,2,5088],t:7,e:"ui-section",a:{label:"Door control"},f:[{t:4,f:["[ ",{p:[124,6,5166],t:7,e:"span",a:{"class":"bad"},f:["Door is ",{t:2,x:{r:["data.locked","data.welded"],s:'(_0?"bolted":"")+(_0&&_1?" and ":"")+(_1?"welded":"")'},p:[124,32,5192]}]}," ]"],n:50,x:{r:["data.locked","data.welded"],s:"_0||_1"},p:[123,3,5125]}," ",{p:[126,3,5327],t:7,e:"div",a:{style:"float:right"},f:[{p:[127,4,5357],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(_2&&"disabled")'},p:[127,22,5375]}],icon:"sign-out",action:"open-close"},f:["Open door"]}," ",{p:[128,4,5502],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.locked","data.welded","data.opened"],s:'(_0||_1)||(!_2&&"disabled")'},p:[128,22,5520]}],icon:"sign-in",action:"open-close"},f:["Close door"]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],356:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," ",{p:[7,1,267],t:7,e:"ui-notice",f:[{t:4,f:[{p:[9,5,312],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[10,7,355],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[10,24,372]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[10,75,423]}]}]}],n:50,r:"data.siliconUser",p:[8,3,282]},{t:4,n:51,f:[{p:[13,5,514],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,31,540]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[16,1,625],t:7,e:"status"}," ",{t:4,f:[{t:4,f:[{p:[19,7,719],t:7,e:"ui-display",a:{title:"Air Controls"},f:[{p:[20,9,762],t:7,e:"ui-section",f:[{p:[21,11,786],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"exclamation-triangle":"exclamation"'},p:[21,28,803]}],style:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"caution":null'},p:[21,98,873]}],action:[{t:2,x:{r:["data.atmos_alarm"],s:'_0?"reset":"alarm"'},p:[22,23,937]}]},f:["Area Atmosphere Alarm"]}]}," ",{p:[24,9,1045],t:7,e:"ui-section",f:[{p:[25,11,1069],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0==3?"exclamation-triangle":"exclamation"'},p:[25,28,1086]}],style:[{t:2,x:{r:["data.mode"],s:'_0==3?"danger":null'},p:[25,96,1154]}],action:"mode",params:['{"mode": ',{t:2,x:{r:["data.mode"],s:"_0==3?1:3"},p:[26,44,1236]},"}"]},f:["Panic Siphon"]}]}," ",{p:[28,9,1322],t:7,e:"br"}," ",{p:[29,9,1337],t:7,e:"ui-section",f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:"sign-out",action:"tgui:view",params:'{"screen": "vents"}'},f:["Vent Controls"]}]}," ",{p:[32,9,1494],t:7,e:"ui-section",f:[{p:[33,11,1518],t:7,e:"ui-button",a:{icon:"filter",action:"tgui:view",params:'{"screen": "scrubbers"}'},f:["Scrubber Controls"]}]}," ",{p:[35,9,1657],t:7,e:"ui-section",f:[{p:[36,11,1681],t:7,e:"ui-button",a:{icon:"cog",action:"tgui:view",params:'{"screen": "modes"}'},f:["Operating Mode"]}]}," ",{p:[38,9,1810],t:7,e:"ui-section",f:[{p:[39,11,1834],t:7,e:"ui-button",a:{icon:"bar-chart",action:"tgui:view",params:'{"screen": "thresholds"}'},f:["Alarm Thresholds"]}]}]}],n:50,x:{r:["config.screen"],s:'_0=="home"'},p:[18,3,680]},{t:4,n:51,f:[{t:4,n:50,x:{r:["config.screen"],s:'_0=="vents"'},f:[{p:[43,5,2032],t:7,e:"vents"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&(_0=="scrubbers")'},f:[" ",{p:[45,5,2089],t:7,e:"scrubbers"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&(_0=="modes"))'},f:[" ",{p:[47,5,2146],t:7,e:"modes"}]},{t:4,n:50,x:{r:["config.screen"],s:'(!(_0=="vents"))&&((!(_0=="scrubbers"))&&((!(_0=="modes"))&&(_0=="thresholds")))'},f:[" ",{p:[49,5,2204],t:7,e:"thresholds"}]}],x:{r:["config.screen"],s:'_0=="home"'}}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[17,1,636]}]},r.exports.components=r.exports.components||{};var i={vents:t(362),modes:t(358),thresholds:t(361),status:t(360),scrubbers:t(359)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,358:358,359:359,360:360,361:361,362:362}],357:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-button",a:{icon:"arrow-left",action:"tgui:view",params:'{"screen": "home"}'},f:["Back"]}]},e.exports=a.extend(r.exports)},{341:341}],358:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,115],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Operating Modes",button:0},f:[" ",{t:4,f:[{p:[8,5,168],t:7,e:"ui-section",f:[{p:[9,7,188],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["selected"],s:'_0?"check-square-o":"square-o"'},p:[9,24,205]}],state:[{t:2,x:{r:["selected","danger"],s:'_0?_1?"danger":"selected":null'},p:[10,16,267]}],action:"mode",params:['{"mode": ',{t:2,r:"mode",p:[11,40,361]},"}"]},f:[{t:2,r:"name",p:[11,51,372]}]}]}],n:52,r:"data.modes",p:[7,3,142]}]}]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],359:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," ",{p:{button:[{p:[6,5,185],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Scrubber Controls",button:0},f:[" ",{t:4,f:[{p:[9,5,242],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[9,27,264]}]},f:[{p:[10,7,287],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,323],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[11,26,340]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[11,68,382]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[12,46,459]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[12,66,479]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[12,80,493]}]}]}," ",{p:[14,7,558],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[15,9,593],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["scrubbing"],s:'_0?"filter":"sign-in"'},p:[15,26,610]}],style:[{t:2,x:{r:["scrubbing"],s:'_0?null:"danger"'},p:[15,71,655]}],action:"scrubbing",params:['{"id_tag": "',{t:2,r:"id_tag",p:[16,50,738]},'", "val": ',{t:2,x:{r:["scrubbing"],s:"+!_0"},p:[16,70,758]},"}"]},f:[{t:2,x:{r:["scrubbing"],s:'_0?"Scrubbing":"Siphoning"'},p:[16,88,776]}]}]}," ",{p:[18,7,858],t:7,e:"ui-section",a:{label:"Range"},f:[{p:[19,9,894],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["widenet"],s:'_0?"expand":"compress"'},p:[19,26,911]}],style:[{t:2,x:{r:["widenet"],s:'_0?"selected":null'},p:[19,70,955]}],action:"widenet",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,1036]},'", "val": ',{t:2,x:{r:["widenet"],s:"+!_0"},p:[20,68,1056]},"}"]},f:[{t:2,x:{r:["widenet"],s:'_0?"Expanded":"Normal"'},p:[20,84,1072]}]}]}," ",{p:[22,7,1148],t:7,e:"ui-section",a:{label:"Filters"},f:[{p:[23,9,1186],t:7,e:"filters"}]}]}],n:52,r:"data.scrubbers",p:[8,3,212]},{t:4,n:51,f:[{p:[27,5,1257],t:7,e:"span",a:{"class":"bad"},f:["Error: No scrubbers connected."]}],r:"data.scrubbers"}]}]},r.exports.components=r.exports.components||{};var i={filters:t(457),back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357,457:457}],360:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Air Status"},f:[{t:4,f:[{t:4,f:[{p:[4,7,110],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[4,26,129]}]},f:[{p:[5,6,146],t:7,e:"span",a:{"class":[{t:2,x:{r:["danger_level"],s:'_0==2?"bad":_0==1?"average":"good"'},p:[5,19,159]}]},f:[{t:2,x:{r:["value"],s:"Math.fixed(_0,2)"},p:[6,5,237]},{t:2,r:"unit",p:[6,29,261]}]}]}],n:52,r:"adata.environment_data",p:[3,5,70]}," ",{p:[10,5,322],t:7,e:"ui-section",a:{label:"Local Status"},f:[{p:[11,7,363],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.danger_level"],s:'_0==2?"bad bold":_0==1?"average bold":"good"'},p:[11,20,376]}]},f:[{t:2,x:{r:["data.danger_level"],s:'_0==2?"Danger (Internals Required)":_0==1?"Caution":"Optimal"'},p:[12,6,475]}]}]}," ",{p:[15,5,619],t:7,e:"ui-section",a:{label:"Area Status"},f:[{p:[16,7,659],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.atmos_alarm","data.fire_alarm"],s:'_0||_1?"bad bold":"good"'},p:[16,20,672]}]},f:[{t:2,x:{r:["data.atmos_alarm","fire_alarm"],s:'_0?"Atmosphere Alarm":_1?"Fire Alarm":"Nominal"'},p:[17,8,744]}]}]}],n:50,r:"data.environment_data",p:[2,3,35]},{t:4,n:51,f:[{p:[21,5,876],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[22,7,912],t:7,e:"span",a:{"class":"bad bold"},f:["Cannot obtain air sample for analysis."]}]}],r:"data.environment_data"}," ",{t:4,f:[{p:[26,5,1040],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[27,7,1076],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[25,3,1014]}]}]},e.exports=a.extend(r.exports)},{341:341}],361:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.css=" th, td {\r\n padding-right: 16px;\r\n text-align: left;\r\n }",r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,116],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Alarm Thresholds",button:0},f:[" ",{p:[7,3,143],t:7,e:"table",f:[{p:[8,5,156],t:7,e:"thead",f:[{p:[8,12,163],t:7,e:"tr",f:[{p:[9,7,175],t:7,e:"th"}," ",{p:[10,7,192],t:7,e:"th",f:[{p:[10,11,196],t:7,e:"span",a:{"class":"bad"},f:["min2"]}]}," ",{p:[11,7,238],t:7,e:"th",f:[{p:[11,11,242],t:7,e:"span",a:{"class":"average"},f:["min1"]}]}," ",{p:[12,7,288],t:7,e:"th",f:[{p:[12,11,292],t:7,e:"span",a:{"class":"average"},f:["max1"]}]}," ",{p:[13,7,338],t:7,e:"th",f:[{p:[13,11,342],t:7,e:"span",a:{"class":"bad"},f:["max2"]}]}]}]}," ",{p:[15,5,401],t:7,e:"tbody",f:[{t:4,f:[{p:[16,32,441],t:7,e:"tr",f:[{p:[17,9,455],t:7,e:"th",f:[{t:3,r:"name",p:[17,13,459]}]}," ",{t:4,f:[{p:[18,27,502],t:7,e:"td",f:[{p:[19,11,518],t:7,e:"ui-button",a:{action:"threshold",params:['{"env": "',{t:2,r:"env",p:[19,58,565]},'", "var": "',{t:2,r:"val",p:[19,76,583]},'"}']},f:[{t:2,x:{r:["selected"],s:"Math.fixed(_0,2)"},p:[19,87,594]}]}]}],n:52,r:"settings",p:[18,9,484]}]}],n:52,r:"data.thresholds",p:[16,7,416]}]}," ",{p:[23,3,697],t:7,e:"table",f:[]}]}]}," "]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],362:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:{button:[{p:[5,5,113],t:7,e:"back"}]},t:7,e:"ui-display",a:{title:"Vent Controls",button:0},f:[" ",{t:4,f:[{p:[8,5,166],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"long_name",p:[8,27,188]}]},f:[{p:[9,7,211],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[10,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["power"],s:'_0?"power-off":"close"'},p:[10,26,264]}],style:[{t:2,x:{r:["power"],s:'_0?"selected":null'},p:[10,68,306]}],action:"power",params:['{"id_tag": "',{t:2,r:"id_tag",p:[11,46,383]},'", "val": ',{t:2,x:{r:["power"],s:"+!_0"},p:[11,66,403]},"}"]},f:[{t:2,x:{r:["power"],s:'_0?"On":"Off"'},p:[11,80,417]}]}]}," ",{p:[13,7,482],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[14,9,517],t:7,e:"span",f:[{t:2,x:{r:["direction"],s:'_0=="release"?"Pressurizing":"Siphoning"'},p:[14,15,523]}]}]}," ",{p:[16,7,616],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[17,9,665],t:7,e:"ui-button",a:{icon:"sign-in",style:[{t:2,x:{r:["incheck"],s:'_0?"selected":null'},p:[17,42,698]}],action:"incheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[18,48,779]},'", "val": ',{t:2,r:"checks",p:[18,68,799]},"}"]},f:["Internal"]}," ",{p:[19,9,842],t:7,e:"ui-button",a:{icon:"sign-out",style:[{t:2,x:{r:["excheck"],s:'_0?"selected":null'},p:[19,43,876]}],action:"excheck",params:['{"id_tag": "',{t:2,r:"id_tag",p:[20,48,957]},'", "val": ',{t:2,r:"checks",p:[20,68,977]},"}"]},f:["External"]}]}," ",{t:4,f:[{p:[23,9,1064],t:7,e:"ui-section",a:{label:"Internal Target Pressure"},f:[{p:[24,11,1121],t:7,e:"ui-button",a:{icon:"pencil",action:"set_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[25,33,1210]},'"}']},f:[{t:2,x:{r:["internal"],s:"Math.fixed(_0)"},p:[25,47,1224]}]}," ",{p:[26,11,1272],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["intdefault"],s:'_0?"disabled":null'},p:[26,44,1305]}],action:"reset_internal_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[27,33,1407]},'"}']},f:["Reset"]}]}],n:50,r:"incheck",p:[22,7,1039]}," ",{t:4,f:[{p:[31,11,1511],t:7,e:"ui-section",a:{label:"External Target Pressure"},f:[{p:[32,13,1570],t:7,e:"ui-button",a:{icon:"pencil",action:"set_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[33,35,1661]},'"}']},f:[{t:2,x:{r:["external"],s:"Math.fixed(_0)"},p:[33,49,1675]}]}," ",{p:[34,13,1725],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["extdefault"],s:'_0?"disabled":null'},p:[34,46,1758]}],action:"reset_external_pressure",params:['{"id_tag": "',{t:2,r:"id_tag",p:[35,35,1862]},'"}']},f:["Reset"]}]}],n:50,r:"excheck",p:[30,7,1484]}]}],n:52,r:"data.vents",p:[7,3,140]},{t:4,n:51,f:[{p:[40,5,1973],t:7,e:"span",a:{"class":"bad"},f:["Error: No vents connected."]}],r:"data.vents"}]}]},r.exports.components=r.exports.components||{};var i={back:t(357)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,357:357}],363:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.css=" table {\r\n width: 100%;\r\n border-spacing: 2px;\r\n }\r\n th {\r\n text-align: left;\r\n }\r\n td {\r\n vertical-align: top;\r\n }\r\n td .button {\r\n margin-top: 4px\r\n }",r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",f:[{p:[3,5,34],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oneAccess"],s:'_0?"unlock":"lock"'},p:[3,22,51]}],action:"one_access"},f:[{t:2,x:{r:["data.oneAccess"],s:'_0?"One":"All"'},p:[3,82,111]}," Required"]}," ",{p:[4,5,172],t:7,e:"ui-button",a:{icon:"refresh",action:"clear"},f:["Clear"]}]}," ",{p:[6,3,251],t:7,e:"hr"}," ",{p:[7,3,260],t:7,e:"table",f:[{p:[8,3,271],t:7,e:"thead",f:[{p:[9,4,283],t:7,e:"tr",f:[{t:4,f:[{p:[10,5,315],t:7,e:"th",f:[{p:[10,9,319],t:7,e:"span",a:{"class":"highlight bold"},f:[{t:2,r:"name",p:[10,38,348]}]}]}],n:52,r:"data.regions",p:[9,8,287]}]}]}," ",{p:[13,3,403],t:7,e:"tbody",f:[{p:[14,4,415],t:7,e:"tr",f:[{t:4,f:[{p:[15,5,447],t:7,e:"td",f:[{t:4,f:[{p:[16,11,481],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["req"],s:'_0?"check-square-o":"square-o"'},p:[16,28,498]}],style:[{t:2,x:{r:["req"],s:'_0?"selected":null'},p:[16,76,546]}],action:"set",params:['{"access": "',{t:2,r:"id",p:[17,46,621]},'"}']},f:[{t:2,r:"name",p:[17,56,631]}]}," ",{p:[18,9,661],t:7,e:"br"}],n:52,r:"accesses",p:[15,9,451]}]}],n:52,r:"data.regions",p:[14,8,419]}]}]}]}," ",{p:[23,2,731],t:7,e:"hr"}," ",{p:[24,2,739],t:7,e:"span",a:{"class":"highlight bold"},f:["Unrestricted Access:"]}," ",{p:[25,2,798],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&1?"check-square-o":"square-o"'},p:[25,19,815]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&1?"selected":null'},p:[25,88,884]}],action:"direc_set",params:'{"unres_direction": "1"}'},f:["North"]}," ",{p:[26,2,1007],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&4?"check-square-o":"square-o"'},p:[26,19,1024]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&4?"selected":null'},p:[26,88,1093]}],action:"direc_set",params:'{"unres_direction": "4"}'},f:["East"]}," ",{p:[27,2,1215],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&2?"check-square-o":"square-o"'},p:[27,19,1232]}],style:[{t:2,x:{r:["data.unres_direction"],
+s:'_0&2?"selected":null'},p:[27,88,1301]}],action:"direc_set",params:'{"unres_direction": "2"}'},f:["South"]}," ",{p:[28,2,1424],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.unres_direction"],s:'_0&8?"check-square-o":"square-o"'},p:[28,19,1441]}],style:[{t:2,x:{r:["data.unres_direction"],s:'_0&8?"selected":null'},p:[28,88,1510]}],action:"direc_set",params:'{"unres_direction": "8"}'},f:["West"]}]}," "]},e.exports=a.extend(r.exports)},{341:341}],364:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}}},computed:{malfAction:function(){switch(this.get("data.malfStatus")){case 1:return"hack";case 2:return"occupy";case 3:return"deoccupy"}},malfButton:function(){switch(this.get("data.malfStatus")){case 1:return"Override Programming";case 2:case 4:return"Shunt Core Process";case 3:return"Return to Main Core"}},malfIcon:function(){switch(this.get("data.malfStatus")){case 1:return"terminal";case 2:case 4:return"caret-square-o-down";case 3:return"caret-square-o-left"}},powerCellStatusState:function(){var t=this.get("data.powerCellStatus");return t>50?"good":t>25?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[46,2,1206],t:7,e:"ui-notice",f:[{p:[47,3,1221],t:7,e:"b",f:[{p:[47,6,1224],t:7,e:"h3",f:["SYSTEM FAILURE"]}]}," ",{p:[48,3,1255],t:7,e:"i",f:["I/O regulators malfunction detected! Waiting for system reboot..."]},{p:[48,75,1327],t:7,e:"br"}," Automatic reboot in ",{t:2,r:"data.failTime",p:[49,23,1355]}," seconds... ",{p:[50,3,1387],t:7,e:"ui-button",a:{icon:"refresh",action:"reboot"},f:["Reboot Now"]},{p:[50,67,1451],t:7,e:"br"},{p:[50,71,1455],t:7,e:"br"},{p:[50,75,1459],t:7,e:"br"}]}],n:50,r:"data.failTime",p:[45,1,1182]},{t:4,n:51,f:[{p:[53,2,1491],t:7,e:"ui-notice",f:[{t:4,f:[{p:[55,3,1535],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[56,5,1576],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[56,22,1593]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[56,73,1644]}]}]}],n:50,r:"data.siliconUser",p:[54,4,1507]},{t:4,n:51,f:[{p:[59,3,1732],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[59,29,1758]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[62,2,1846],t:7,e:"ui-display",a:{title:"Power Status"},f:[{p:[63,4,1884],t:7,e:"ui-section",a:{label:"Main Breaker"},f:[{t:4,f:[{p:[65,5,1967],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isOperating"],s:'_0?"good":"bad"'},p:[65,18,1980]}]},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[65,57,2019]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[64,3,1921]},{t:4,n:51,f:[{p:[67,5,2079],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[67,22,2096]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[67,75,2149]}],action:"breaker"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[68,21,2212]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}," ",{p:[71,4,2293],t:7,e:"ui-section",a:{label:"External Power"},f:[{p:[72,3,2332],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.externalPower"],s:"_0(_1)"},p:[72,16,2345]}]},f:[{t:2,x:{r:["data.externalPower"],s:'_0==2?"Good":_0==1?"Low":"None"'},p:[72,52,2381]}]}]}," ",{p:[74,4,2490],t:7,e:"ui-section",a:{label:"Power Cell"},f:[{t:4,f:[{p:[76,5,2567],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerCellStatus",p:[76,38,2600]}],state:[{t:2,r:"powerCellStatusState",p:[76,71,2633]}]},f:[{t:2,x:{r:["adata.powerCellStatus"],s:"Math.fixed(_0)"},p:[76,97,2659]},"%"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[75,3,2525]},{t:4,n:51,f:[{p:[78,5,2724],t:7,e:"span",a:{"class":"bad"},f:["Removed"]}],x:{r:["data.powerCellStatus"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[82,3,2830],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{t:4,f:[{p:[84,4,2913],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.chargeMode"],s:'_0?"good":"bad"'},p:[84,17,2926]}]},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[84,55,2964]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[83,5,2868]},{t:4,n:51,f:[{p:[86,4,3026],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.chargeMode"],s:'_0?"refresh":"close"'},p:[86,21,3043]}],style:[{t:2,x:{r:["data.chargeMode"],s:'_0?"selected":null'},p:[86,71,3093]}],action:"charge"},f:[{t:2,x:{r:["data.chargeMode"],s:'_0?"Auto":"Off"'},p:[87,22,3156]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}," [",{p:[90,6,3236],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.chargingStatus"],s:"_0(_1)"},p:[90,19,3249]}]},f:[{t:2,x:{r:["data.chargingStatus"],s:'_0==2?"Fully Charged":_0==1?"Charging":"Not Charging"'},p:[90,56,3286]}]},"]"]}],n:50,x:{r:["data.powerCellStatus"],s:"_0!=null"},p:[81,4,2790]}]}," ",{p:[94,2,3445],t:7,e:"ui-display",a:{title:"Power Channels"},f:[{t:4,f:[{p:[96,3,3517],t:7,e:"ui-section",a:{label:[{t:2,r:"title",p:[96,22,3536]}],nowrap:0},f:[{p:[97,5,3560],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.powerChannels",m:[{t:30,n:"@index"},"powerLoad"]},p:[97,26,3581]}]}," ",{p:[98,5,3634],t:7,e:"div",a:{"class":"content"},f:[{p:[98,26,3655],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0>=2?"good":"bad"'},p:[98,39,3668]}]},f:[{t:2,x:{r:["status"],s:'_0>=2?"On":"Off"'},p:[98,73,3702]}]}]}," ",{p:[99,5,3751],t:7,e:"div",a:{"class":"content"},f:["[",{p:[99,27,3773],t:7,e:"span",f:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"Auto":"Manual"'},p:[99,33,3779]}]},"]"]}," ",{p:[100,5,3849],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{t:4,f:[{p:[102,6,3942],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["status"],s:'_0==1||_0==3?"selected":null'},p:[102,39,3975]}],action:"channel",params:[{t:2,r:"topicParams.auto",p:[103,30,4057]}]},f:["Auto"]}," ",{p:[104,6,4102],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["status"],s:'_0==2?"selected":null'},p:[104,41,4137]}],action:"channel",params:[{t:2,r:"topicParams.on",p:[105,13,4204]}]},f:["On"]}," ",{p:[106,6,4245],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["status"],s:'_0==0?"selected":null'},p:[106,37,4276]}],action:"channel",params:[{t:2,r:"topicParams.off",p:[107,13,4343]}]},f:["Off"]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[101,4,3895]}]}]}],n:52,r:"data.powerChannels",p:[95,4,3485]}," ",{p:[112,4,4439],t:7,e:"ui-section",a:{label:"Total Load"},f:[{p:[113,3,4474],t:7,e:"span",a:{"class":"bold"},f:[{t:2,r:"adata.totalLoad",p:[113,22,4493]}]}]}]}," ",{t:4,f:[{p:[117,4,4585],t:7,e:"ui-display",a:{title:"System Overrides"},f:[{p:[118,3,4626],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"overload"},f:["Overload"]}," ",{t:4,f:[{p:[120,5,4727],t:7,e:"ui-button",a:{icon:[{t:2,r:"malfIcon",p:[120,22,4744]}],state:[{t:2,x:{r:["data.malfStatus"],s:'_0==4?"disabled":null'},p:[120,43,4765]}],action:[{t:2,r:"malfAction",p:[120,97,4819]}]},f:[{t:2,r:"malfButton",p:[120,113,4835]}]}],n:50,r:"data.malfStatus",p:[119,3,4698]}]}],n:50,r:"data.siliconUser",p:[116,2,4556]}," ",{p:[124,2,4903],t:7,e:"ui-notice",f:[{p:[125,4,4919],t:7,e:"ui-section",a:{label:"Emergency Light Fallback"},f:[{t:4,f:[{p:[127,8,5020],t:7,e:"span",f:[{t:2,x:{r:["data.emergencyLights"],s:'_0?"Enabled":"Disabled"'},p:[127,14,5026]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[126,6,4971]},{t:4,n:51,f:[{p:[129,8,5106],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"emergency_lighting"},f:[{t:2,x:{r:["data.emergencyLights"],s:'_0?"Enabled":"Disabled"'},p:[129,66,5164]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}," ",{p:[133,2,5275],t:7,e:"ui-notice",f:[{p:[134,4,5291],t:7,e:"ui-section",a:{label:"Night Shift Lighting"},f:[{t:4,f:[{p:[136,8,5388],t:7,e:"span",f:[{t:2,x:{r:["data.nightshiftLights"],s:'_0?"Enabled":"Disabled"'},p:[136,14,5394]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[135,6,5339]},{t:4,n:51,f:[{p:[138,8,5475],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"toggle_nightshift"},f:[{t:2,x:{r:["data.nightshiftLights"],s:'_0?"Enabled":"Disabled"'},p:[138,65,5532]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}," ",{p:[142,2,5644],t:7,e:"ui-notice",f:[{p:[143,4,5660],t:7,e:"ui-section",a:{label:"Cover Lock"},f:[{t:4,f:[{p:[145,5,5741],t:7,e:"span",f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[145,11,5747]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"},p:[144,3,5695]},{t:4,n:51,f:[{p:[147,5,5819],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.coverLocked"],s:'_0?"lock":"unlock"'},p:[147,22,5836]}],action:"cover"},f:[{t:2,x:{r:["data.coverLocked"],s:'_0?"Engaged":"Disengaged"'},p:[147,79,5893]}]}],x:{r:["data.locked","data.siliconUser"],s:"_0&&!_1"}}]}]}],r:"data.failTime"}]},e.exports=a.extend(r.exports)},{341:341}],365:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Alarms"},f:[{p:[2,3,31],t:7,e:"ul",f:[{t:4,f:[{p:[4,7,72],t:7,e:"li",f:[{p:[4,11,76],t:7,e:"ui-button",a:{icon:"close",style:"danger",action:"clear",params:['{"zone": "',{t:2,r:".",p:[4,83,148]},'"}']},f:[{t:2,r:".",p:[4,92,157]}]}]}],n:52,r:"data.priority",p:[3,5,41]},{t:4,n:51,f:[{p:[6,7,201],t:7,e:"li",f:[{p:[6,11,205],t:7,e:"span",a:{"class":"good"},f:["No Priority Alerts"]}]}],r:"data.priority"}," ",{t:4,f:[{p:[9,7,303],t:7,e:"li",f:[{p:[9,11,307],t:7,e:"ui-button",a:{icon:"close",style:"caution",action:"clear",params:['{"zone": "',{t:2,r:".",p:[9,84,380]},'"}']},f:[{t:2,r:".",p:[9,93,389]}]}]}],n:52,r:"data.minor",p:[8,5,275]},{t:4,n:51,f:[{p:[11,7,433],t:7,e:"li",f:[{p:[11,11,437],t:7,e:"span",a:{"class":"good"},f:["No Minor Alerts"]}]}],r:"data.minor"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],366:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.tank","data.sensors.0.long_name"],s:"_0?_1:null"},p:[1,20,19]}]},f:[{t:4,f:[{p:[3,5,102],t:7,e:"ui-subdisplay",a:{title:[{t:2,x:{r:["data.tank","long_name"],s:"!_0?_1:null"},p:[3,27,124]}]},f:[{p:[4,7,167],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[5,3,200],t:7,e:"span",f:[{t:2,x:{r:["pressure"],s:"Math.fixed(_0,2)"},p:[5,9,206]}," kPa"]}]}," ",{t:4,f:[{p:[8,9,302],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[9,11,346],t:7,e:"span",f:[{t:2,x:{r:["temperature"],s:"Math.fixed(_0,2)"},p:[9,17,352]}," K"]}]}],n:50,r:"temperature",p:[7,7,273]}," ",{t:4,f:[{p:[13,9,462],t:7,e:"ui-section",a:{label:[{t:2,r:"id",p:[13,28,481]}]},f:[{p:[14,5,495],t:7,e:"span",f:[{t:2,x:{r:["."],s:"Math.fixed(_0,2)"},p:[14,11,501]},"%"]}]}],n:52,i:"id",r:"gases",p:[12,4,434]}]}],n:52,r:"adata.sensors",p:[2,3,73]}]}," ",{t:4,f:[{p:{button:[{p:[23,5,704],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[25,5,792],t:7,e:"ui-section",a:{label:"Input Injector"},f:[{p:[26,7,835],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputting"],s:'_0?"power-off":"close"'},p:[26,24,852]}],style:[{t:2,x:{r:["data.inputting"],s:'_0?"selected":null'},p:[26,75,903]}],action:"input"},f:[{t:2,x:{r:["data.inputting"],s:'_0?"Injecting":"Off"'},p:[27,9,968]}]}]}," ",{p:[29,5,1044],t:7,e:"ui-section",a:{label:"Input Rate"},f:[{p:[30,7,1083],t:7,e:"span",f:[{t:2,x:{r:["adata.inputRate"],s:"Math.fixed(_0)"},p:[30,13,1089]}," L/s"]}]}," ",{p:[32,5,1156],t:7,e:"ui-section",a:{label:"Output Regulator"},f:[{p:[33,7,1201],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputting"],s:'_0?"power-off":"close"'},p:[33,24,1218]}],style:[{t:2,x:{r:["data.outputting"],s:'_0?"selected":null'},p:[33,76,1270]}],action:"output"},f:[{t:2,x:{r:["data.outputting"],s:'_0?"Open":"Closed"'},p:[34,9,1337]}]}]}," ",{p:[36,5,1412],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[37,7,1456],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure"},f:[{t:2,x:{r:["adata.outputPressure"],s:"Math.round(_0)"},p:[37,50,1499]}," kPa"]}]}]}],n:50,r:"data.tank",p:[20,1,618]}]},e.exports=a.extend(r.exports)},{341:341}],367:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,518],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[9,11,524]}," kPa"]}]}," ",{p:[11,3,586],t:7,e:"ui-section",a:{label:"Filter"},f:[{t:4,f:[{p:[13,7,654],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[13,25,672]}],action:"filter",params:['{"mode": ',{t:2,r:"id",p:[14,42,748]},"}"]},f:[{t:2,r:"name",p:[14,51,757]}]}],n:52,r:"data.filter_types",p:[12,5,619]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],368:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{p:[6,3,223],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[7,5,265],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[8,5,360],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.set_pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[8,35,390]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[9,5,522],t:7,e:"span",f:[{t:2,x:{r:["adata.set_pressure"],s:"Math.round(_0)"},p:[9,11,528]}," kPa"]}]}," ",{p:[11,3,594],t:7,e:"ui-section",a:{label:"Node 1"},f:[{p:[12,5,627],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[12,44,666]}],action:"node1",params:'{"concentration": -0.1}'}}," ",{p:[14,5,783],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==0?"disabled":null'},p:[14,39,817]}],action:"node1",params:'{"concentration": -0.01}'}}," ",{p:[16,5,935],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[16,38,968]}],action:"node1",params:'{"concentration": 0.01}'}}," ",{p:[18,5,1087],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node1_concentration"],s:'_0==100?"disabled":null'},p:[18,43,1125]}],action:"node1",params:'{"concentration": 0.1}'}}," ",{p:[20,5,1243],t:7,e:"span",f:[{t:2,x:{r:["adata.node1_concentration"],s:"Math.round(_0)"},p:[20,11,1249]},"%"]}]}," ",{p:[22,3,1319],t:7,e:"ui-section",a:{label:"Node 2"},f:[{p:[23,5,1352],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[23,44,1391]}],action:"node2",params:'{"concentration": -0.1}'}}," ",{p:[25,5,1508],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==0?"disabled":null'},p:[25,39,1542]}],action:"node2",params:'{"concentration": -0.01}'}}," ",{p:[27,5,1660],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[27,38,1693]}],action:"node2",params:'{"concentration": 0.01}'}}," ",{p:[29,5,1812],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.node2_concentration"],s:'_0==100?"disabled":null'},p:[29,43,1850]}],action:"node2",params:'{"concentration": 0.1}'}}," ",{p:[31,5,1968],t:7,e:"span",f:[{t:2,x:{r:["adata.node2_concentration"],s:"Math.round(_0)"},p:[31,11,1974]},"%"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],369:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,48],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[3,22,65]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[3,66,109]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[4,22,164]}]}]}," ",{t:4,f:[{p:[7,5,250],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{p:[8,7,292],t:7,e:"ui-button",a:{icon:"pencil",action:"rate",params:'{"rate": "input"}'},f:["Set"]}," ",{p:[9,7,381],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.rate","data.max_rate"],s:'_0==_1?"disabled":null'},p:[9,37,411]}],action:"rate",params:'{"rate": "max"}'},f:["Max"]}," ",{p:[10,7,525],t:7,e:"span",f:[{t:2,x:{r:["adata.rate"],s:"Math.round(_0)"},p:[10,13,531]}," L/s"]}]}],n:50,r:"data.max_rate",p:[6,3,223]},{t:4,n:51,f:[{p:[13,5,605],t:7,e:"ui-section",a:{label:"Output Pressure"},f:[{p:[14,7,649],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[15,7,746],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.pressure","data.max_pressure"],s:'_0==_1?"disabled":null'},p:[15,37,776]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}," ",{p:[16,7,906],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[16,13,912]}," kPa"]}]}],r:"data.max_rate"}]}]},e.exports=a.extend(r.exports)},{341:341}],370:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,72],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"data.borg.name",p:[1,20,19]}],button:0},f:[" ",{p:[5,2,149],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[6,4,181],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.emagged"],s:'_0?"check-square-o":"square-o"'},p:[6,21,198]}],style:[{t:2,x:{r:["data.borg.emagged"],s:'_0?"selected":null'},p:[6,83,260]}],action:"toggle_emagged"},f:["Emagged"]}," ",{p:[7,4,351],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.lockdown"],s:'_0?"check-square-o":"square-o"'},p:[7,21,368]}],style:[{t:2,x:{r:["data.borg.lockdown"],s:'_0?"selected":null'},p:[7,84,431]}],action:"toggle_lockdown"},f:["Locked down"]}," ",{p:[8,4,528],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.scrambledcodes"],s:'_0?"check-square-o":"square-o"'},p:[8,21,545]}],style:[{t:2,x:{r:["data.borg.scrambledcodes"],s:'_0?"selected":null'},p:[8,90,614]}],action:"toggle_scrambledcodes"},f:["Scrambled codes"]}]}," ",{p:[10,2,741],t:7,e:"ui-section",a:{label:"Charge"},f:[{t:4,f:[{p:[12,4,803],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.cell.maxcharge",p:[12,25,824]}],value:[{t:2,r:"data.cell.charge",p:[12,57,856]}]},f:[{t:2,x:{r:["data.cell.charge"],s:"Math.round(_0)"},p:[12,79,878]}," / ",{t:2,x:{r:["data.cell.maxcharge"],s:"Math.round(_0)"},p:[12,114,913]}]}],n:50,x:{r:["data.cell.missing"],s:"!_0"},p:[11,3,772]},{t:4,n:51,f:[{p:[14,4,974],t:7,e:"span",a:{"class":"warning"},f:["Cell missing"]},{p:[14,45,1015],t:7,e:"br"}],x:{r:["data.cell.missing"],s:"!_0"}}," ",{p:[16,3,1035],t:7,e:"ui-button",a:{icon:"pencil",action:"set_charge"},f:["Set"]},{p:[16,63,1095],t:7,e:"ui-button",a:{icon:"eject",action:"change_cell"},f:["Change"]},{p:[16,126,1158],t:7,e:"ui-button",a:{icon:"trash","class":"bad",action:"remove_cell"},f:["Remove"]}]}," ",{p:[18,2,1252],t:7,e:"ui-section",a:{label:"Radio channels"},f:[{t:4,f:[{p:[20,4,1319],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["installed"],s:'_0?"check-square-o":"square-o"'},p:[20,21,1336]}],style:[{t:2,x:{r:["installed"],s:'_0?"selected":null'},p:[20,75,1390]}],action:"toggle_radio",params:['{"channel": "',{t:2,r:"name",p:[20,154,1469]},'"}']},f:[{t:2,r:"name",p:[20,166,1481]}]}],n:52,r:"data.channels",p:[19,3,1291]}]}," ",{p:[23,2,1533],t:7,e:"ui-section",a:{label:"Module"},f:[{t:4,f:[{p:[25,4,1591],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.active_module","type"],s:'_0==_1?"check-square-o":"square-o"'},p:[25,21,1608]}],style:[{t:2,x:{r:["data.borg.active_module","type"],s:'_0==_1?"selected":null'},p:[25,97,1684]}],action:"setmodule",params:['{"module": "',{t:2,r:"type",p:[25,193,1780]},'"}']},f:[{t:2,r:"name",p:[25,205,1792]}]}],n:52,r:"data.modules",p:[24,3,1564]}]}," ",{p:[28,2,1844],t:7,e:"ui-section",a:{label:"Upgrades"},f:[{t:4,f:[{p:[30,4,1905],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["installed"],s:'_0?"check-square-o":"square-o"'},p:[30,21,1922]}],style:[{t:2,x:{r:["installed"],s:'_0?"selected":null'},p:[30,75,1976]}],action:"toggle_upgrade",params:['{"upgrade": "',{t:2,r:"type",p:[30,155,2056]},'"}']},f:[{t:2,r:"name",p:[30,167,2068]}]}],n:52,r:"data.upgrades",p:[29,3,1877]}]}," ",{p:[33,2,2120],t:7,e:"ui-section",a:{label:"Master AI"},f:[{t:4,f:[{p:[35,4,2177],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["connected"],s:'_0?"check-square-o":"square-o"'},p:[35,21,2194]}],style:[{t:2,x:{r:["connected"],s:'_0?"selected":null'},p:[35,75,2248]}],action:"slavetoai",params:['{"slavetoai": "',{t:2,r:"ref",p:[35,152,2325]},'"}']},f:[{t:2,r:"name",p:[35,163,2336]}]}],n:52,r:"data.ais",p:[34,3,2154]}]}]}," ",{p:{button:[{p:[41,3,2460],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.borg.lawupdate"],s:'_0?"check-square-o":"square-o"'},p:[41,20,2477]}],style:[{t:2,x:{r:["data.borg.lawupdate"],s:'_0?"selected":null'},p:[41,84,2541]}],action:"toggle_lawupdate"},f:["Lawsync"]}]},t:7,e:"ui-display",a:{title:"Laws",button:0},f:[" ",{t:4,f:[{p:[44,3,2672],t:7,e:"p",f:[{t:2,r:".",p:[44,6,2675]}]}],n:52,r:"data.laws",p:[43,2,2649]}]}]},e.exports=a.extend(r.exports)},{341:341}],371:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"selected":null'},p:[3,38,100]}],action:[{t:2,x:{r:["data.timing"],s:'_0?"stop":"start"'},p:[3,83,145]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"Stop":"Start"'},p:[3,119,181]}]}," ",{p:[4,5,233],t:7,e:"ui-button",a:{icon:"lightbulb-o",action:"flash",style:[{t:2,x:{r:["data.flash_charging"],s:'_0?"disabled":null'},p:[4,57,285]}]},f:[{t:2,x:{r:["data.flash_charging"],s:'_0?"Recharging":"Flash"'},p:[4,102,330]}]}]},t:7,e:"ui-display",a:{title:"Cell Timer",button:0},f:[" ",{p:[6,3,410],t:7,e:"ui-section",f:[{p:[7,5,428],t:7,e:"ui-button",a:{icon:"fast-backward",action:"time",params:'{"adjust": -600}'}}," ",{p:[8,5,518],t:7,e:"ui-button",a:{icon:"backward",action:"time",params:'{"adjust": -100}'}}," ",{p:[9,5,603],t:7,e:"span",f:[{t:2,x:{r:["text","data.minutes"],s:"_0.zeroPad(_1,2)"},p:[9,11,609]},":",{t:2,x:{r:["text","data.seconds"],s:"_0.zeroPad(_1,2)"},p:[9,45,643]}]}," ",{p:[10,5,689],t:7,e:"ui-button",a:{icon:"forward",action:"time",params:'{"adjust": 100}'}}," ",{p:[11,5,772],t:7,e:"ui-button",a:{icon:"fast-forward",action:"time",params:'{"adjust": 600}'}}]}," ",{p:[13,3,875],t:7,e:"ui-section",f:[{p:[14,7,895],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "short"}'},f:["Short"]}," ",{p:[15,7,999],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "medium"}'},f:["Medium"]}," ",{p:[16,7,1105],t:7,e:"ui-button",a:{icon:"hourglass-start",action:"preset",params:'{"preset": "long"}'},f:["Long"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],372:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Bluespace Artillery Control",button:0},f:[{t:4,f:[{p:[8,3,167],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,5,200],t:7,e:"ui-button",a:{icon:"crosshairs",action:"recalibrate"},f:[{t:2,r:"data.target",p:[9,55,250]}]}]}," ",{p:[11,3,298],t:7,e:"ui-section",a:{label:"Controls"},f:[{t:4,f:[{p:[13,3,356],t:7,e:"ui-notice",f:[{p:[14,4,372],t:7,e:"span",f:["Bluespace Artillery firing protocols must be globally unlocked from two keycard authentication devices first!"]}]}],n:50,x:{r:["data.unlocked"],s:"!_0"},p:[12,2,330]},{t:4,n:51,f:[{p:[17,3,525],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.ready"],s:'_0?null:"disabled"'},p:[17,36,558]}],action:"fire"},f:["FIRE!"]}],x:{r:["data.unlocked"],s:"!_0"}}]}],n:50,r:"data.connected",p:[7,3,141]}," ",{t:4,f:[{p:[22,3,694],t:7,e:"ui-section",a:{label:"Maintenance"},f:[{p:[23,7,734],t:7,e:"ui-button",a:{icon:"wrench",action:"build"},f:["Complete Deployment."]}]}],n:50,x:{r:["data.connected"],s:"!_0"},p:[21,3,667]}]}]},e.exports=a.extend(r.exports)},{341:341}],373:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.hasHoldingTank"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:{button:[{p:[6,5,185],t:7,e:"ui-button",a:{icon:"pencil",action:"relabel"},f:["Relabel"]}]},t:7,e:"ui-display",a:{title:"Canister",button:0},f:[" ",{p:[8,3,266],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[9,5,301],t:7,e:"span",f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[9,11,307]}," kPa"]}]}," ",{p:[11,3,373],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[12,5,404],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.portConnected"],s:'_0?"good":"average"'},p:[12,18,417]}]},f:[{t:2,x:{r:["data.portConnected"],s:'_0?"Connected":"Not Connected"'},p:[12,63,462]}]}]}," ",{t:4,f:[{p:[15,3,573],t:7,e:"ui-section",a:{label:"Access"},f:[{p:[16,7,608],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.restricted"],s:'_0?"lock":"unlock"'},p:[16,24,625]}],style:[{t:2,x:{r:[],s:'"caution"'},p:[17,14,680]}],action:"restricted"},f:[{t:2,x:{r:["data.restricted"],s:'_0?"Restricted to Engineering":"Public"'},p:[18,27,722]}]}]}],n:50,r:"data.isPrototype",p:[14,3,544]}]}," ",{p:[22,1,839],t:7,e:"ui-display",a:{title:"Valve"},f:[{p:[23,3,869],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[24,5,912],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[24,18,925]}],max:[{t:2,r:"data.maxReleasePressure",p:[24,52,959]}],value:[{t:2,r:"data.releasePressure",p:[25,14,1002]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[25,40,1028]}," kPa"]}]}," ",{p:[27,3,1099],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[28,5,1144],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[28,38,1177]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[30,5,1333],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[30,36,1364]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[32,5,1511],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[33,5,1606],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[33,35,1636]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}," ",{p:[36,3,1798],t:7,e:"ui-section",a:{label:"Valve"},f:[{p:[37,5,1830],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.valveOpen"],s:'_0?"unlock":"lock"'},p:[37,22,1847]}],style:[{t:2,x:{r:["data.valveOpen","data.hasHoldingTank"],s:'_0?_1?"caution":"danger":null'},p:[38,14,1901]}],action:"valve"},f:[{t:2,x:{r:["data.valveOpen"],s:'_0?"Open":"Closed"'},p:[39,22,1995]}]}]}]}," ",{t:4,f:[{p:[42,1,2090],t:7,e:"ui-display",a:{title:"Valve Toggle Timer"},f:[{t:4,f:[{p:[44,5,2155],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[45,7,2196],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.timer_is_not_default"],s:'_0?null:"disabled"'},p:[45,40,2229]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[47,7,2358],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.timer_is_not_min"],s:'_0?null:"disabled"'},p:[47,38,2389]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[49,7,2520],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:[],s:'"disabled"'},p:[49,39,2552]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[51,7,2637],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.timer_is_not_max"],s:'_0?null:"disabled"'},p:[51,37,2667]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[43,3,2133]}," ",{p:[55,3,2833],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[56,6,2866],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[56,39,2899]}],action:"toggle_timer"},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[57,30,2969]}]}," ",{p:[59,2,3017],t:7,e:"ui-section",a:{label:"Time until Valve Toggle"},f:[{p:[60,2,3064],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[60,8,3070]}]}]}]}]}],n:50,r:"data.isPrototype",p:[41,1,2062]},{p:{button:[{t:4,f:[{p:[69,7,3277],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.valveOpen"],s:'_0?"danger":null'},p:[69,38,3308]}],action:"eject"},f:["Eject"]}],n:50,r:"data.hasHoldingTank",p:[68,5,3242]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[73,3,3442],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holdingTank.name",p:[74,4,3473]}]}," ",{p:[76,3,3519],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holdingTank.tankPressure"],s:"Math.round(_0)"},p:[77,4,3553]}," kPa"]}],n:50,r:"data.hasHoldingTank",p:[72,3,3411]},{t:4,n:51,f:[{p:[80,3,3635],t:7,e:"ui-section",f:[{p:[81,4,3652],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.hasHoldingTank"}]}]},e.exports=a.extend(r.exports)},{341:341}],374:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,158],t:7,e:"ui-display",a:{title:"Cargo"},f:[{p:[12,3,188],t:7,e:"ui-section",a:{label:"Shuttle"},f:[{t:4,f:[{p:[14,7,270],t:7,e:"ui-button",a:{action:"send"},f:[{t:2,r:"data.location",p:[14,32,295]}]}],n:50,x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"},p:[13,5,222]},{t:4,n:51,f:[{p:[16,7,346],t:7,e:"span",f:[{t:2,r:"data.location",p:[16,13,352]}]}],x:{r:["data.docked","data.requestonly"],s:"_0&&!_1"}}]}," ",{p:[19,3,410],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[20,5,444],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[20,11,450]}]}]}," ",{p:[22,3,506],t:7,e:"ui-section",a:{label:"CentCom Message"},f:[{p:[23,7,550],t:7,e:"span",f:[{t:2,r:"data.message",p:[23,13,556]}]}]}," ",{t:4,f:[{p:[26,5,644],t:7,e:"ui-section",a:{label:"Loan"},f:[{t:4,f:[{p:[28,9,716],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.away","data.docked"],s:'_0&&_1?null:"disabled"'},p:[29,17,744]}],action:"loan"},f:["Loan Shuttle"]}],n:50,x:{r:["data.loan_dispatched"],s:"!_0"},p:[27,7,677]},{t:4,n:51,f:[{p:[32,9,868],t:7,e:"span",a:{"class":"bad"},f:["Loaned to CentCom"]}],x:{r:["data.loan_dispatched"],s:"!_0"}}]}],n:50,x:{r:["data.loan","data.requestonly"],s:"_0&&!_1"},p:[25,3,600]}]}," ",{t:4,f:[{p:{button:[{p:[40,7,1066],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.cart.length"],s:'_0?null:"disabled"'},p:[40,38,1097]}],action:"clear"},f:["Clear"]}]},t:7,e:"ui-display",a:{title:"Cart",button:0},f:[" ",{t:4,f:[{p:[43,7,1222],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[44,9,1263],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[44,31,1285]}]}," ",{p:[45,9,1307],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[45,30,1328]}]}," ",{p:[46,9,1354],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[46,30,1375]}," Credits"]}," ",{p:[47,9,1407],t:7,e:"div",a:{"class":"content"},f:[{p:[48,11,1440],t:7,e:"ui-button",a:{icon:"minus",action:"remove",
+params:['{"id": "',{t:2,r:"id",p:[48,67,1496]},'"}']}}]}]}],n:52,r:"data.cart",p:[42,5,1195]},{t:4,n:51,f:[{p:[52,7,1566],t:7,e:"span",f:["Nothing in Cart"]}],r:"data.cart"}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[37,1,972]},{p:{button:[{t:4,f:[{p:[59,7,1735],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.requests.length"],s:'_0?null:"disabled"'},p:[59,38,1766]}],action:"denyall"},f:["Clear"]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[58,5,1702]}]},t:7,e:"ui-display",a:{title:"Requests",button:0},f:[" ",{t:4,f:[{p:[63,5,1908],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[64,7,1947],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[64,29,1969]}]}," ",{p:[65,7,1989],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"object",p:[65,28,2010]}]}," ",{p:[66,7,2034],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"cost",p:[66,28,2055]}," Credits"]}," ",{p:[67,7,2085],t:7,e:"div",a:{"class":"content"},f:["By ",{t:2,r:"orderer",p:[67,31,2109]}]}," ",{p:[68,7,2134],t:7,e:"div",a:{"class":"content"},f:["Comment: ",{t:2,r:"reason",p:[68,37,2164]}]}," ",{t:4,f:[{p:[70,9,2223],t:7,e:"div",a:{"class":"content"},f:[{p:[71,11,2256],t:7,e:"ui-button",a:{icon:"check",action:"approve",params:['{"id": "',{t:2,r:"id",p:[71,68,2313]},'"}']}}," ",{p:[72,11,2336],t:7,e:"ui-button",a:{icon:"close",action:"deny",params:['{"id": "',{t:2,r:"id",p:[72,65,2390]},'"}']}}]}],n:50,x:{r:["data.requestonly"],s:"!_0"},p:[69,7,2188]}]}],n:52,r:"data.requests",p:[62,3,1879]},{t:4,n:51,f:[{p:[77,7,2473],t:7,e:"span",f:["No Requests"]}],r:"data.requests"}]}," ",{p:[80,1,2529],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[80,16,2544]}]},f:[{t:4,f:[{p:[82,5,2587],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[82,16,2598]}]},f:[{t:4,f:[{p:[84,9,2641],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,28,2660]}],candystripe:0,right:0},f:[{p:[85,11,2700],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"desc",p:[85,31,2720]}],"tooltip-side":"left",action:"add",params:['{"id": "',{t:2,r:"id",p:[85,90,2779]},'"}']},f:[{t:2,r:"cost",p:[85,100,2789]}," Credits"]}]}],n:52,r:"packs",p:[83,7,2616]}]}],n:52,r:"data.supplies",p:[81,3,2558]}]}]},e.exports=a.extend(r.exports)},{341:341}],375:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tabs:function(){return Object.keys(this.get("data.supplies"))}}}}(r),r.exports.template={v:3,t:[" ",{p:[12,1,174],t:7,e:"ui-notice",f:[{t:4,f:[{p:[14,5,220],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[15,7,263],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[15,24,280]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[15,75,331]}]}]}],n:50,r:"data.siliconUser",p:[13,3,189]},{t:4,n:51,f:[{p:[18,5,422],t:7,e:"span",f:["Swipe a QM-Level ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[18,39,456]}," this interface."]}],r:"data.siliconUser"}]}," ",{t:4,f:[{p:[23,3,568],t:7,e:"ui-display",a:{title:"Express Cargo Console"},f:[{p:[25,5,618],t:7,e:"ui-section",a:{label:"Landing Location"},f:[{p:[26,7,663],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.usingBeacon"],s:'_0?null:"selected"'},p:[26,25,681]}],action:"LZCargo"},f:["Cargo Bay"]}," ",{p:[27,7,770],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.hasBeacon","data.usingBeacon"],s:'_0?_1?"selected":null:"disabled"'},p:[27,25,788]}],action:"LZBeacon"},f:[{t:2,r:"data.beaconzone",p:[27,116,879]}," (",{t:2,r:"data.beaconName",p:[27,137,900]},")"]}," ",{p:[28,7,940],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.canBuyBeacon"],s:'_0?null:"disabled"'},p:[28,25,958]}],action:"printBeacon"},f:[{t:2,r:"data.printMsg",p:[28,90,1023]}]}]}," ",{p:[31,5,1079],t:7,e:"ui-section",a:{label:"Credits"},f:[{p:[32,7,1115],t:7,e:"span",f:[{t:2,x:{r:["adata.points"],s:"Math.floor(_0)"},p:[32,13,1121]}]}]}," ",{p:[35,5,1183],t:7,e:"ui-section",a:{label:"Notice"},f:[{p:[36,7,1218],t:7,e:"span",f:[{t:2,r:"data.message",p:[36,13,1224]}]}]}]}," ",{p:[39,3,1287],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"tabs",p:[39,18,1302]}]},f:[{t:4,f:[{p:[41,7,1349],t:7,e:"tab",a:{name:[{t:2,r:"name",p:[41,18,1360]}]},f:[{t:4,f:[{p:[43,11,1407],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[43,30,1426]}],candystripe:0,right:0},f:[{p:[44,13,1468],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.canBeacon"],s:'_0?null:"disabled"'},p:[44,31,1486]}],tooltip:[{t:2,r:"desc",p:[44,80,1535]}],"tooltip-side":"left",action:"add",params:['{"id": "',{t:2,r:"id",p:[44,139,1594]},'"}']},f:[{t:2,r:"cost",p:[44,149,1604]}," Credits ",{t:2,r:"data.beaconError",p:[44,166,1621]}]}]}],n:52,r:"packs",p:[42,9,1380]}]}],n:52,r:"data.supplies",p:[40,5,1318]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[22,1,543]}]},e.exports=a.extend(r.exports)},{341:341}],376:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Cellular Emporium",button:0},f:[{p:[2,3,49],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.can_readapt"],s:'_0?null:"disabled"'},p:[2,36,82]}],action:"readapt"},f:["Readapt"]}," ",{p:[4,3,169],t:7,e:"ui-section",a:{label:"Genetic Points Remaining",right:0},f:[{t:2,r:"data.genetic_points_remaining",p:[5,5,226]}]}]}," ",{p:[8,1,293],t:7,e:"ui-display",f:[{t:4,f:[{p:[10,3,335],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[10,22,354]}],candystripe:0,right:0},f:[{p:[11,5,388],t:7,e:"span",f:[{t:2,r:"desc",p:[11,11,394]}]}," ",{p:[12,5,415],t:7,e:"span",f:[{t:2,r:"helptext",p:[12,11,421]}]}," ",{p:[13,5,446],t:7,e:"span",f:["Cost: ",{t:2,r:"dna_cost",p:[13,17,458]}]}," ",{p:[14,5,483],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["owned","can_purchase"],s:'_0?"selected":_1?null:"disabled"'},p:[15,14,508]}],action:"evolve",params:['{"name": "',{t:2,r:"name",p:[17,25,615]},'"}']},f:[{t:2,x:{r:["owned"],s:'_0?"Evolved":"Evolve"'},p:[18,7,635]}]}]}],n:52,r:"data.abilities",p:[9,1,307]},{t:4,f:[{p:[23,3,738],t:7,e:"span",a:{"class":"warning"},f:["No abilities available."]}],n:51,r:"data.abilities",p:[22,1,715]}]}]},e.exports=a.extend(r.exports)},{341:341}],377:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,5,17],t:7,e:"span",f:["To use this, simply spawn the atoms you want in one of the four Centcom Supplypod Bays. Items in the bay will then be launched inside your supplypod, one turf-full at a time! You can optionally use the following buttons to configure how the supplypod acts."]}]}," ",{p:[5,1,304],t:7,e:"ui-display",a:{title:"Centcom Pod Customization (to be used against helen weinstein)"},f:[{p:[6,4,392],t:7,e:"ui-section",a:{label:"Which supplypod bay will you use?"},f:[{p:[7,9,458],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==1?"selected":null'},p:[7,27,476]}],action:"bay1"},f:["Bay #1"]}," ",{p:[8,9,557],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==2?"selected":null'},p:[8,27,575]}],action:"bay2"},f:["Bay #2"]}," ",{p:[9,9,656],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==3?"selected":null'},p:[9,27,674]}],action:"bay3"},f:["Bay #3"]}," ",{p:[10,9,755],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.bay"],s:'_0==4?"selected":null'},p:[10,27,773]}],action:"bay4"},f:["Bay #4"]}]}," ",{p:[13,5,871],t:7,e:"ui-section",a:{label:"Useful teleport tools!"},f:[{p:[14,9,926],t:7,e:"ui-button",a:{action:"teleportCentcom"},f:["Teleport to Centcom's Supplypod Loading Bay"]}," ",{p:[15,9,1027],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.oldArea"],s:'_0?null:"disabled"'},p:[15,27,1045]}],action:"teleportBack"},f:["Teleport Back to ",{t:2,x:{r:["data.oldArea"],s:'_0?_0:"where you were"'},p:[15,103,1121]}]}]}," ",{p:[18,5,1210],t:7,e:"ui-section",a:{label:"Keep stuff after launching?"},f:[{p:[19,9,1268],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchClone"],s:'_0?"selected":null'},p:[19,27,1286]}],action:"launchClone","tooltip-side":"left",tooltip:"Choosing this will create a duplicate of the item to be launched in Centcom, allowing you to send one type of item multiple times. Either way, the atoms are forceMoved into the supplypod after it lands (but before it opens)."},f:["Clone and Launch"]}]}," ",{p:[23,5,1668],t:7,e:"ui-section",a:{label:"Launch all at once?"},f:[{p:[24,9,1718],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchChoice"],s:'_0==1?"selected":null'},p:[24,27,1736]}],action:"launchOrdered","tooltip-side":"left",tooltip:'Instead of launching everything in the bay at once, this will "scan" things (one turf-full at a time) in order, left to right and top to bottom. Refreshing will reset the "scanner" to the top-leftmost position.'},f:["Ordered"]}," ",{p:[26,9,2086],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.launchChoice"],s:'_0==2?"selected":null'},p:[26,27,2104]}],action:"launchRandom","tooltip-side":"left",tooltip:"Instead of launching everything in the bay at once, this will launch one random turf of items at a time."},f:["Random"]}]}," ",{p:[30,5,2362],t:7,e:"ui-section",a:{label:"Add an explosion?"},f:[{p:[31,9,2410],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.explosionChoice"],s:'_0==1?"selected":null'},p:[31,27,2428]}],action:"explosionCustom","tooltip-side":"left",tooltip:"This will cause an explosion of whatever size you like (including flame range) to occur as soon as the supplypod lands. Dont worry, supply-pods are explosion-proof!"},f:["Custom Size"]}," ",{p:[33,9,2740],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.explosionChoice"],s:'_0==2?"selected":null'},p:[33,27,2758]}],action:"explosionBus","tooltip-side":"left",tooltip:"This will cause a maxcap explosion (dependent on server config) to occur as soon as the supplypod lands. Dont worry, supply-pods are explosion-proof!"},f:["Adminbus"]}]}," ",{p:[37,5,3066],t:7,e:"ui-section",a:{label:"Extra damage?","(default":"None)"},f:[{p:[38,9,3127],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.damageChoice"],s:'_0==1?"selected":null'},p:[38,27,3145]}],action:"damageCustom","tooltip-side":"left",tooltip:"Anyone caught under the pod when it lands will be dealt this amount of brute damage. Sucks to be them!"},f:["Custom Damage"]}," ",{p:[40,9,3392],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.damageChoice"],s:'_0==2?"selected":null'},p:[40,27,3410]}],action:"damageGib","tooltip-side":"left",tooltip:"This will attempt to gib any mob caught under the pod when it lands, as well as dealing a nice 5000 brute damage. Ya know, just to be sure!"},f:["Gib"]}]}," ",{p:[44,5,3698],t:7,e:"ui-section",a:{label:"Extra effects?"},f:[{p:[45,9,3743],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectStun"],s:'_0?"selected":null'},p:[45,27,3761]}],action:"effectStun","tooltip-side":"left",tooltip:"Anyone who is on the turf when the supplypod is launched will be stunned until the supplypod lands. They cant get away that easy!"},f:["Stun"]}," ",{p:[47,9,4017],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectLimb"],s:'_0?"selected":null'},p:[47,27,4035]}],action:"effectLimb","tooltip-side":"left",tooltip:"This will cause anyone caught under the pod to lose a limb, excluding their head."},f:["Delimb"]}," ",{p:[49,9,4245],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectBluespace"],s:'_0?"selected":null'},p:[49,27,4263]}],action:"effectBluespace","tooltip-side":"left",tooltip:"Gives the supplypod an advanced Bluespace Recyling Device. After opening, the supplypod will be warped directly to the surface of a nearby NT-designated trash planet (/r/ss13)."},f:["Bluespace"]}," ",{p:[51,9,4581],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectStealth"],s:'_0?"selected":null'},p:[51,27,4599]}],action:"effectStealth","tooltip-side":"left",tooltip:'This hides the red target icon from appearing when you launch the supplypod. Combos well with the "Invisible" style. Sneak attack, go!'},f:["Stealth"]}," ",{p:[53,9,4869],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectQuiet"],s:'_0?"selected":null'},p:[53,27,4887]}],action:"effectQuiet","tooltip-side":"left",tooltip:"This will keep the supplypod from making any sounds, except for those specifically set by admins in the Sound section."},f:["Quiet Landing"]}," ",{p:[55,9,5143],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectReverse"],s:'_0?"selected":null'},p:[55,27,5161]}],action:"effectReverse","tooltip-side":"left",tooltip:"This pod will not send any items. Instead, after landing, the supplypod will close (similar to a normal closet closing), and then launch back to the right centcom bay to drop off any new contents."},f:["Reverse Mode"]}," ",{p:[57,9,5498],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectMissile"],s:'_0?"selected":null'},p:[57,27,5516]}],action:"effectMissile","tooltip-side":"left",tooltip:"This pod will not send any items. Instead, it will immediatley delete after landing (Similar visually to setting openDelay & departDelay to 0, but this looks nicer). Useful if you just wanna fuck some shit up. Combos well with the Missile style."},f:["Missile Mode"]}," ",{p:[59,9,5902],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectCircle"],s:'_0?"selected":null'},p:[59,27,5920]}],action:"effectCircle","tooltip-side":"left",tooltip:"This will make the supplypod come in from any angle. Im not sure why this feature exists, but here it is."},f:["Any Descent Angle"]}," ",{p:[61,9,6169],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectBurst"],s:'_0?"selected":null'},p:[61,27,6187]}],action:"effectBurst","tooltip-side":"left",tooltip:"This will make each click launch 5 supplypods inaccuratly around the target turf (a 3x3 area). Combos well with the Missle Mode if you dont want shit lying everywhere after."},f:["Machine Gun Mode"]}," ",{p:[63,9,6501],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectTarget"],s:'_0?"selected":null'},p:[63,27,6519]}],action:"effectTarget","tooltip-side":"left",tooltip:"This will make the supplypod target a specific atom, instead of the mouses position. Smiting does this automatically!"},f:["Specific Target"]}," ",{p:[65,9,6778],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.effectName"],s:'_0?"selected":null'},p:[65,27,6796]}],action:"effectName","tooltip-side":"left",tooltip:"Allows you to add a custom name and description."},f:["Custom Name/Desc"]}]}," ",{p:[69,5,7e3],t:7,e:"ui-section",a:{label:"Sound?"},f:[{p:[70,9,7037],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.landingSound"],s:'_0?"selected":null'},p:[70,27,7055]}],action:"landingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod lands."},f:["Custom Landing Sound"]}," ",{p:[72,10,7245],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.openingSound"],s:'_0?"selected":null'},p:[72,28,7263]}],action:"openingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod opens."},f:["Custom Opening Sound"]}," ",{p:[74,9,7452],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.leavingSound"],s:'_0?"selected":null'},p:[74,27,7470]}],action:"leavingSound","tooltip-side":"left",tooltip:"Choose a sound to play when the pod departs (whether that be delection in the case of a bluespace pod, or leaving for centcom for a reversing pod)."},f:["Custom Leaving Sound"]}," ",{p:[76,9,7764],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.soundVolume"],s:'_0?"selected":null'},p:[76,27,7782]}],action:"soundVolume","tooltip-side":"left",tooltip:"Choose the volume for the sound to play at. Default values are between 1 and 100, but hey, do whatever. Im a tooltip, not a cop."},f:["Admin Sound Volume"]}]}," ",{p:[80,5,8070],t:7,e:"ui-section",a:{label:"Delay timers?"},f:[{p:[81,9,8114],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.landingDelay"],s:'_0!=5?"selected":null'},p:[81,27,8132]}],action:"landingDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to hit the station. By default this value is 0.5 seconds."},f:["Custom Landing Time"]}," ",{p:[83,10,8394],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.openingDelay"],s:'_0!=30?"selected":null'},p:[83,28,8412]}],action:"openingDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to open after landing. Useful for giving whatevers inside the pod a nice dramatic entrance! By default this value is 3 seconds."},f:["Custom Opening Time"]}," ",{p:[85,9,8744],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.departureDelay"],s:'_0!=30?"selected":null'},p:[85,27,8762]}],action:"departureDelay","tooltip-side":"left",tooltip:"Choose the amount of time it takes for the supplypod to leave after landing. By default this value is 3 seconds."},f:["Custom Leaving Time"]}]}," ",{p:[89,5,9047],t:7,e:"ui-section",a:{label:"Style?"},f:[{p:[90,9,9084],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==1?"selected":null'},p:[90,27,9102]}],action:"styleStandard","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to your standard Nanotrasen black and orange. Same color scheme as the normal station-used supplypods."},f:["Standard"]}," ",{p:[92,9,9405],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==2?"selected":null'},p:[92,27,9423]}],action:"styleBluespace","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to the same as the stations upgraded blue-and-white Bluespace Supplypods."},f:["Advanced"]}," ",{p:[94,9,9698],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==4?"selected":null'},p:[94,27,9716]}],action:"styleSyndie","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a menacing black and blood-red. Great for sending meme-ops in style!"},f:["Syndicate"]}," ",{p:[96,9,9987],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==5?"selected":null'},p:[96,27,10005]}],action:"styleBlue","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a menacing black and dark blue. Great for sending deathsquads in style!"},f:["Deathsquad"]}," ",{p:[98,10,10279],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==6?"selected":null'},p:[98,28,10297]}],action:"styleCult","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a blood and rune covered cult pod!"},f:["Cult Pod"]}," ",{p:[100,9,10524],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==7?"selected":null'},p:[100,27,10542]}],action:"styleMissile","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large missile. Combos well with a missile mode, so the missile doesnt stick around after landing."},f:["Missile"]}," ",{p:[102,9,10836],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==8?"selected":null'},p:[102,27,10854]}],action:"styleSMissile","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large blood-red missile. Combos well with missile mode, so the missile doesnt stick around after landing."},f:["Syndicate Missile"]}," ",{p:[104,9,11167],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==9?"selected":null'},p:[104,27,11185]}],action:"styleBox","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom style to a large, dark-green military supply crate."},f:["Supply Crate"]}," ",{p:[106,9,11423],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==10?"selected":null'},p:[106,27,11441]}],action:"styleHONK","tooltip-side":"left",tooltip:"Changes the pods style from the default Centcom color scheme to a colorful, clown inspired look."},f:["HONK"]}," ",{p:[108,9,11670],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==11?"selected":null'},p:[108,27,11688]}],action:"styleFruit","tooltip-side":"left",tooltip:"for when an orange is angry"},f:["Fruit~"]}," ",{p:[110,9,11851],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==12?"selected":null'},p:[110,27,11869]}],action:"styleInvisible","tooltip-side":"left",tooltip:'Makes the supplypod invisible! Useful for when you want to use this feature with a gateway or something. Combos well with the "Stealth" and "Quiet Landing" effects.'},f:["Invisible"]}," ",{p:[112,9,12175],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.styleChoice"],s:'_0==13?"selected":null'},p:[112,27,12193]}],action:"styleGondola","tooltip-side":"left",tooltip:"this gondola can control when he wants to deliver his supplies if he has a smart enough mind, so offer up his body to ghosts for maximum enjoyment. (Make sure to turn off bluespace and set a arbitrarily high open-time if you do!)"},f:["Gondola (alive)"]}]}]}," ",{p:[117,1,12597],t:7,e:"ui-display",f:[{p:[118,5,12615],t:7,e:"ui-section",a:{label:[{t:2,r:"data.numObjects",p:[118,26,12636]}," turfs with launchable atoms found in Bay #",{t:2,r:"data.bay",p:[118,88,12698]}]},f:[{p:[119,9,12722],t:7,e:"ui-button",a:{action:"refresh","tooltip-side":"right",tooltip:"Manually refreshes the possible things to launch in the pod bay."},f:["Refresh Pod Bay"]}]}," ",{p:[123,5,12909],t:7,e:"ui-section",f:[{p:[124,9,12931],t:7,e:"ui-button",a:{style:[{t:2,x:{r:["data.giveLauncher"],s:'_0?"selected":null'},p:[124,27,12949]}],action:"giveLauncher","tooltip-side":"right",tooltip:"THE CODEX ASTARTES CALLS THIS MANEUVER: STEEL RAIN!!"},f:["Enter Launch Mode"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],378:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Energy"},f:[{p:[3,5,64],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.maxEnergy",p:[3,26,85]}],value:[{t:2,r:"data.energy",p:[3,53,112]}]},f:[{t:2,x:{r:["adata.energy"],s:"Math.fixed(_0)"},p:[3,70,129]}," Units"]}]}]}," ",{p:[6,1,206],t:7,e:"ui-display",a:{title:"Saved Recipes",button:0},f:[{p:[7,3,251],t:7,e:"ui-section",f:[{p:[8,5,269],t:7,e:"ui-button",a:{icon:"plus",action:"add_recipe"},f:["Add Recipe"]}," ",{p:[9,2,337],t:7,e:"ui-button",a:{icon:"minus",action:"clear_recipes"},f:["Clear Recipes"]}," ",{t:4,f:[{p:[11,7,445],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense_recipe",params:['{"recipe": "',{t:2,r:"contents",p:[11,80,518]},'"}']},f:[{t:2,r:"recipe_name",p:[11,96,534]}]}],n:52,r:"data.recipes",p:[10,5,415]}]}]}," ",{p:{button:[{t:4,f:[{p:[18,7,719],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.amount","."],s:'_0==_1?"selected":null'},p:[18,37,749]}],action:"amount",params:['{"target": ',{t:2,r:".",p:[18,114,826]},"}"]},f:[{t:2,r:".",p:[18,122,834]}]}],n:52,r:"data.beakerTransferAmounts",p:[17,5,675]}]},t:7,e:"ui-display",a:{title:"Dispense",button:0},f:[" ",{p:[21,3,886],t:7,e:"ui-section",f:[{t:4,f:[{p:[23,7,936],t:7,e:"ui-button",a:{grid:0,icon:"tint",action:"dispense",params:['{"reagent": "',{t:2,r:"id",p:[23,74,1003]},'"}']},f:[{t:2,r:"title",p:[23,84,1013]}]}],n:52,r:"data.chemicals",p:[22,5,904]}]}]}," ",{p:{button:[{t:4,f:[{p:[30,7,1190],t:7,e:"ui-button",a:{icon:"minus",action:"remove",params:['{"amount": ',{t:2,r:".",p:[30,66,1249]},"}"]},f:[{t:2,r:".",p:[30,74,1257]}]}],n:52,r:"data.beakerTransferAmounts",p:[29,5,1146]}," ",{p:[32,5,1295],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[32,36,1326]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[34,3,1423],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[36,7,1493],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[36,13,1499]},"/",{t:2,r:"data.beakerMaxVolume",p:[36,55,1541]}," Units"]}," ",{p:[37,4,1583],t:7,e:"span",f:["pH: ",{t:2,x:{r:["adata.beakerCurrentpH","adata.partRating"],s:"Math.round(_0*_1)/_1"},p:[37,14,1593]}]}," ",{p:[38,7,1679],t:7,e:"br"}," ",{t:4,f:[{p:[40,9,1732],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[40,52,1775]}," units of ",{t:2,r:"name",p:[40,87,1810]}]},{p:[40,102,1825],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[39,7,1692]},{t:4,n:51,f:[{p:[42,9,1856],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[35,5,1458]},{t:4,n:51,f:[{p:[45,7,1932],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],379:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[2,3,35],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,5,67],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isActive"],s:'_0?"power-off":"close"'},p:[3,22,84]}],style:[{t:2,x:{r:["data.isActive"],s:'_0?"selected":null'},p:[4,10,137]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,10,186]}],action:"power"},f:[{t:2,x:{r:["data.isActive"],s:'_0?"On":"Off"'},p:[6,18,249]}]}]}," ",{p:[8,3,314],t:7,e:"ui-section",a:{label:"Target"},f:[{p:[9,4,346],t:7,e:"ui-button",a:{icon:"pencil",action:"temperature",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[9,79,421]}," K"]}]}]}," ",{p:{button:[{p:[14,5,564],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[14,36,595]}],action:"eject"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[16,3,692],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[18,7,762],t:7,e:"span",f:["Temperature: ",{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[18,26,781]}," K"]}," ",{p:[19,4,828],t:7,e:"br"}," ",{p:[20,7,842],t:7,e:"span",f:["pH: ",{t:2,x:{r:["adata.currentpH","adata.partRating"],s:"Math.round(_0*_1)/_1"},p:[20,17,852]}]}," ",{p:[21,7,932],t:7,e:"br"}," ",{t:4,f:[{p:[23,3,980],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[23,46,1023]}," units of ",{t:2,r:"name",p:[23,81,1058]}]},{p:[23,96,1073],t:7,e:"br"}," ",{t:4,f:[{p:[25,4,1111],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:["Purity: ",{t:2,x:{r:["purity"],s:"Math.fixed(_0,2)"},p:[25,55,1162]}]},{p:[25,87,1194],t:7,e:"br"}],n:50,r:"data.showPurity",p:[24,3,1083]}],n:52,r:"adata.beakerContents",p:[22,7,946]},{t:4,n:51,f:[{p:[28,9,1237],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[17,5,727]},{t:4,n:51,f:[{p:[31,7,1313],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],380:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:["\ufeff",{t:4,f:[" ",{p:[2,2,33],t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[{p:[3,3,71],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"close"'},p:[3,20,88]}],style:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"selected":null'},p:[4,11,144]}],state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,11,200]}],action:"eject"},f:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"Eject":"No beaker"'},p:[7,5,269]}]}," ",{p:[10,3,341],t:7,e:"ui-section",f:[{t:4,f:[{t:4,f:[{p:[13,6,427],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[13,25,446]}," units of ",{t:2,r:"name",p:[13,60,481]}],nowrap:0},f:[{p:[14,7,506],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[15,8,556],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[15,61,609]},'", "amount": 1}']},f:["1"]}," ",{p:[16,8,654],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[16,61,707]},'", "amount": 5}']},f:["5"]}," ",{p:[17,8,752],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[17,61,805]},'", "amount": 10}']},f:["10"]}," ",{p:[18,8,852],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[18,61,905]},'", "amount": 1000}']},f:["All"]}," ",{p:[19,8,955],t:7,e:"ui-button",a:{action:"transferToBuffer",params:['{"id": "',{t:2,r:"id",p:[19,61,1008]},'", "amount": -1}']},f:["Custom"]}," ",{p:[20,8,1059],t:7,e:"ui-button",a:{action:"analyzeBeak",params:['{"id": "',{t:2,r:"id",p:[20,56,1107]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.beakerContents",p:[12,5,391]},{t:4,n:51,f:[{p:[24,5,1189],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"data.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,4,358]},{t:4,n:51,f:[{p:[27,5,1260],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}," ",{p:[32,2,1348],t:7,e:"ui-display",a:{title:"Buffer"},f:[{p:[33,3,1379],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?null:"selected"'},p:[33,41,1417]}]},f:["Destroy"]}," ",{p:[34,3,1475],t:7,e:"ui-button",a:{action:"toggleMode",state:[{t:2,x:{r:["data.mode"],s:'_0?"selected":null'},p:[34,41,1513]}]},f:["Transfer to Beaker"]}," ",{p:[35,3,1582],t:7,e:"ui-section",f:[{t:4,f:[{p:[37,5,1634],t:7,e:"ui-section",a:{label:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[37,24,1653]}," units of ",{t:2,r:"name",p:[37,59,1688]}],nowrap:0},f:[{p:[38,6,1712],t:7,e:"div",a:{"class":"content",style:"float:right"},f:[{p:[39,7,1761],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[39,62,1816]},'", "amount": 1}']},f:["1"]}," ",{p:[40,7,1860],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[40,62,1915]},'", "amount": 5}']},f:["5"]}," ",{p:[41,7,1959],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[41,62,2014]},'", "amount": 10}']},f:["10"]}," ",{p:[42,7,2060],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[42,62,2115]},'", "amount": 1000}']},f:["All"]}," ",{p:[43,7,2164],t:7,e:"ui-button",a:{action:"transferFromBuffer",params:['{"id": "',{t:2,r:"id",p:[43,62,2219]},'", "amount": -1}']},f:["Custom"]}," ",{p:[44,7,2269],t:7,e:"ui-button",a:{action:"analyzeBuff",params:['{"id": "',{t:2,r:"id",p:[44,55,2317]},'"}']},f:["Analyze"]}]}]}],n:52,r:"data.bufferContents",p:[36,4,1599]}]}]}," ",{t:4,f:[{p:[52,3,2453],t:7,e:"ui-display",a:{title:"Pills, Bottles and Patches"},f:[{t:4,f:[{p:[54,5,2537],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["id","data.chosenPillStyle"],s:'_0==_1?"selected":null'},p:[54,23,2555]}],action:"pillStyle",params:['{"id": "',{t:2,r:"id",p:[54,108,2640]},'"}']},f:[{t:3,r:"htmltag",p:[54,118,2650]}]}],n:52,r:"data.pillStyles",p:[53,4,2506]}," ",{p:[56,4,2694],t:7,e:"br"}," ",{t:4,f:[{p:[58,5,2740],t:7,e:"ui-button",a:{action:"ejectp",state:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?null:"disabled"'},p:[58,39,2774]}]},f:[{t:2,x:{r:["data.isPillBottleLoaded"],s:'_0?"Eject":"No Pill bottle loaded"'},p:[58,88,2823]}]}," ",{p:[59,5,2904],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.pillBotContent",p:[59,27,2926]},"/",{t:2,r:"data.pillBotMaxContent",p:[59,51,2950]}]}],n:50,r:"data.isPillBottleLoaded",p:[57,4,2703]},{t:4,n:51,f:[{p:[61,5,3002],t:7,e:"span",a:{"class":"average"},f:["No Pillbottle"]}],r:"data.isPillBottleLoaded"}," ",{p:[64,4,3063],t:7,e:"br"}," ",{p:[65,4,3073],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[65,63,3132]}]},f:["Create Pill (max 50µ)"]}," ",{p:[66,4,3216],t:7,e:"br"}," ",{p:[67,4,3226],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[67,63,3285]}]},f:["Create Multiple Pills"]}," ",{p:[68,4,3369],t:7,e:"br"}," ",{p:[69,4,3379],t:7,e:"br"}," ",{p:[70,4,3389],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[70,64,3449]}]},f:["Create Patch (max 40µ)"]}," ",{p:[71,4,3534],t:7,e:"br"}," ",{p:[72,4,3544],t:7,e:"ui-button",a:{action:"createPatch",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[72,64,3604]}]},f:["Create Multiple Patches"]}," ",{p:[73,4,3690],t:7,e:"br"}," ",{p:[74,4,3700],t:7,e:"br"}," ",{p:[75,4,3710],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[75,65,3771]}]},f:["Create Bottle (max 30µ)"]}," ",{p:[76,4,3857],t:7,e:"br"}," ",{p:[77,4,3867],t:7,e:"ui-button",a:{
+action:"createBottle",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[77,65,3928]}]},f:["Dispense Buffer to Bottles"]}," ",{p:[78,4,4017],t:7,e:"br"}," ",{p:[79,4,4027],t:7,e:"br"}," ",{p:[80,4,4037],t:7,e:"ui-button",a:{action:"createVial",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[80,63,4096]}]},f:["Create Hypo Vial (max 60µ)"]}," ",{p:[81,4,4185],t:7,e:"br"}," ",{p:[82,4,4195],t:7,e:"ui-button",a:{action:"createVial",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[82,63,4254]}]},f:["Dispense Buffer to Hypo vials"]}," ",{p:[83,4,4347],t:7,e:"br"}," ",{p:[84,4,4357],t:7,e:"br"}," ",{p:[85,4,4367],t:7,e:"ui-button",a:{action:"createDart",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[85,63,4426]}]},f:["Create SmartDart (max 20µ)"]}," ",{p:[86,4,4515],t:7,e:"br"}," ",{p:[87,4,4525],t:7,e:"ui-button",a:{action:"createDart",params:'{"many": 1}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[87,63,4584]}]},f:["Create Multiple SmartDarts"]}," ",{p:[88,4,4674],t:7,e:"br"}]}],n:50,x:{r:["data.condi"],s:"!_0"},p:[51,2,2430]},{t:4,n:51,f:[{p:[93,3,4717],t:7,e:"ui-display",a:{title:"Condiments bottles and packs"},f:[{p:[94,4,4772],t:7,e:"ui-button",a:{action:"createPill",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[94,63,4831]}]},f:["Create Pack (max 10µ)"]}," ",{p:[95,4,4915],t:7,e:"br"}," ",{p:[96,4,4925],t:7,e:"br"}," ",{p:[97,4,4935],t:7,e:"ui-button",a:{action:"createBottle",params:'{"many": 0}',state:[{t:2,x:{r:["data.bufferContents"],s:'_0?null:"disabled"'},p:[97,65,4996]}]},f:["Create Bottle (max 50µ)"]}]}],x:{r:["data.condi"],s:"!_0"}}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,2,1]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.screen"],s:'_0=="analyze"'},f:[{p:[101,2,5144],t:7,e:"ui-display",a:{title:[{t:2,r:"data.analyzeVars.name",p:[101,20,5162]}]},f:[{p:[102,3,5193],t:7,e:"span",a:{"class":"highlight"},f:["Description:"]}," ",{p:[103,3,5241],t:7,e:"span",a:{"class":"content",style:"float:center"},f:[{t:2,r:"data.analyzeVars.description",p:[103,46,5284]}]}," ",{p:[104,3,5327],t:7,e:"br"}," ",{p:[105,3,5336],t:7,e:"span",a:{"class":"highlight"},f:["Color:"]}," ",{p:[106,3,5378],t:7,e:"span",a:{style:["color: ",{t:2,r:"data.analyzeVars.color",p:[106,23,5398]},"; background-color: ",{t:2,r:"data.analyzeVars.color",p:[106,69,5444]}]},f:[{t:2,r:"data.analyzeVars.color",p:[106,97,5472]}]}," ",{p:[107,3,5509],t:7,e:"br"}," ",{p:[108,3,5518],t:7,e:"span",a:{"class":"highlight"},f:["State:"]}," ",{p:[109,3,5560],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.state",p:[109,25,5582]}]}," ",{p:[110,3,5619],t:7,e:"br"}," ",{p:[111,3,5628],t:7,e:"span",a:{"class":"highlight"},f:["Metabolization Rate:"]}," ",{p:[112,3,5684],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.metaRate",p:[112,25,5706]},"µ/minute"]}," ",{p:[113,3,5754],t:7,e:"br"}," ",{p:[114,3,5763],t:7,e:"span",a:{"class":"highlight"},f:["Overdose Threshold:"]}," ",{p:[115,3,5818],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.overD",p:[115,25,5840]}]}," ",{p:[116,3,5877],t:7,e:"br"}," ",{p:[117,3,5886],t:7,e:"span",a:{"class":"highlight"},f:["Addiction Threshold:"]}," ",{p:[118,3,5942],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.addicD",p:[118,25,5964]}]}," ",{p:[119,3,6002],t:7,e:"br"}," ",{t:4,f:[{p:[121,4,6041],t:7,e:"span",a:{"class":"highlight"},f:["Minumum Reaction Temperature:"]}," ",{p:[122,4,6107],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.minTemp",p:[122,26,6129]},"K"]}," ",{p:[123,4,6170],t:7,e:"br"}," ",{p:[124,4,6180],t:7,e:"span",a:{"class":"highlight"},f:["Optimal Reaction Temperature:"]}," ",{p:[125,4,6246],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.maxTemp",p:[125,26,6268]},"K"]}," ",{p:[126,4,6309],t:7,e:"br"}," ",{p:[127,4,6319],t:7,e:"span",a:{"class":"highlight"},f:["Explosion Reaction Temperature:"]}," ",{p:[128,4,6387],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.eTemp",p:[128,26,6409]},"K"]}," ",{p:[129,4,6448],t:7,e:"br"}," ",{p:[130,4,6458],t:7,e:"span",a:{"class":"highlight"},f:["Optimal reaction pH:"]}," ",{p:[131,4,6515],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.pHpeak",p:[131,26,6537]}]}," ",{p:[132,4,6576],t:7,e:"br"}," ",{p:[133,4,6586],t:7,e:"span",a:{"class":"highlight"},f:["Current Purity:"]}," ",{p:[134,4,6638],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.purityF",p:[134,26,6660]}]}," ",{p:[135,4,6700],t:7,e:"br"}," ",{p:[136,4,6710],t:7,e:"span",a:{"class":"highlight"},f:["Inverse Purity Threshold:"]}," ",{p:[137,4,6772],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.inverseRatioF",p:[137,26,6794]}]}," ",{p:[138,4,6840],t:7,e:"br"}," ",{p:[139,4,6850],t:7,e:"span",a:{"class":"highlight"},f:["Explosion Purity Threshold:"]}," ",{p:[140,4,6914],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.analyzeVars.purityE",p:[140,26,6936]}]}," ",{p:[141,4,6976],t:7,e:"br"}],n:50,r:"data.fermianalyze",p:[120,3,6011]}," ",{p:[143,3,6996],t:7,e:"br"}," ",{p:[144,3,7005],t:7,e:"ui-button",a:{action:"goScreen",params:'{"screen": "home"}'},f:["Back"]}]}]}],x:{r:["data.screen"],s:'_0=="home"'}}]},e.exports=a.extend(r.exports)},{341:341}],381:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Recipient Contents"},f:[{p:[2,2,42],t:7,e:"ui-section",f:[{p:[3,3,58],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[3,34,89]}],action:"ejectBeaker"},f:["Eject"]}," ",{p:[4,3,176],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[4,35,208]}],action:"input"},f:["Input"]}," ",{p:[5,3,289],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[5,35,321]}],action:"amount"},f:[{t:2,r:"data.amount",p:[5,96,382]},"U"]}," ",{p:[6,3,414],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?"disabled":null'},p:[6,33,444]}],action:"makecup"},f:["Create Beaker"]}]}]}," ",{p:[9,1,564],t:7,e:"ui-display",a:{title:"Recipient"},f:[{p:[10,2,597],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[12,4,662],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[12,10,668]},"/",{t:2,r:"data.beakerMaxVolume",p:[12,52,710]}," Units"]}," ",{t:4,f:[{p:[14,5,788],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[14,48,831]}," units of ",{t:2,r:"name",p:[14,83,866]}]},{p:[14,98,881],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[13,4,752]},{t:4,n:51,f:[{p:[16,5,905],t:7,e:"span",a:{"class":"bad"},f:["Recipient Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[11,3,630]},{t:4,n:51,f:[{p:[19,4,976],t:7,e:"span",a:{"class":"average"},f:["No Recipient"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],382:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-button",a:{action:"toggle"},f:[{t:2,x:{r:["data.recollection"],s:'_0?"Recital":"Recollection"'},p:[2,30,43]}]}]}," ",{t:4,f:[{p:[5,3,149],t:7,e:"ui-display",f:[{t:3,r:"data.rec_text",p:[6,3,165]}," ",{t:4,f:[{p:[8,4,231],t:7,e:"br"},{p:[8,8,235],t:7,e:"ui-button",a:{action:"rec_category",params:['{"category": "',{t:2,r:"name",p:[8,63,290]},'"}']},f:[{t:3,r:"name",p:[8,75,302]}," - ",{t:3,r:"desc",p:[8,88,315]}]}],n:52,r:"data.recollection_categories",p:[7,3,188]}," ",{t:3,r:"data.rec_section",p:[10,3,354]}," ",{t:3,r:"data.rec_binds",p:[11,3,380]}]}],n:50,r:"data.recollection",p:[4,1,120]},{t:4,n:51,f:[{p:[14,2,431],t:7,e:"ui-display",a:{title:"Power",button:0},f:[{p:[15,4,469],t:7,e:"ui-section",f:[{t:3,r:"data.power",p:[16,6,488]}]}]}," ",{p:[19,2,541],t:7,e:"ui-display",f:[{p:[20,3,557],t:7,e:"ui-section",f:[{p:[21,4,574],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Driver"?"selected":null'},p:[21,22,592]}],action:"select",params:'{"category": "Driver"}'},f:["Driver"]}," ",{p:[22,4,715],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Script"?"selected":null'},p:[22,22,733]}],action:"select",params:'{"category": "Script"}'},f:["Scripts"]}," ",{p:[23,4,857],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.selected"],s:'_0=="Application"?"selected":null'},p:[23,22,875]}],action:"select",params:'{"category": "Application"}'},f:["Applications"]}," ",{p:[24,4,1014],t:7,e:"br"},{t:3,r:"data.tier_info",p:[24,8,1018]}]}," ",{p:[26,3,1059],t:7,e:"ui-section",f:[{t:3,r:"data.scripturecolors",p:[27,4,1076]}]},{p:[28,16,1119],t:7,e:"hr"}," ",{p:[29,3,1127],t:7,e:"ui-section",f:[{t:4,f:[{p:[31,4,1172],t:7,e:"div",f:[{p:[31,9,1177],t:7,e:"ui-button",a:{tooltip:[{t:3,r:"tip",p:[31,29,1197]}],"tooltip-side":"right",action:"recite",params:['{"category": "',{t:2,r:"type",p:[31,99,1267]},'"}']},f:["Recite ",{t:3,r:"required",p:[31,118,1286]}]}," ",{t:4,f:[{t:4,f:[{p:[34,6,1362],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[34,53,1409]},'"}']},f:["Unbind ",{t:3,r:"bound",p:[34,72,1428]}]}],n:50,r:"bound",p:[33,5,1342]},{t:4,n:51,f:[{p:[36,6,1472],t:7,e:"ui-button",a:{action:"bind",params:['{"category": "',{t:2,r:"type",p:[36,53,1519]},'"}']},f:["Quickbind"]}],r:"bound"}],n:50,r:"quickbind",p:[32,6,1319]}," ",{t:3,r:"name",p:[39,6,1586]}," ",{t:3,r:"descname",p:[39,17,1597]}," ",{t:3,r:"invokers",p:[39,32,1612]}]}],n:52,r:"data.scripture",p:[30,3,1143]}]}]}],r:"data.recollection"}]},e.exports=a.extend(r.exports)},{341:341}],383:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Codex Gigas"},f:[{p:[2,2,35],t:7,e:"ui-section",f:[{t:2,r:"data.name",p:[3,3,51]}]}," ",{p:[5,5,86],t:7,e:"ui-section",a:{label:"Prefix"},f:[{p:[6,3,117],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[6,22,136]}],action:"Dark "},f:["Dark"]}," ",{p:[7,3,221],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[7,22,240]}],action:"Hellish "},f:["Hellish"]}," ",{p:[8,3,331],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[8,22,350]}],action:"Fallen "},f:["Fallen"]}," ",{p:[9,3,439],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[9,22,458]}],action:"Fiery "},f:["Fiery"]}," ",{p:[10,3,545],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[10,22,564]}],action:"Sinful "},f:["Sinful"]}," ",{p:[11,3,653],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[11,22,672]}],action:"Blood "},f:["Blood"]}," ",{p:[12,3,759],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==1?null:"disabled"'},p:[12,22,778]}],action:"Fluffy "},f:["Fluffy"]}]}," ",{p:[14,5,888],t:7,e:"ui-section",a:{label:"Title"},f:[{p:[15,3,918],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[15,22,937]}],action:"Lord "},f:["Lord"]}," ",{p:[16,3,1022],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[16,22,1041]}],action:"Prelate "},f:["Prelate"]}," ",{p:[17,3,1132],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[17,22,1151]}],action:"Count "},f:["Count"]}," ",{p:[18,3,1238],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[18,22,1257]}],action:"Viscount "},f:["Viscount"]}," ",{p:[19,3,1350],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[19,22,1369]}],action:"Vizier "},f:["Vizier"]}," ",{p:[20,3,1458],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[20,22,1477]}],action:"Elder "},f:["Elder"]}," ",{p:[21,3,1564],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=2?null:"disabled"'},p:[21,22,1583]}],action:"Adept "},f:["Adept"]}]}," ",{p:[23,5,1691],t:7,e:"ui-section",a:{label:"Name"},f:[{p:[24,3,1720],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[24,22,1739]}],action:"hal"},f:["hal"]}," ",{p:[25,3,1821],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[25,22,1840]}],action:"ve"},f:["ve"]}," ",{p:[26,3,1920],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[26,22,1939]}],action:"odr"},f:["odr"]}," ",{p:[27,3,2021],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[27,22,2040]}],action:"neit"},f:["neit"]}," ",{p:[28,3,2124],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[28,22,2143]}],action:"ci"},f:["ci"]}," ",{p:[29,3,2223],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[29,22,2242]}],action:"quon"},f:["quon"]}," ",{p:[30,3,2326],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[30,22,2345]}],action:"mya"},f:["mya"]}," ",{p:[31,3,2427],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[31,22,2446]}],action:"folth"},f:["folth"]}," ",{p:[32,3,2532],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[32,22,2551]}],action:"wren"},f:["wren"]}," ",{p:[33,3,2635],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[33,22,2654]}],action:"geyr"},f:["geyr"]}," ",{p:[34,3,2738],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[34,22,2757]}],action:"hil"},f:["hil"]}," ",{p:[35,3,2839],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[35,22,2858]}],action:"niet"},f:["niet"]}," ",{p:[36,3,2942],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[36,22,2961]}],action:"twou"},f:["twou"]}," ",{p:[37,3,3045],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[37,22,3064]}],action:"phi"},f:["phi"]}," ",{p:[38,3,3146],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0<=4?null:"disabled"'},p:[38,22,3165]}],action:"coa"},f:["coa"]}]}," ",{p:[40,5,3268],t:7,e:"ui-section",a:{label:"suffix"},f:[{p:[41,3,3299],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[41,22,3318]}],action:" the Red"},f:["the Red"]}," ",{p:[42,3,3409],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[42,22,3428]}],action:" the Soulless"},f:["the Soulless"]}," ",{p:[43,3,3529],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[43,22,3548]}],action:" the Master"},f:["the Master"]}," ",{p:[44,3,3645],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[44,22,3664]}],action:", the Lord of all things"},f:["the Lord of all things"]}," ",{p:[45,3,3786],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0==4?null:"disabled"'},p:[45,22,3805]}],action:", Jr."},f:["jr"]}]}," ",{p:[47,5,3909],t:7,e:"ui-section",a:{label:"submit"},f:[{p:[48,3,3941],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.currentSection"],s:'_0>=4?null:"disabled"'},p:[48,21,3959]}],action:"search"},f:["search"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],384:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[2,1,2],t:7,e:"ui-button",a:{icon:"circle",action:"clean_order"},f:["Clear Order"]},{p:[2,70,71],t:7,e:"br"},{p:[2,74,75],t:7,e:"br"}," ",{p:[3,1,81],t:7,e:"i",f:["Your new computer device you always dreamed of is just four steps away..."]},{p:[3,81,161],t:7,e:"hr"}," ",{t:4,f:[" ",{p:[5,1,223],t:7,e:"div",a:{"class":"item"},f:[{p:[6,2,244],t:7,e:"h2",f:["Step 1: Select your device type"]}," ",{p:[7,2,287],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "1"}'},f:["Laptop"]}," ",{p:[8,2,377],t:7,e:"ui-button",a:{icon:"calc",action:"pick_device",params:'{"pick" : "2"}'},f:["LTablet"]}]}],n:50,x:{r:["data.state"],s:"_0==0"},p:[4,1,167]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.state"],s:"_0==1"},f:[{p:[11,1,502],t:7,e:"div",a:{"class":"item"},f:[{p:[12,2,523],t:7,e:"h2",f:["Step 2: Personalise your device"]}," ",{p:[13,2,566],t:7,e:"table",f:[{p:[14,3,577],t:7,e:"tr",f:[{p:[15,4,586],t:7,e:"td",f:[{p:[15,8,590],t:7,e:"b",f:["Current Price:"]}]},{p:[16,4,616],t:7,e:"td",f:[{t:2,r:"data.totalprice",p:[16,8,620]},"C"]}]}," ",{p:[18,3,653],t:7,e:"tr",f:[{p:[19,4,663],t:7,e:"td",f:[{p:[19,8,667],t:7,e:"b",f:["Battery:"]}]},{p:[20,4,687],t:7,e:"td",f:[{p:[20,8,691],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "1"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==1?"selected":null'},p:[20,73,756]}]},f:["Standard"]}]},{p:[21,4,827],t:7,e:"td",f:[{p:[21,8,831],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "2"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==2?"selected":null'},p:[21,73,896]}]},f:["Upgraded"]}]},{p:[22,4,967],t:7,e:"td",f:[{p:[22,8,971],t:7,e:"ui-button",a:{action:"hw_battery",params:'{"battery" : "3"}',state:[{t:2,x:{r:["data.hw_battery"],s:'_0==3?"selected":null'},p:[22,73,1036]}]},f:["Advanced"]}]}]}," ",{p:[24,3,1115],t:7,e:"tr",f:[{p:[25,4,1124],t:7,e:"td",f:[{p:[25,8,1128],t:7,e:"b",f:["Hard Drive:"]}]},{p:[26,4,1151],t:7,e:"td",f:[{p:[26,8,1155],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "1"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==1?"selected":null'},p:[26,67,1214]}]},f:["Standard"]}]},{p:[27,4,1282],t:7,e:"td",f:[{p:[27,8,1286],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "2"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==2?"selected":null'},p:[27,67,1345]}]},f:["Upgraded"]}]},{p:[28,4,1413],t:7,e:"td",f:[{p:[28,8,1417],t:7,e:"ui-button",a:{action:"hw_disk",params:'{"disk" : "3"}',state:[{t:2,x:{r:["data.hw_disk"],s:'_0==3?"selected":null'},p:[28,67,1476]}]},f:["Advanced"]}]}]}," ",{p:[30,3,1552],t:7,e:"tr",f:[{p:[31,4,1561],t:7,e:"td",f:[{p:[31,8,1565],t:7,e:"b",f:["Network Card:"]}]},{p:[32,4,1590],t:7,e:"td",f:[{p:[32,8,1594],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "0"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==0?"selected":null'},p:[32,73,1659]}]},f:["None"]}]},{p:[33,4,1726],t:7,e:"td",f:[{p:[33,8,1730],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "1"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==1?"selected":null'},p:[33,73,1795]}]},f:["Standard"]}]},{p:[34,4,1866],t:7,e:"td",f:[{p:[34,8,1870],t:7,e:"ui-button",a:{action:"hw_netcard",params:'{"netcard" : "2"}',state:[{t:2,x:{r:["data.hw_netcard"],s:'_0==2?"selected":null'},p:[34,73,1935]}]},f:["Advanced"]}]}]}," ",{p:[36,3,2014],t:7,e:"tr",f:[{p:[37,4,2023],t:7,e:"td",f:[{p:[37,8,2027],t:7,e:"b",f:["Nano Printer:"]}]},{p:[38,4,2052],t:7,e:"td",f:[{p:[38,8,2056],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "0"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==0?"selected":null'},p:[38,73,2121]}]},f:["None"]}]},{p:[39,4,2190],t:7,e:"td",f:[{p:[39,8,2194],t:7,e:"ui-button",a:{action:"hw_nanoprint",params:'{"print" : "1"}',state:[{t:2,x:{r:["data.hw_nanoprint"],s:'_0==1?"selected":null'},p:[39,73,2259]}]},f:["Standard"]}]}]}," ",{p:[41,3,2340],t:7,e:"tr",f:[{p:[42,4,2349],t:7,e:"td",f:[{p:[42,8,2353],t:7,e:"b",f:["Card Reader:"]}]},{p:[43,4,2377],t:7,e:"td",f:[{p:[43,8,2381],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "0"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==0?"selected":null'},p:[43,67,2440]}]},f:["None"]}]},{p:[44,4,2504],t:7,e:"td",f:[{p:[44,8,2508],t:7,e:"ui-button",a:{action:"hw_card",params:'{"card" : "1"}',state:[{t:2,x:{r:["data.hw_card"],s:'_0==1?"selected":null'},p:[44,67,2567]}]},f:["Standard"]}]}]}]}," ",{t:4,f:[" ",{p:[49,4,2706],t:7,e:"table",f:[{p:[50,5,2719],t:7,e:"tr",f:[{p:[51,6,2730],t:7,e:"td",f:[{p:[51,10,2734],t:7,e:"b",f:["Processor Unit:"]}]},{p:[52,6,2763],t:7,e:"td",f:[{p:[52,10,2767],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "1"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==1?"selected":null'},p:[52,67,2824]}]},f:["Standard"]}]},{p:[53,6,2893],t:7,e:"td",f:[{p:[53,10,2897],t:7,e:"ui-button",a:{action:"hw_cpu",params:'{"cpu" : "2"}',state:[{t:2,x:{r:["data.hw_cpu"],s:'_0==2?"selected":null'},p:[53,67,2954]}]},f:["Advanced"]}]}]}," ",{p:[55,5,3033],t:7,e:"tr",f:[{p:[56,6,3044],t:7,e:"td",f:[{p:[56,10,3048],t:7,e:"b",f:["Tesla Relay:"]}]},{p:[57,6,3074],t:7,e:"td",f:[{p:[57,10,3078],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "0"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==0?"selected":null'},p:[57,71,3139]}]},f:["None"]}]},{p:[58,6,3206],t:7,e:"td",f:[{p:[58,10,3210],t:7,e:"ui-button",a:{action:"hw_tesla",params:'{"tesla" : "1"}',state:[{t:2,x:{r:["data.hw_tesla"],s:'_0==1?"selected":null'},p:[58,71,3271]}]},f:["Standard"]}]}]}]}],n:50,x:{r:["data.devtype"],s:"_0!=2"},p:[48,3,2659]}," ",{p:[62,3,3374],t:7,e:"table",f:[{p:[63,4,3386],t:7,e:"tr",f:[{p:[64,5,3396],t:7,e:"td",f:[{p:[64,9,3400],t:7,e:"b",f:["Confirm Order:"]}]},{p:[65,5,3427],t:7,e:"td",f:[{p:[65,9,3431],t:7,e:"ui-button",a:{action:"confirm_order"},f:["CONFIRM"]}]}]}]}," ",{p:[69,2,3512],t:7,e:"hr"}," ",{p:[70,2,3519],t:7,e:"b",f:["Battery"]}," allows your device to operate without external utility power source. Advanced batteries increase battery life.",{p:[70,127,3644],t:7,e:"br"}," ",{p:[71,2,3651],t:7,e:"b",f:["Hard Drive"]}," stores file on your device. Advanced drives can store more files, but use more power, shortening battery life.",{p:[71,130,3779],t:7,e:"br"}," ",{p:[72,2,3786],t:7,e:"b",f:["Network Card"]}," allows your device to wirelessly connect to stationwide NTNet network. Basic cards are limited to on-station use, while advanced cards can operate anywhere near the station, which includes the asteroid outposts.",{p:[72,233,4017],t:7,e:"br"}," ",{p:[73,2,4024],t:7,e:"b",f:["Processor Unit"]}," is critical for your device's functionality. It allows you to run programs from your hard drive. Advanced CPUs use more power, but allow you to run more programs on background at once.",{p:[73,208,4230],t:7,e:"br"}," ",{p:[74,2,4237],t:7,e:"b",f:["Tesla Relay"]}," is an advanced wireless power relay that allows your device to connect to nearby area power controller to provide alternative power source. This component is currently unavailable on tablet computers due to size restrictions.",{p:[74,246,4481],t:7,e:"br"}," ",{p:[75,2,4488],t:7,e:"b",f:["Nano Printer"]}," is device that allows for various paperwork manipulations, such as, scanning of documents or printing new ones. This device was certified EcoFriendlyPlus and is capable of recycling existing paper for printing purposes.",{p:[75,241,4727],t:7,e:"br"}," ",{p:[76,2,4734],t:7,e:"b",f:["Card Reader"]}," adds a slot that allows you to manipulate RFID cards. Please note that this is not necessary to allow the device to read your identification, it is just necessary to manipulate other cards."]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&(_0==2)"},f:[" ",{p:[79,2,4981],t:7,e:"h2",f:["Step 3: Payment"]}," ",{p:[80,2,5008],t:7,e:"b",f:["Your device is now ready for fabrication.."]},{p:[80,51,5057],t:7,e:"br"}," ",{p:[81,2,5064],t:7,e:"i",f:["Please ensure the required amount of credits are in the machine, then press purchase."]},{p:[81,94,5156],t:7,e:"br"}," ",{p:[82,2,5163],t:7,e:"i",f:["Current credits: ",{p:[82,22,5183],t:7,e:"b",f:[{t:2,r:"data.credits",p:[82,25,5186]},"C"]}]},{p:[82,50,5211],t:7,e:"br"}," ",{p:[83,2,5218],t:7,e:"i",f:["Total price: ",{p:[83,18,5234],t:7,e:"b",f:[{t:2,r:"data.totalprice",p:[83,21,5237]},"C"]}]},{p:[83,49,5265],t:7,e:"br"},{p:[83,53,5269],t:7,e:"br"}," ",{p:[84,2,5276],t:7,e:"ui-button",a:{action:"purchase",state:[{t:2,x:{r:["data.credits","data.totalprice"],s:'_0>=_1?null:"disabled"'},p:[84,38,5312]}]},f:["PURCHASE"]}]},{t:4,n:50,x:{r:["data.state"],s:"(!(_0==1))&&((!(_0==2))&&(_0==3))"},f:[" ",{p:[87,2,5423],t:7,e:"h2",f:["Step 4: Thank you for your purchase"]},{p:[87,46,5467],t:7,e:"br"}," ",{p:[88,2,5474],t:7,e:"b",f:["Should you experience any issues with your new device, contact your local network admin for assistance."]}]}],x:{r:["data.state"],s:"_0==0"}}]},e.exports=a.extend(r.exports)},{341:341}],385:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,22],t:7,e:"ui-display",f:[{p:[3,2,37],t:7,e:"ui-section",a:{label:"Cap"},f:[{p:[4,3,65],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.is_capped"],s:'_0?"power-off":"close"'},p:[4,20,82]}],style:[{t:2,x:{r:["data.is_capped"],s:'_0?null:"selected"'},p:[4,71,133]}],action:"toggle_cap"},f:[{t:2,x:{r:["data.is_capped"],s:'_0?"On":"Off"'},p:[6,4,202]}]}]}]}],n:50,r:"data.has_cap",p:[1,1,0]},{p:[10,1,288],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,2,419],t:7,e:"ui-section",f:[{p:[15,3,435],t:7,e:"ui-button",a:{action:"select_colour"},f:["Select New Colour"]}]}],n:50,r:"data.can_change_colour",p:[13,1,386]}]}," ",{p:[19,1,540],t:7,e:"ui-display",a:{title:"Stencil"},f:[{t:4,f:[{p:[21,2,599],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[21,21,618]}]},f:[{t:4,f:[{p:[23,7,655],t:7,e:"ui-button",a:{action:"select_stencil",params:['{"item":"',{t:2,r:"item",p:[23,59,707]},'"}'],style:[{t:2,x:{r:["item","data.selected_stencil"],s:'_0==_1?"selected":null'},p:[24,12,731]}]},f:[{t:2,r:"item",p:[25,4,791]}]}],n:52,r:"items",p:[22,3,632]}]}],n:52,r:"data.drawables",p:[20,3,572]}]}," ",{p:[31,1,874],t:7,e:"ui-display",a:{title:"Text Mode"},f:[{p:[32,2,907],t:7,e:"ui-section",a:{label:"Current Buffer"},f:[{t:2,r:"data.text_buffer",p:[32,37,942]}]}," ",{p:[34,2,981],t:7,e:"ui-section",f:[{p:[34,14,993],t:7,e:"ui-button",a:{action:"enter_text"},f:["New Text"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],386:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{isHead:function(t){return t%10==0},dept_class:function(t){return 0==t?"dept-cap":t>=10&&20>t?"dept-sec":t>=20&&30>t?"dept-med":t>=30&&40>t?"dept-sci":t>=40&&50>t?"dept-eng":t>=50&&60>t?"dept-cargo":t>=200&&230>t?"dept-cent":"dept-other"},health_state:function(t,e,n,a){var r=t+e+n+a;return 0>=r?"health-5":25>=r?"health-4":50>=r?"health-3":75>=r?"health-2":"health-0"}}}}(r),r.exports.css=" .health {\r\n width: 16px;\r\n height: 16px;\r\n background-color: #FFF;\r\n border: 1px solid #434343;\r\n position: relative;\r\n top: 2px;\r\n display: inline-block;\r\n }\r\n .health-5 { background-color: #17d568; }\r\n .health-4 { background-color: #2ecc71; }\r\n .health-3 { background-color: #e67e22; }\r\n .health-2 { background-color: #ed5100; }\r\n .health-1 { background-color: #e74c3c; }\r\n .health-0 { background-color: #ed2814; }\r\n\r\n .dept-cap {color : #C06616;}\r\n .dept-sec {color : #E74C3C;}\r\n .dept-med {color : #3498DB;}\r\n .dept-sci {color : #9B59B6;}\r\n .dept-eng {color : #F1C40F;}\r\n .dept-cargo {color : #F39C12;}\r\n .dept-cent {color : #00C100;}\r\n .dept-other {color: #C38312;}\r\n\r\n .oxy { color : #3498db; }\r\n .toxin { color : #2ecc71; }\r\n .burn { color : #e67e22; }\r\n .brute { color : #e74c3c; }\r\n\r\n table.crew{\r\n border-collapse: collapse;\r\n }\r\n\r\n table.crew td {\r\n padding : 0px 10px;\r\n }",r.exports.template={v:3,t:[" ",{p:[27,1,1030],t:7,e:"ui-display",f:[{p:[28,2,1045],t:7,e:"ui-section",f:[{p:[29,3,1061],t:7,e:"table",a:{"class":"crew"},f:[{p:[30,3,1085],t:7,e:"thead",f:[{p:[31,3,1096],t:7,e:"tr",f:[{p:[32,4,1105],t:7,e:"th",f:["Name"]}," ",{p:[33,4,1123],t:7,e:"th",f:["Status"]}," ",{p:[34,4,1143],t:7,e:"th",f:["Vitals"]}," ",{p:[35,4,1163],t:7,e:"th",f:["Position"]}," ",{t:4,f:[{p:[37,5,1216],t:7,e:"th",f:["Tracking"]}],n:50,r:"data.link_allowed",p:[36,4,1185]}]}]}," ",{p:[41,3,1270],t:7,e:"tbody",f:[{t:4,f:[{p:[43,4,1308],t:7,e:"tr",f:[{p:[44,5,1318],t:7,e:"td",f:[{p:[45,6,1329],t:7,e:"span",a:{"class":[{t:2,x:{r:["isHead","ijob"],s:'_0(_1)?"bold ":""'},p:[45,19,1342]},{t:2,x:{r:["dept_class","ijob"],s:"_0(_1)"},p:[45,49,1372]}]},f:[{t:2,r:"name",p:[46,7,1402]}," (",{t:2,r:"assignment",p:[46,17,1412]},") ",{p:[47,6,1434],t:7,e:"span",f:[]}]}]}," ",{p:[49,5,1457],t:7,e:"td",f:[{t:4,f:[{p:[51,7,1498],t:7,e:"span",a:{"class":["health ",{t:2,x:{r:["health_state","oxydam","toxdam","burndam","brutedam"],s:"_0(_1,_2,_3,_4)"},p:[51,27,1518]}]}}],n:50,x:{r:["oxydam"],s:"_0!=null"},p:[50,6,1468]},{t:4,n:51,f:[{t:4,f:[{p:[54,8,1626],t:7,e:"span",a:{"class":"health health-5"}}],n:50,r:"life_status",p:[53,7,1598]},{t:4,n:51,f:[{p:[56,8,1688],t:7,e:"span",a:{"class":"health health-0"}}],r:"life_status"}],x:{r:["oxydam"],s:"_0!=null"}}]}," ",{p:[60,5,1771],t:7,e:"td",f:[{t:4,f:[{p:[62,7,1812],t:7,e:"span",f:["( ",{p:[64,8,1836],t:7,e:"span",a:{"class":"oxy"},f:[{t:2,r:"oxydam",p:[64,26,1854]}]}," / ",{p:[66,8,1890],t:7,e:"span",a:{"class":"toxin"},f:[{t:2,r:"toxdam",p:[66,28,1910]}]}," / ",{p:[68,8,1946],t:7,e:"span",a:{"class":"burn"},f:[{t:2,r:"burndam",p:[68,27,1965]}]}," / ",{p:[70,8,2002],t:7,e:"span",a:{"class":"brute"},f:[{t:2,r:"brutedam",p:[70,28,2022]}]}," )"]}],n:50,x:{r:["oxydam"],s:"_0!=null"},p:[61,6,1782]},{t:4,n:51,f:[{t:4,f:[{p:[75,8,2116],t:7,e:"span",f:["Alive"]}],n:50,r:"life_status",p:[74,7,2088]},{t:4,n:51,f:[{p:[77,8,2159],t:7,e:"span",f:["Dead"]}],r:"life_status"}],x:{r:["oxydam"],s:"_0!=null"}}]}," ",{p:[81,5,2222],t:7,e:"td",f:[{t:4,f:[{p:[83,6,2260],t:7,e:"span",f:[{t:2,r:"area",p:[83,12,2266]}]}],n:50,x:{r:["pos_x"],s:"_0!=null"},p:[82,5,2232]},{t:4,n:51,f:[{p:[85,6,2302],t:7,e:"span",f:["N/A"]}],x:{r:["pos_x"],s:"_0!=null"}}]}," ",{t:4,f:[{p:[89,6,2381],t:7,e:"td",f:[{p:[90,7,2393],t:7,e:"ui-button",a:{action:"select_person",state:[{t:2,x:{r:["can_track"],s:'_0?null:"disabled"'},p:[90,48,2434]}],params:['{"name":"',{t:2,r:"name",p:[90,100,2486]},'"}']},f:["Track"]}]}],n:50,r:"data.link_allowed",p:[88,5,2348]}]}],n:52,r:"data.sensors",p:[42,3,1281]}]}]}]}]}," "]},e.exports=a.extend(r.exports)},{341:341}],387:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,189],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,223],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,236]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,265]}]}]}," ",{p:[9,4,317],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[10,6,356],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.temperaturestatus",p:[10,19,369]}]},f:[{t:2,r:"data.occupant.bodyTemperature",p:[10,56,406]}," K"]}]}," ",{p:[12,5,472],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[13,7,507],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[13,20,520]}],max:[{t:2,r:"data.occupant.maxHealth",p:[13,54,554]}],value:[{t:2,r:"data.occupant.health",p:[13,90,590]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[14,16,632]}]},f:[{t:2,r:"data.occupant.health",p:[14,68,684]}]}]}," ",{t:4,f:[{p:[17,7,908],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[17,26,927]}]},f:[{p:[18,9,948],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[18,30,969]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,66,1005]}],state:"bad"},f:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[18,103,1042]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[16,5,742]}],n:50,r:"data.hasOccupant",p:[5,3,159]}]}," ",{p:[23,1,1138],t:7,e:"ui-display",a:{title:"Cell"},f:[{p:[24,3,1167],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[25,5,1199],t:7,e:"ui-button",a:{
+icon:[{t:2,x:{r:["data.isOperating"],s:'_0?"power-off":"close"'},p:[25,22,1216]}],style:[{t:2,x:{r:["data.isOperating"],s:'_0?"selected":null'},p:[26,14,1276]}],state:[{t:2,x:{r:["data.isOpen"],s:'_0?"disabled":null'},p:[27,14,1332]}],action:"power"},f:[{t:2,x:{r:["data.isOperating"],s:'_0?"On":"Off"'},p:[28,22,1391]}]}]}," ",{p:[30,3,1459],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[31,3,1495],t:7,e:"span",a:{"class":[{t:2,r:"data.temperaturestatus",p:[31,16,1508]}]},f:[{t:2,r:"data.cellTemperature",p:[31,44,1536]}," K"]}]}," ",{p:[33,2,1588],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[34,5,1619],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isOpen"],s:'_0?"unlock":"lock"'},p:[34,22,1636]}],action:"door"},f:[{t:2,x:{r:["data.isOpen"],s:'_0?"Open":"Closed"'},p:[34,73,1687]}]}," ",{p:[35,5,1740],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoEject"],s:'_0?"sign-out":"sign-in"'},p:[35,22,1757]}],action:"autoeject"},f:[{t:2,x:{r:["data.autoEject"],s:'_0?"Auto":"Manual"'},p:[35,86,1821]}]}]}]}," ",{p:{button:[{p:[40,5,1967],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.isBeakerLoaded"],s:'_0?null:"disabled"'},p:[40,36,1998]}],action:"ejectbeaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{p:[42,3,2101],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[45,9,2211],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,r:"volume",p:[45,52,2254]}," units of ",{t:2,r:"name",p:[45,72,2274]}]},{p:[45,87,2289],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[44,7,2171]},{t:4,n:51,f:[{p:[47,9,2320],t:7,e:"span",a:{"class":"bad"},f:["Beaker Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[43,5,2136]},{t:4,n:51,f:[{p:[50,7,2396],t:7,e:"span",a:{"class":"average"},f:["No Beaker"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],388:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",a:{label:"State"},f:[{t:4,f:[{p:[4,4,76],t:7,e:"span",a:{"class":"good"},f:["Ready"]}],n:50,r:"data.full_pressure",p:[3,3,45]},{t:4,n:51,f:[{t:4,f:[{p:[7,5,153],t:7,e:"span",a:{"class":"bad"},f:["Power Disabled"]}],n:50,r:"data.panel_open",p:[6,4,124]},{t:4,n:51,f:[{t:4,f:[{p:[10,6,248],t:7,e:"span",a:{"class":"average"},f:["Pressurizing"]}],n:50,r:"data.pressure_charging",p:[9,5,211]},{t:4,n:51,f:[{p:[12,6,310],t:7,e:"span",a:{"class":"bad"},f:["Off"]}],r:"data.pressure_charging"}],r:"data.panel_open"}],r:"data.full_pressure"}]}," ",{p:[17,2,393],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[18,3,426],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.per",p:[18,36,459]}],state:"good"},f:[{t:2,r:"data.per",p:[18,63,486]},"%"]}]}," ",{p:[20,5,530],t:7,e:"ui-section",a:{label:"Handle"},f:[{p:[21,9,567],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.flush"],s:'_0?"toggle-on":"toggle-off"'},p:[22,10,589]}],state:[{t:2,x:{r:["data.isai","data.panel_open"],s:'_0||_1?"disabled":null'},p:[23,11,647]}],action:[{t:2,x:{r:["data.flush"],s:'_0?"handle-0":"handle-1"'},p:[24,12,714]}]},f:[{t:2,x:{r:["data.flush"],s:'_0?"Disengage":"Engage"'},p:[25,5,763]}]}]}," ",{p:[27,2,837],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[28,3,867],t:7,e:"ui-button",a:{icon:"sign-out",state:[{t:2,x:{r:["data.isai"],s:'_0?"disabled":null'},p:[28,37,901]}],action:"eject"},f:["Eject Contents"]},{p:[28,114,978],t:7,e:"br"}]}," ",{p:[30,2,1002],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,3,1032],t:7,e:"ui-button",a:{icon:"power-off",state:[{t:2,x:{r:["data.panel_open"],s:'_0?"disabled":null'},p:[31,38,1067]}],action:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"pump-0":"pump-1"'},p:[31,87,1116]}],style:[{t:2,x:{r:["data.pressure_charging"],s:'_0?"selected":null'},p:[31,145,1174]}]}},{p:[31,206,1235],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],389:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"DNA Vault Database"},f:[{p:[2,3,43],t:7,e:"ui-section",a:{label:"Human DNA"},f:[{p:[3,7,81],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.dna_max",p:[3,28,102]}],value:[{t:2,r:"data.dna",p:[3,53,127]}]},f:[{t:2,r:"data.dna",p:[3,67,141]},"/",{t:2,r:"data.dna_max",p:[3,80,154]}," Samples"]}]}," ",{p:[5,3,208],t:7,e:"ui-section",a:{label:"Plant Data"},f:[{p:[6,5,245],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.plants_max",p:[6,26,266]}],value:[{t:2,r:"data.plants",p:[6,54,294]}]},f:[{t:2,r:"data.plants",p:[6,71,311]},"/",{t:2,r:"data.plants_max",p:[6,87,327]}," Samples"]}]}," ",{p:[8,3,384],t:7,e:"ui-section",a:{label:"Animal Data"},f:[{p:[9,5,422],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.animals_max",p:[9,26,443]}],value:[{t:2,r:"data.animals",p:[9,55,472]}]},f:[{t:2,r:"data.animals",p:[9,73,490]},"/",{t:2,r:"data.animals_max",p:[9,90,507]}," Samples"]}]}]}," ",{t:4,f:[{p:[13,1,616],t:7,e:"ui-display",a:{title:"Personal Gene Therapy"},f:[{p:[14,3,663],t:7,e:"ui-section",f:[{p:[15,2,678],t:7,e:"span",f:["Applicable gene therapy treatments:"]}]}," ",{p:[17,3,747],t:7,e:"ui-section",f:[{p:[18,2,762],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceA",p:[18,47,807]},'"}']},f:[{t:2,r:"data.choiceA",p:[18,67,827]}]}," ",{p:[19,2,858],t:7,e:"ui-button",a:{action:"gene",params:['{"choice": "',{t:2,r:"data.choiceB",p:[19,47,903]},'"}']},f:[{t:2,r:"data.choiceB",p:[19,67,923]}]}]}]}],n:50,x:{r:["data.completed","data.used"],s:"_0&&!_1"},p:[12,1,578]}]},e.exports=a.extend(r.exports)},{341:341}],390:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,183],t:7,e:"ui-section",a:{label:"Items in storage"},f:[{p:[7,4,225],t:7,e:"span",f:[{t:2,r:"data.items",p:[7,10,231]}]}]}],n:50,r:"data.items",p:[5,3,159]}," ",{t:4,f:[{p:[11,5,310],t:7,e:"ui-section",a:{label:"State"},f:[{p:[12,7,344],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[12,20,357]}]},f:[{t:2,r:"data.occupant.stat",p:[12,49,386]}]}]}," ",{p:[14,5,439],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[15,7,474],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[15,20,487]}],max:[{t:2,r:"data.occupant.maxHealth",p:[15,54,521]}],value:[{t:2,r:"data.occupant.health",p:[15,90,557]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[16,16,599]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[16,68,651]}]}]}," ",{t:4,f:[{p:[19,7,888],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[19,26,907]}]},f:[{p:[20,9,928],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[20,30,949]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[20,66,985]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[20,103,1022]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[18,5,722]}," ",{p:[23,5,1109],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[24,9,1145],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[24,22,1158]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[24,68,1204]}]}]}," ",{p:[26,5,1287],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[27,9,1323],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[27,22,1336]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[27,68,1382]}]}]}," ",{p:[29,5,1466],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[31,11,1553],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[31,54,1596]}," units of ",{t:2,r:"name",p:[31,89,1631]}]},{p:[31,104,1646],t:7,e:"br"}],n:52,r:"adata.occupant.reagents",p:[30,9,1508]},{t:4,n:51,f:[{p:[33,11,1681],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[10,3,283]}]}," ",{p:[38,1,1777],t:7,e:"ui-display",a:{title:"Operations"},f:[{p:[39,3,1812],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[41,7,1872],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied"],s:'_0?null:"disabled"'},p:[41,38,1903]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[41,111,1976]},'"}']},f:[{t:2,r:"name",p:[41,121,1986]}]},{p:[41,141,2006],t:7,e:"br"}],n:52,r:"data.chem",p:[40,5,1845]}]}," ",{p:[44,2,2046],t:7,e:"ui-section",a:{label:"Eject"},f:[{p:[45,6,2079],t:7,e:"ui-button",a:{icon:"sign-out",action:"eject"},f:["Eject Contents"]}]}," ",{p:[47,2,2166],t:7,e:"ui-section",a:{label:"Self Cleaning"},f:[{p:[48,3,2204],t:7,e:"ui-button",a:{icon:"recycle",action:"cleaning"},f:["Self-Clean Cycle"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],391:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,24],t:7,e:"ui-display",a:{title:[{t:2,r:"data.question",p:[2,21,42]}]},f:[{p:[3,5,66],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,9,118],t:7,e:"ui-button",a:{action:"vote",params:['{"answer": "',{t:2,r:"answer",p:[6,45,174]},'"}'],style:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[7,18,206]}]},f:[{t:2,r:"answer",p:[7,53,241]}," (",{t:2,r:"amount",p:[7,65,253]},")"]}],n:52,r:"data.answers",p:[4,7,86]}]}]}],n:50,r:"data.shaking",p:[1,1,0]},{t:4,n:51,f:[{p:[13,3,353],t:7,e:"ui-notice",f:["The eightball is not currently being shaken."]}],r:"data.shaking"}]},e.exports=a.extend(r.exports)},{341:341}],392:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,5,17],t:7,e:"span",f:["Time Until Launch: ",{t:2,r:"data.timer_str",p:[2,30,42]}]}]}," ",{p:[4,1,83],t:7,e:"ui-notice",f:[{p:[5,3,98],t:7,e:"span",f:["Engines: ",{t:2,x:{r:["data.engines_started"],s:'_0?"Online":"Idle"'},p:[5,18,113]}]}]}," ",{p:[7,1,180],t:7,e:"ui-display",a:{title:"Early Launch"},f:[{p:[8,2,216],t:7,e:"span",f:["Authorizations Remaining: ",{t:2,x:{r:["data.emagged","data.authorizations_remaining"],s:'_0?"ERROR":_1'},p:[9,2,250]}]}," ",{p:[10,2,318],t:7,e:"ui-button",a:{icon:"exclamation-triangle",action:"authorize",style:"danger",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[12,10,404]}]},f:["AUTHORIZE"]}," ",{p:[15,2,473],t:7,e:"ui-button",a:{icon:"minus",action:"repeal",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[16,10,523]}]},f:["Repeal"]}," ",{p:[19,2,589],t:7,e:"ui-button",a:{icon:"close",action:"abort",state:[{t:2,x:{r:["data.enabled"],s:'_0?null:"disabled"'},p:[20,10,638]}]},f:["Repeal All"]}]}," ",{p:[24,1,722],t:7,e:"ui-display",a:{title:"Authorizations"},f:[{t:4,f:[{p:[26,3,793],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{t:2,r:"name",p:[26,34,824]}," (",{t:2,r:"job",p:[26,44,834]},")"]}],n:52,r:"data.authorizations",p:[25,2,760]},{t:4,n:51,f:[{p:[28,3,870],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:["No authorizations."]}],r:"data.authorizations"}]}]},e.exports=a.extend(r.exports)},{341:341}],393:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.hidden_message",p:[3,5,50]}]}," ",{p:[5,3,94],t:7,e:"ui-section",a:{label:"Created On"},f:[{t:2,r:"data.realdate",p:[6,5,131]}]}," ",{p:[8,3,169],t:7,e:"ui-section",a:{label:"Approval"},f:[{p:[9,5,204],t:7,e:"ui-button",a:{icon:"arrow-up",state:[{t:2,x:{r:["data.is_creator","data.has_liked"],s:'_0?"disabled":_1?"selected":null'},p:[11,14,252]}],action:"like"},f:[{t:2,r:"data.num_likes",p:[12,21,344]}]}," ",{p:[13,5,380],t:7,e:"ui-button",a:{icon:"circle",state:[{t:2,x:{r:["data.is_creator","data.has_liked","data.has_disliked"],s:'_0?"disabled":!_1&&!_2?"selected":null'},p:[15,14,426]}],action:"neutral"}}," ",{p:[17,5,562],t:7,e:"ui-button",a:{icon:"arrow-down",state:[{t:2,x:{r:["data.is_creator","data.has_disliked"],s:'_0?"disabled":_1?"selected":null'},p:[19,14,612]}],action:"dislike"},f:[{t:2,r:"data.num_dislikes",p:[20,24,710]}]}]}]}," ",{t:4,f:[{p:[24,3,805],t:7,e:"ui-display",a:{title:"Admin Panel"},f:[{p:[25,5,843],t:7,e:"ui-section",a:{label:"Creator Ckey"},f:[{t:2,r:"data.creator_key",p:[25,38,876]}]}," ",{p:[26,5,915],t:7,e:"ui-section",a:{label:"Creator Character Name"},f:[{t:2,r:"data.creator_name",p:[26,48,958]}]}," ",{p:[27,5,998],t:7,e:"ui-button",a:{icon:"remove",action:"delete",style:"danger"},f:["Delete"]}]}],n:50,r:"data.admin_mode",p:[23,1,778]}]},e.exports=a.extend(r.exports)},{341:341}],394:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The requested interface (",{t:2,r:"config.interface",p:[2,34,46]},") was not found. Does it exist?"]}]}]},e.exports=a.extend(r.exports)},{341:341}],395:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,20],t:7,e:"ui-notice",f:["Currently syncing with the database"]}],n:50,r:"data.sync",p:[1,1,0]},{t:4,n:51,f:[{p:{button:[{p:[8,4,163],t:7,e:"ui-button",a:{icon:"eject",action:"eject_all"},f:["Eject all"]}," ",{p:[9,4,232],t:7,e:"ui-button",a:{icon:["toggle-",{t:2,x:{r:["data.show_materials"],s:'_0?"off":"on"'},p:[9,28,256]}],action:"toggle_materials_visibility"},f:[{t:2,x:{r:["data.show_materials"],s:'_0?"Hide":"Show"'},p:[10,5,339]}]}]},t:7,e:"ui-display",a:{title:"Materials",button:0},f:[" ",{t:4,f:[{p:[14,4,449],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[15,5,484],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[16,6,520],t:7,e:"section",a:{"class":"cell"}}," ",{p:[17,6,559],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[20,6,620],t:7,e:"section",a:{"class":"cell"},f:["Amount"]}," ",{p:[23,6,680],t:7,e:"section",a:{"class":"cell"}}," ",{p:[24,6,719],t:7,e:"section",a:{"class":"cell"}}]}," ",{t:4,f:[{p:[27,6,808],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[28,7,845],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[29,8,876]}]}," ",{p:[31,7,910],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"amount",p:[32,8,941]}]}," ",{p:[34,7,977],t:7,e:"section",a:{"class":"cell"},f:[{p:[35,8,1008],t:7,e:"ui-button",a:{icon:"eject"},f:["Release amount"]}]}," ",{p:[37,7,1084],t:7,e:"section",a:{"class":"cell",style:"width: 40px;"},f:[{p:[38,8,1136],t:7,e:"ui-button",a:{icon:"eject"},f:["Release all"]}]}]}],n:52,r:"data.all_materials",p:[26,5,773]}]}],n:50,r:"data.show_materials",p:[13,3,417]}]}," ",{p:[45,2,1274],t:7,e:"ui-display",a:{title:"Categories"},f:[{t:4,f:[{p:[47,4,1334],t:7,e:"ui-button",f:[{t:2,r:".",p:[47,15,1345]}]}],r:"data.categories",p:[46,3,1309]}]}],r:"data.sync"}]},e.exports=a.extend(r.exports)},{341:341}],396:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,3,16],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,5,49],t:7,e:"ui-button",a:{action:"toggle_power",style:[{t:2,x:{r:["data.toggle"],s:'_0?"selected":null'},p:[5,18,111]}]},f:["Turn ",{t:2,x:{r:["data.toggle"],s:'_0?"off":"on"'},p:[6,16,166]}]}]}," ",{p:[9,3,235],t:7,e:"ui-display",a:{title:"Logging"},f:[{t:4,f:[{p:[11,3,292],t:7,e:"ui-section",a:{label:">"},f:[{t:2,r:".",p:[11,25,314]},{p:[11,30,319],t:7,e:"ui-section",f:[]}]}],n:52,r:"data.logs",p:[10,5,269]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],397:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{seclevelState:function(){switch(this.get("data.seclevel")){case"blue":return"average";case"red":return"bad";case"delta":return"bad bold";default:return"good"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[16,1,323],t:7,e:"ui-display",f:[{p:[17,5,341],t:7,e:"ui-section",a:{label:"Alert Level"},f:[{p:[18,9,383],t:7,e:"span",a:{"class":[{t:2,r:"seclevelState",p:[18,22,396]}]},f:[{t:2,x:{r:["text","data.seclevel"],s:"_0.titleCase(_1)"},p:[18,41,415]}]}]}," ",{p:[20,5,480],t:7,e:"ui-section",a:{label:"Controls"},f:[{p:[21,9,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.alarm"],s:'_0?"close":"bell-o"'},p:[21,26,536]}],action:[{t:2,x:{r:["data.alarm"],s:'_0?"reset":"alarm"'},p:[21,71,581]}]},f:[{t:2,x:{r:["data.alarm"],s:'_0?"Reset":"Activate"'},p:[22,13,631]}]}]}," ",{t:4,f:[{p:[25,7,733],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[26,9,771],t:7,e:"span",a:{"class":"bad bold"},f:["Safety measures offline. Device may exhibit abnormal behavior."]}]}],n:50,r:"data.emagged",p:[24,5,705]}]}]},e.exports=a.extend(r.exports)},{341:341}],398:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[2,1,31],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[3,2,60],t:7,e:"ui-button",a:{icon:"power-off",style:[{t:2,x:{r:["data.power"],s:'_0?"selected":"danger"'},p:[3,37,95]}],action:"power"},f:[{t:2,x:{r:["data.power"],s:'_0?"Enabled":"Disabled"'},p:[3,92,150]}]}]}," ",{p:[5,1,218],t:7,e:"ui-section",a:{label:"Tag"},f:[{p:[6,2,245],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:[{t:2,r:"data.tag",p:[6,43,286]}]}]}," ",{p:[8,1,327],t:7,e:"ui-section",a:{label:"Scanning mode"},f:[{p:[9,2,364],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.updating"],s:'_0?"unlock":"lock"'},p:[9,18,380]}],style:[{t:2,x:{r:["data.updating"],s:'_0?null:"danger"'},p:[9,63,425]}],action:"updating",tooltip:"Toggle between automatic scanning or scan only when a button is pressed.","tooltip-side":"right"},f:[{t:2,x:{r:["data.updating"],s:'_0?"AUTO":"MANUAL"'},p:[9,221,583]}]}]}," ",{p:[11,1,649],t:7,e:"ui-section",a:{label:"Detection range"},f:[{p:[12,2,688],t:7,e:"ui-button",a:{icon:"refresh",style:[{t:2,x:{r:["data.globalmode"],s:'_0?null:"selected"'},p:[12,35,721]}],action:"globalmode",tooltip:"Local sector or whole region scanning.","tooltip-side":"right"},f:[{t:2,x:{r:["data.globalmode"],s:'_0?"MAXIMUM":"LOCAL"'},p:[12,165,851]}]}]}]}," ",{t:4,f:[{p:[16,2,957],t:7,e:"ui-display",a:{title:"Current Location"},f:[{p:[17,3,998],t:7,e:"span",f:[{t:2,r:"data.current",p:[17,9,1004]}]}]}," ",{p:[20,2,1048],t:7,e:"ui-display",a:{title:"Detected Signals"},f:[{t:4,f:[{p:[22,3,1114],t:7,e:"ui-section",a:{label:[{t:2,r:"entrytag",p:[22,21,1132]}]},f:[{p:[23,3,1149],t:7,e:"span",f:[{t:2,r:"area",p:[23,9,1155]}," (",{t:2,r:"coord",p:[23,19,1165]},")"]}," ",{t:4,f:[{p:[25,4,1209],t:7,e:"span",f:["Dist: ",{t:2,r:"dist",p:[25,16,1221]},"m Dir: ",{t:2,r:"degrees",p:[25,31,1236]},"° (",{t:2,r:"direction",p:[25,45,1250]},")"]}],n:50,r:"direction",p:[24,3,1187]}]}],n:52,r:"data.signals",p:[21,2,1088]}]}],n:50,r:"data.power",p:[15,1,936]}]},e.exports=a.extend(r.exports)},{341:341}],399:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Labor Camp Teleporter"},f:[{p:[2,2,45],t:7,e:"ui-section",a:{label:"Teleporter Status"},f:[{p:[3,3,87],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.teleporter"],s:'_0?"good":"bad"'},p:[3,16,100]}]},f:[{t:2,x:{r:["data.teleporter"],s:'_0?"Connected":"Not connected"'},p:[3,54,138]}]}]}," ",{t:4,f:[{p:[6,4,244],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[7,5,279],t:7,e:"span",f:[{t:2,r:"data.teleporter_location",p:[7,11,285]}]}]}," ",{p:[9,4,343],t:7,e:"ui-section",a:{label:"Locked status"},f:[{p:[10,5,383],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"lock":"unlock"'},p:[10,22,400]}],action:"teleporter_lock"},f:[{t:2,x:{r:["data.teleporter_lock"],s:'_0?"Locked":"Unlocked"'},p:[10,93,471]}]}," ",{p:[11,5,537],t:7,e:"ui-button",a:{action:"toggle_open"},f:[{t:2,x:{r:["data.teleporter_state_open"],s:'_0?"Open":"Closed"'},p:[11,37,569]}]}]}],n:50,r:"data.teleporter",p:[5,3,216]},{t:4,n:51,f:[{p:[14,4,666],t:7,e:"span",f:[{p:[14,10,672],t:7,e:"ui-button",a:{action:"scan_teleporter"},f:["Scan Teleporter"]}]}],r:"data.teleporter"}]}," ",{p:[17,1,770],t:7,e:"ui-display",a:{title:"Labor Camp Beacon"},f:[{p:[18,2,811],t:7,e:"ui-section",a:{label:"Beacon Status"},f:[{p:[19,3,849],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.beacon"],s:'_0?"good":"bad"'},p:[19,16,862]}]},f:[{t:2,x:{r:["data.beacon"],s:'_0?"Connected":"Not connected"'},p:[19,50,896]}]}]}," ",{t:4,f:[{p:[22,3,992],t:7,e:"ui-section",a:{label:"Location"},f:[{p:[23,4,1026],t:7,e:"span",f:[{t:2,r:"data.beacon_location",p:[23,10,1032]}]}]}],n:50,r:"data.beacon",p:[21,2,969]},{t:4,n:51,f:[{p:[26,4,1097],t:7,e:"span",f:[{p:[26,10,1103],t:7,e:"ui-button",a:{action:"scan_beacon"},f:["Scan Beacon"]}]}],r:"data.beacon"}]}," ",{p:[29,1,1193],t:7,e:"ui-display",a:{title:"Prisoner details"},f:[{p:[30,2,1233],t:7,e:"ui-section",a:{label:"Prisoner ID"},f:[{p:[31,3,1269],t:7,e:"ui-button",a:{action:"handle_id"},f:[{t:2,x:{r:["data.id","data.id_name"],s:'_0?_1:"-------------"'},p:[31,33,1299]}]}]}," ",{t:4,f:[{p:[34,2,1392],t:7,e:"ui-section",a:{label:"Set ID goal"},f:[{p:[35,4,1429],t:7,e:"ui-button",a:{action:"set_goal"},f:[{t:2,r:"data.goal",p:[35,33,1458]}]}]}],n:50,r:"data.id",p:[33,2,1374]}," ",{p:[38,2,1512],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[39,3,1545],t:7,e:"span",f:[{t:2,x:{r:["data.prisoner.name"],s:'_0?_0:"No Occupant"'},p:[39,9,1551]}]}]}," ",{t:4,f:[{p:[42,3,1661],t:7,e:"ui-section",a:{label:"Criminal Status"},f:[{p:[43,4,1702],t:7,e:"span",f:[{t:2,r:"data.prisoner.crimstat",p:[43,10,1708]}]}]}],n:50,r:"data.prisoner",p:[41,2,1636]}]}," ",{p:[47,1,1785],t:7,e:"ui-display",f:[{p:[48,2,1800],t:7,e:"center",f:[{p:[48,10,1808],t:7,e:"ui-button",a:{action:"teleport",state:[{t:2,x:{r:["data.can_teleport"],s:'_0?null:"disabled"'},p:[48,45,1843]}]},f:["Process Prisoner"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],400:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Stored Items"},f:[{t:4,f:[{p:[3,3,59],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,22,78]}]},f:[{p:[4,4,93],t:7,e:"ui-button",a:{action:"release_items",params:['{"mobref":',{t:2,r:"mob",p:[4,56,145]},"}"],state:[{t:2,x:{r:["data.can_reclaim"],s:'_0?null:"disabled"'},p:[4,72,161]}]},f:["Drop Items"]}]}],n:52,r:"data.mobs",p:[2,2,36]}]}]},e.exports=a.extend(r.exports)},{341:341}],401:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{p:[3,3,70],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.emagged"],s:'_0?"un":null'},p:[3,20,87]},"lock"],state:[{t:2,x:{r:["data.can_toggle_safety"],s:'_0?null:"disabled"'},p:[3,63,130]}],action:"safety"},f:["Safeties: ",{p:[4,14,209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.emagged"],s:'_0?"bad":"good"'},p:[4,27,222]}]},f:[{t:2,x:{r:["data.emagged"],s:'_0?"OFF":"ON"'},p:[4,62,257]}]}]}]},t:7,e:"ui-display",a:{title:"Default Programs",button:0},f:[" ",{t:4,f:[{p:[8,2,363],t:7,e:"ui-button",a:{action:"load_program",params:['{"type": ',{t:2,r:"type",p:[8,52,413]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[8,70,431]}]},f:[{t:2,r:"name",p:[9,5,483]}," "]},{p:[10,14,506],t:7,e:"br"}],n:52,r:"data.default_programs",p:[7,2,329]}]}," ",{t:4,f:[{p:[14,2,562],t:7,e:"ui-display",a:{title:"Dangerous Programs"},f:[{t:4,f:[{p:[16,4,638],t:7,e:"ui-button",a:{icon:"warning",action:"load_program",params:['{"type": ',{t:2,r:"type",p:[16,69,703]},"}"],style:[{t:2,x:{r:["data.program","type"],s:'_0==_1?"selected":null'},p:[16,87,721]}]},f:[{t:2,r:"name",p:[17,5,773]}," "]},{p:[18,16,798],t:7,e:"br"}],n:52,r:"data.emag_programs",p:[15,3,605]}]}],n:50,r:"data.emagged",p:[13,1,539]}]},e.exports=a.extend(r.exports)},{341:341}],402:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{occupantStatState:function(){switch(this.get("data.occupant.stat")){case 0:return"good";case 1:return"average";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[15,1,280],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[16,3,313],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[17,3,346],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[17,9,352]}]}]}," ",{t:4,f:[{p:[20,5,466],t:7,e:"ui-section",a:{label:"State"},f:[{p:[21,7,500],t:7,e:"span",a:{"class":[{t:2,r:"occupantStatState",p:[21,20,513]}]},f:[{t:2,x:{r:["data.occupant.stat"],s:'_0==0?"Conscious":_0==1?"Unconcious":"Dead"'},p:[21,43,536]}]}]}],n:50,r:"data.occupied",p:[19,3,439]}]}," ",{p:[25,1,680],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[26,2,712],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[27,5,743],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[27,22,760]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[27,71,809]}]}]}," ",{p:[29,3,874],t:7,e:"ui-section",a:{label:"Uses"},f:[{t:2,r:"data.ready_implants",p:[30,5,905]}," ",{t:4,f:[{p:[32,7,969],t:7,e:"span",a:{"class":"fa fa-cog fa-spin"}}],n:50,r:"data.replenishing",p:[31,5,936]}]}," ",{p:[35,3,1036],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[36,7,1073],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.occupied","data.ready_implants","data.ready"],s:'_0&&_1>0&&_2?null:"disabled"'},p:[36,25,1091]}],action:"implant"},f:[{t:2,x:{r:["data.ready","data.special_name"],s:'_0?(_1?_1:"Implant"):"Recharging"'},p:[37,9,1198]}," "]},{p:[38,19,1302],t:7,e:"br"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],403:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{t:4,f:[{p:[15,3,296],t:7,e:"ui-notice",f:[{p:[16,5,313],t:7,e:"span",f:["Wipe in progress!"]}]}],n:50,r:"data.wiping",p:[14,1,273]},{p:{button:[{t:4,f:[{p:[22,7,479],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.isDead"],s:'_0?"disabled":null'},p:[22,38,510]}],action:"wipe"},f:[{t:2,x:{r:["data.wiping"],s:'_0?"Stop Wiping":"Wipe"'},p:[22,89,561]}," AI"]}],n:50,r:"data.name",p:[21,5,454]}]},t:7,e:"ui-display",a:{title:[{t:2,x:{r:["data.name"],s:'_0||"Empty Card"'},p:[19,19,388]}],button:0},f:[" ",{t:4,f:[{p:[26,5,672],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[27,9,709],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"bad":"good"'},p:[27,22,722]}]},f:[{t:2,x:{r:["data.isDead","data.isBraindead"],s:'_0||_1?"Offline":"Operational"'},p:[27,76,776]}]}]}," ",{p:[29,5,871],t:7,e:"ui-section",a:{label:"Software Integrity"},f:[{p:[30,7,918],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[30,40,951]}],state:[{t:2,r:"healthState",p:[30,64,975]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[30,81,992]},"%"]}]}," ",{p:[32,5,1055],t:7,e:"ui-section",a:{label:"Laws"},f:[{t:4,f:[{p:[34,9,1117],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[34,33,1141]}]},{p:[34,45,1153],t:7,e:"br"}],n:52,r:"data.laws",p:[33,7,1088]}]}," ",{p:[37,5,1200],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[38,7,1237],t:7,e:"ui-button",a:{icon:"signal",style:[{t:2,x:{r:["data.wireless"],s:'_0?"selected":null'},p:[38,39,1269]}],action:"wireless"},f:["Wireless Activity"]}," ",{p:[39,7,1363],t:7,e:"ui-button",a:{icon:"microphone",style:[{t:2,x:{r:["data.radio"],s:'_0?"selected":null'},p:[39,43,1399]}],action:"radio"},f:["Subspace Radio"]}]}],n:50,r:"data.name",p:[25,3,649]}]}]},e.exports=a.extend(r.exports)},{341:341}],404:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,23],t:7,e:"ui-notice",f:[{p:[3,3,38],t:7,e:"span",f:["Waiting for another device to confirm your request..."]}]}],n:50,r:"data.waiting",p:[1,1,0]},{t:4,n:51,f:[{p:[6,2,132],t:7,e:"ui-display",f:[{p:[7,3,148],t:7,e:"ui-section",f:[{t:4,f:[{p:[9,5,197],t:7,e:"ui-button",a:{icon:"check",action:"auth_swipe"},f:["Authorize ",{t:2,r:"data.auth_required",p:[9,59,251]}]}],n:50,r:"data.auth_required",p:[8,4,165]},{t:4,n:51,f:[{p:[11,5,304],t:7,e:"ui-button",a:{icon:"warning",state:[{t:2,x:{r:["data.red_alert"],s:'_0?"disabled":null'},p:[11,38,337]}],action:"red_alert"},f:["Red Alert"]}," ",{p:[12,5,423],t:7,e:"ui-button",a:{icon:"wrench",state:[{t:2,x:{r:["data.emergency_maint"],s:'_0?"disabled":null'},p:[12,37,455]}],action:"emergency_maint"},f:["Emergency Maintenance Access"]}," ",{p:[13,5,572],t:7,e:"ui-button",a:{icon:"warning",state:"null",action:"bsa_unlock"},f:["Bluespace Artillery Unlock"]}],r:"data.auth_required"}]}]}],r:"data.waiting"}]},e.exports=a.extend(r.exports)},{341:341}],405:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Ore values"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"ui-section",a:{label:[{t:2,r:"ore",p:[3,22,76]}]},f:[{p:[4,4,90],t:7,e:"span",f:[{t:2,r:"value",p:[4,10,96]}]}]}],n:52,r:"data.ores",p:[2,2,34]}]}," ",{p:[8,1,158],t:7,e:"ui-display",a:{title:"Points"},f:[{p:[9,2,188],t:7,e:"ui-section",a:{label:"Unclaimed points"},f:[{p:[10,3,229],t:7,e:"span",f:[{t:2,r:"data.unclaimed_points",p:[10,9,235]}]}," ",{p:[11,3,271],t:7,e:"ui-button",a:{action:"claim_points",state:[{t:2,x:{r:["data.unclaimed_points"],s:'_0?null:"disabled"'},p:[11,42,310]}]},f:["Claim points"]}]}]}," ",{p:[14,1,413],t:7,e:"ui-display",f:[{p:[15,2,428],t:7,e:"span",f:["Points: ",{t:2,r:"data.id_points",p:[15,16,442]}]}," ",{p:[16,2,470],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[17,3,501],t:7,e:"span",f:[{t:2,r:"data.status_info",p:[17,9,507]}]}," ",{p:[18,3,538],t:7,e:"ui-button",a:{action:"move_shuttle",state:[{t:2,x:{r:["data.can_go_home"],s:'_0?null:"disabled"'},p:[18,42,577]}]},f:["Move shuttle"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],406:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Known Languages"},f:[{t:4,f:[{p:[3,5,70],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[3,23,88]}]},f:[{p:[4,7,105],t:7,e:"span",f:[{t:2,r:"desc",p:[4,13,111]}]}," ",{p:[5,7,134],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[5,19,146]}]}," ",{t:4,f:[{p:[7,9,192],t:7,e:"span",f:["(gained from mob)"]}],n:50,r:"shadow",p:[6,7,168]}," ",{p:[9,7,245],t:7,e:"span",f:[{t:2,x:{r:["can_speak"],s:'_0?"Can Speak":"Cannot Speak"'},p:[9,13,251]}]}," ",{t:4,f:[{p:[11,9,342],t:7,e:"ui-button",a:{action:"select_default",params:['{"language_name":"',{t:2,r:"name",p:[13,37,425]},'"}'],style:[{t:2,x:{r:["is_default","can_speak"],s:'_0?"selected":_1?null:"disabled"'},p:[14,18,455]}]},f:[{t:2,x:{r:["is_default"],s:'_0?"Default Language":"Select as Default"'},p:[15,10,526]}]}],n:50,r:"data.is_living",p:[10,7,310]}," ",{t:4,f:[{t:4,f:[{p:[20,11,685],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[20,72,746]},'"}']},f:["Grant"]}],n:50,r:"shadow",p:[19,9,659]},{t:4,n:51,f:[{p:[22,11,805],t:7,e:"ui-button",a:{action:"remove_language",params:['{"language_name":"',{t:2,r:"name",p:[22,73,867]},'"}']},f:["Remove"]}],r:"shadow"}],n:50,r:"data.admin_mode",p:[18,7,626]}]}],n:52,r:"data.languages",p:[2,3,40]}]}," ",{t:4,f:[{t:4,f:[{p:[30,5,1033],t:7,e:"ui-button",a:{action:"toggle_omnitongue",style:[{t:2,x:{r:["data.omnitongue"],s:'_0?"selected":null'},p:[32,14,1092]}]},f:["Omnitongue ",{t:2,x:{r:["data.omnitongue"],s:'_0?"Enabled":"Disabled"'},p:[33,19,1152]}]}],n:50,r:"data.is_living",p:[29,3,1005]}," ",{p:[36,3,1231],t:7,e:"ui-display",a:{title:"Unknown Languages"},f:[{t:4,f:[{p:[38,7,1315],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[38,25,1333]}]},f:[{p:[39,9,1352],t:7,e:"span",f:[{t:2,r:"desc",p:[39,15,1358]}]}," ",{p:[40,9,1383],t:7,e:"span",f:["Key: ,",{t:2,r:"key",p:[40,21,1395]}]}," ",{p:[41,9,1419],t:7,e:"ui-button",a:{action:"grant_language",params:['{"language_name":"',{t:2,r:"name",p:[43,37,1502]},'"}']},f:["Grant"]}]}],n:52,r:"data.unknown_languages",p:[37,5,1275]}]}],n:50,r:"data.admin_mode",p:[28,1,978]}]},e.exports=a.extend(r.exports)},{341:341}],407:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Controls"},f:[{t:4,f:[{t:4,f:[{p:[4,4,84],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[5,5,118],t:7,e:"span",f:["Launchpad closed."]}]}],n:50,r:"data.pad_closed",p:[3,3,56]},{t:4,n:51,f:[{p:[8,4,183],t:7,e:"ui-section",a:{label:"Launchpad"},f:[{p:[9,4,218],t:7,e:"span",f:[{p:[9,10,224],t:7,e:"b",f:[{t:2,
+r:"data.pad_name",p:[9,13,227]}]}]},{p:[9,41,255],t:7,e:"br"}," ",{p:[10,4,264],t:7,e:"ui-button",a:{icon:"pencil",action:"rename"},f:["Rename"]}," ",{p:[11,4,328],t:7,e:"ui-button",a:{icon:"remove",style:"danger",action:"remove"},f:["Remove"]}]}," ",{p:[14,4,427],t:7,e:"ui-section",a:{label:"Set Target"},f:[{p:[15,4,463],t:7,e:"table",f:[{p:[16,4,475],t:7,e:"tr",f:[{p:[17,5,485],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[17,38,518],t:7,e:"ui-button",a:{action:"up-left"},f:["↖"]}]}," ",{p:[18,5,570],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[18,57,622],t:7,e:"ui-button",a:{action:"up"},f:["↑"]}]}," ",{p:[19,5,669],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[19,56,720],t:7,e:"ui-button",a:{action:"up-right"},f:["↗"]}]}]}," ",{p:[21,4,782],t:7,e:"tr",f:[{p:[22,5,792],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[22,38,825],t:7,e:"ui-button",a:{action:"left",style:"width:35px!important"},f:["←"]}]}," ",{p:[23,5,903],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[23,57,955],t:7,e:"ui-button",a:{action:"reset"},f:["R"]}]}," ",{p:[24,5,1005],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[24,56,1056],t:7,e:"ui-button",a:{action:"right"},f:["→"]}]}]}," ",{p:[26,4,1115],t:7,e:"tr",f:[{p:[27,5,1125],t:7,e:"td",a:{style:"width:25px!important"},f:[{p:[27,38,1158],t:7,e:"ui-button",a:{action:"down-left"},f:["↙"]}]}," ",{p:[28,5,1212],t:7,e:"td",a:{style:"width:25px!important; text-align:center"},f:[{p:[28,57,1264],t:7,e:"ui-button",a:{action:"down"},f:["↓"]}]}," ",{p:[29,5,1313],t:7,e:"td",a:{style:"width:25px!important; text-align:right"},f:[{p:[29,56,1364],t:7,e:"ui-button",a:{action:"down-right"},f:["↘"]}]}]}]}]}," ",{p:[33,4,1459],t:7,e:"ui-section",a:{label:"Current Target"},f:[{p:[34,5,1500],t:7,e:"span",f:[{t:2,r:"data.abs_y",p:[34,11,1506]}," ",{t:2,r:"data.north_south",p:[34,26,1521]}]},{p:[34,53,1548],t:7,e:"br"}," ",{p:[35,5,1558],t:7,e:"span",f:[{t:2,r:"data.abs_x",p:[35,11,1564]}," ",{t:2,r:"data.east_west",p:[35,26,1579]}]}]}," ",{p:[37,4,1627],t:7,e:"ui-section",a:{label:"Activate"},f:[{p:[38,5,1662],t:7,e:"ui-button",a:{action:"launch",tooltip:"Teleport everything on the pad to the target.","tooltip-side":"down"},f:["Launch"]}," ",{p:[39,5,1789],t:7,e:"ui-button",a:{action:"pull",tooltip:"Teleport everything from the target to the pad.","tooltip-side":"down"},f:["Pull"]}]}],r:"data.pad_closed"}],n:50,r:"data.has_pad",p:[2,2,32]},{t:4,n:51,f:[{p:[45,3,1956],t:7,e:"ui-section",a:{label:"Warning"},f:[{p:[46,4,1989],t:7,e:"span",f:["No launchpad found. Link the remote to a launchpad."]}]}],r:"data.has_pad"}]}]},e.exports=a.extend(r.exports)},{341:341}],408:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{mechChargeState:function(t){var e=this.get("data.recharge_port.mech.cell.maxcharge");return t>=e/1.5?"good":t>=e/3?"average":"bad"},mechHealthState:function(t){var e=this.get("data.recharge_port.mech.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[20,1,545],t:7,e:"ui-display",a:{title:"Mech Status"},f:[{t:4,f:[{t:4,f:[{p:[23,4,646],t:7,e:"ui-section",a:{label:"Integrity"},f:[{p:[24,6,683],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,27,704]}],value:[{t:2,r:"adata.recharge_port.mech.health",p:[24,74,751]}],state:[{t:2,x:{r:["mechHealthState","adata.recharge_port.mech.health"],s:"_0(_1)"},p:[24,117,794]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.health"],s:"Math.round(_0)"},p:[24,171,848]},"/",{t:2,r:"adata.recharge_port.mech.maxhealth",p:[24,219,896]}]}]}," ",{t:4,f:[{t:4,f:[{p:[28,5,1061],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[28,31,1087],t:7,e:"span",a:{"class":"bad"},f:["Cell Critical Failure"]}]}],n:50,r:"data.recharge_port.mech.cell.critfail",p:[27,3,1010]},{t:4,n:51,f:[{p:[30,11,1170],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[31,13,1210],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.recharge_port.mech.cell.maxcharge",p:[31,34,1231]}],value:[{t:2,r:"adata.recharge_port.mech.cell.charge",p:[31,86,1283]}],state:[{t:2,x:{r:["mechChargeState","adata.recharge_port.mech.cell.charge"],s:"_0(_1)"},p:[31,134,1331]}]},f:[{t:2,x:{r:["adata.recharge_port.mech.cell.charge"],s:"Math.round(_0)"},p:[31,193,1390]},"/",{t:2,x:{r:["adata.recharge_port.mech.cell.maxcharge"],s:"Math.round(_0)"},p:[31,246,1443]}]}]}],r:"data.recharge_port.mech.cell.critfail"}],n:50,r:"data.recharge_port.mech.cell",p:[26,4,970]},{t:4,n:51,f:[{p:[35,3,1558],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[35,29,1584],t:7,e:"span",a:{"class":"bad"},f:["Cell Missing"]}]}],r:"data.recharge_port.mech.cell"}],n:50,r:"data.recharge_port.mech",p:[22,2,610]},{t:4,n:51,f:[{p:[38,4,1662],t:7,e:"ui-section",f:["Mech Not Found"]}],r:"data.recharge_port.mech"}],n:50,r:"data.recharge_port",p:[21,3,581]},{t:4,n:51,f:[{p:[41,5,1729],t:7,e:"ui-section",f:["Recharging Port Not Found"]}," ",{p:[42,2,1782],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}],r:"data.recharge_port"}]}]},e.exports=a.extend(r.exports)},{341:341}],409:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{t:4,f:[{p:[3,5,45],t:7,e:"ui-section",a:{label:"Interface Lock"},f:[{p:[4,7,88],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock":"unlock"'},p:[4,24,105]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Engaged":"Disengaged"'},p:[4,75,156]}]}]}],n:50,r:"data.siliconUser",p:[2,3,15]},{t:4,n:51,f:[{p:[7,5,247],t:7,e:"span",f:["Swipe an ID card to ",{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[7,31,273]}," this interface."]}],r:"data.siliconUser"}]}," ",{p:[10,1,358],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[11,3,389],t:7,e:"ui-section",a:{label:"Power"},f:[{t:4,f:[{p:[13,7,470],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[13,24,487]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[13,68,531]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[13,116,579]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[12,5,421]},{t:4,n:51,f:[{p:[15,7,639],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.on"],s:'_0?"good":"bad"'},p:[15,20,652]}],state:[{t:2,x:{r:["data.cell"],s:'_0?null:"disabled"'},p:[15,57,689]}]},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[15,92,724]}]}],x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"}}]}," ",{p:[18,3,791],t:7,e:"ui-section",a:{label:"Cell"},f:[{p:[19,5,822],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.cell"],s:'_0?null:"bad"'},p:[19,18,835]}]},f:[{t:2,x:{r:["data.cell","data.cellPercent"],s:'_0?_1+"%":"No Cell"'},p:[19,48,865]}]}]}," ",{p:[21,3,943],t:7,e:"ui-section",a:{label:"Mode"},f:[{p:[22,5,974],t:7,e:"span",a:{"class":[{t:2,r:"data.modeStatus",p:[22,18,987]}]},f:[{t:2,r:"data.mode",p:[22,39,1008]}]}]}," ",{p:[24,3,1049],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[25,5,1080],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.load"],s:'_0?"good":"average"'},p:[25,18,1093]}]},f:[{t:2,x:{r:["data.load"],s:'_0?_0:"None"'},p:[25,54,1129]}]}]}," ",{p:[27,3,1191],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[28,5,1229],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.destination"],s:'_0?"good":"average"'},p:[28,18,1242]}]},f:[{t:2,x:{r:["data.destination"],s:'_0?_0:"None"'},p:[28,60,1284]}]}]}]}," ",{t:4,f:[{p:{button:[{t:4,f:[{p:[35,9,1513],t:7,e:"ui-button",a:{icon:"eject",action:"unload"},f:["Unload"]}],n:50,r:"data.load",p:[34,7,1486]}," ",{t:4,f:[{p:[38,9,1623],t:7,e:"ui-button",a:{icon:"eject",action:"ejectpai"},f:["Eject PAI"]}],n:50,r:"data.haspai",p:[37,7,1594]}," ",{p:[40,7,1709],t:7,e:"ui-button",a:{icon:"pencil",action:"setid"},f:["Set ID"]}]},t:7,e:"ui-display",a:{title:"Controls",button:0},f:[" ",{p:[42,5,1791],t:7,e:"ui-section",a:{label:"Destination"},f:[{p:[43,7,1831],t:7,e:"ui-button",a:{icon:"pencil",action:"destination"},f:["Set Destination"]}," ",{p:[44,7,1912],t:7,e:"ui-button",a:{icon:"stop",action:"stop"},f:["Stop"]}," ",{p:[45,7,1973],t:7,e:"ui-button",a:{icon:"play",action:"go"},f:["Go"]}]}," ",{p:[47,5,2047],t:7,e:"ui-section",a:{label:"Home"},f:[{p:[48,7,2080],t:7,e:"ui-button",a:{icon:"home",action:"home"},f:["Go Home"]}," ",{p:[49,7,2144],t:7,e:"ui-button",a:{icon:"pencil",action:"sethome"},f:["Set Home"]}]}," ",{p:[51,5,2231],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[52,7,2268],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoReturn"],s:'_0?"check-square-o":"square-o"'},p:[52,24,2285]}],style:[{t:2,x:{r:["data.autoReturn"],s:'_0?"selected":null'},p:[52,84,2345]}],action:"autoret"},f:["Auto-Return Home"]}," ",{p:[54,7,2449],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.autoPickup"],s:'_0?"check-square-o":"square-o"'},p:[54,24,2466]}],style:[{t:2,x:{r:["data.autoPickup"],s:'_0?"selected":null'},p:[54,84,2526]}],action:"autopick"},f:["Auto-Pickup Crate"]}," ",{p:[56,7,2632],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"check-square-o":"square-o"'},p:[56,24,2649]}],style:[{t:2,x:{r:["data.reportDelivery"],s:'_0?"selected":null'},p:[56,88,2713]}],action:"report"},f:["Report Deliveries"]}]}]}],n:50,x:{r:["data.locked","data.siliconUser"],s:"!_0||_1"},p:[31,1,1373]}]},e.exports=a.extend(r.exports)},{341:341}],410:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Chamber Console"},f:[{p:[2,1,45],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{t:4,f:[{p:[4,2,104],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]},{p:[4,63,165],t:7,e:"br"}," ",{t:4,f:[{p:[6,3,200],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[6,36,233]}]}," ",{p:[7,3,268],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[7,35,300]}]}," ",{p:[8,3,335],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["data.disk.activated"],s:'_0?"Active":"Inactive"'},p:[8,41,373]}]}," ",{t:4,f:[{p:[10,4,477],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"data.disk.activation_delay",p:[10,41,514]}]}],n:50,r:"data.disk.activation_delay",p:[9,3,438]}," ",{t:4,f:[{p:[13,4,600],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"data.disk.timer",p:[13,30,626]}]}," ",{p:[14,4,663],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"data.disk.timer_type",p:[14,36,695]}]}],n:50,r:"data.disk.timer",p:[12,3,572]}," ",{t:4,f:[{p:[17,4,785],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"data.disk.activation_code",p:[17,40,821]}]}],n:50,r:"data.disk.activation_code",p:[16,3,747]}," ",{t:4,f:[{p:[20,4,918],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"data.disk.deactivation_code",p:[20,42,956]}]}],n:50,r:"data.disk.deactivation_code",p:[19,3,878]}," ",{t:4,f:[{p:[23,4,1047],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"data.disk.kill_code",p:[23,34,1077]}]}],n:50,r:"data.disk.kill_code",p:[22,3,1015]}," ",{t:4,f:[{p:[26,4,1163],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"data.disk.trigger_code",p:[26,37,1196]}]}],n:50,r:"data.disk.trigger_code",p:[25,3,1128]}," ",{t:4,f:[{t:4,f:[{p:[30,6,1332],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[30,25,1351]}]},f:[{t:2,r:"value",p:[30,35,1361]}]}],n:52,r:"data.disk.extra_settings",p:[29,4,1291]}],n:50,r:"data.disk.has_extra_settings",p:[28,3,1250]}],n:50,r:"data.has_program",p:[5,2,172]},{t:4,n:51,f:[{p:[34,3,1423],t:7,e:"ui-notice",f:["No program detected."]}],r:"data.has_program"}],n:50,r:"data.has_disk",p:[3,1,80]},{t:4,n:51,f:[{p:[37,2,1489],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"}]}," ",{p:[40,1,1550],t:7,e:"br"}," ",{t:4,f:[{p:[42,2,1582],t:7,e:"ui-notice",f:[{t:2,r:"data.status_msg",p:[42,13,1593]}]}],n:50,r:"data.status_msg",p:[41,1,1556]},{t:4,n:51,f:[{p:[44,2,1637],t:7,e:"ui-display",a:{title:"Chamber"},f:[{p:[45,2,1668],t:7,e:"ui-section",f:[{p:[45,14,1680],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"lock-open":"lock"'},p:[45,30,1696]}],action:"toggle_lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[45,90,1756]}," Chamber"]},{p:[45,146,1812],t:7,e:"br"}]}," ",{p:[46,2,1832],t:7,e:"ui-section",f:[{p:[46,14,1844],t:7,e:"b",f:["Occupant:"]}," ",{t:2,r:"data.occupant_name",p:[46,31,1861]}]}," ",{t:4,f:[{p:[48,4,1929],t:7,e:"ui-section",f:[{p:[48,16,1941],t:7,e:"ui-notice",f:["No nanites detected."]}]}," ",{p:[49,4,2002],t:7,e:"ui-section",f:[{p:[49,16,2014],t:7,e:"ui-button",a:{icon:"syringe",action:"nanite_injection"},f:["Implant Nanites"]}]}],n:50,x:{r:["data.has_nanites"],s:"!_0"},p:[47,2,1899]},{t:4,n:51,f:[{p:[51,3,2121],t:7,e:"ui-display",a:{title:"Nanites"},f:[{t:4,f:[{p:[53,5,2181],t:7,e:"ui-button",a:{icon:"download",action:"add_program"},f:["Install Program From Disk"]},{p:[53,90,2266],t:7,e:"br"}," ",{p:[54,5,2276],t:7,e:"br"}],n:50,r:"data.has_disk",p:[52,4,2154]}," ",{p:[56,4,2297],t:7,e:"ui-section",f:[{p:[57,5,2315],t:7,e:"ui-section",a:{label:"Nanite Volume"},f:[{t:2,r:"data.nanite_volume",p:[57,39,2349]}]}," ",{p:[58,5,2390],t:7,e:"ui-section",a:{label:"Growth Rate"},f:[{t:2,r:"data.regen_rate",p:[58,37,2422]}]}," ",{p:[59,5,2460],t:7,e:"ui-section",a:{label:"Safety Threshold"},f:[{t:2,r:"data.safety_threshold",p:[59,42,2497]}," ",{p:[59,68,2523],t:7,e:"ui-button",a:{icon:"pencil",action:"set_safety"},f:["Set"]}]}," ",{p:[60,5,2603],t:7,e:"ui-section",a:{label:"Cloud ID"},f:[{t:2,x:{r:["data.cloud_id"],s:'_0?_0:"No Cloud"'},p:[60,34,2632]}," ",{p:[60,82,2680],t:7,e:"ui-button",a:{icon:"pencil",action:"set_cloud"},f:["Set"]}]}]}," ",{p:[62,4,2776],t:7,e:"ui-display",a:{title:"Programs"},f:[{t:4,f:[{p:[64,6,2845],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[64,25,2864]}],button:0},f:[{p:[65,6,2888],t:7,e:"ui-button",a:{icon:"minus",action:"remove_program",params:['{"program_id": "',{t:2,r:"id",p:[65,78,2960]},'"}']},f:["Uninstall"]}," ",{p:[66,6,2998],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"desc",p:[66,38,3030]}]}," ",{t:4,f:[{p:[68,7,3094],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["activated"],s:'_0?"Active":"Inactive"'},p:[68,45,3132]}]}," ",{p:[69,7,3191],t:7,e:"ui-section",a:{label:"Nanites Consumed"},f:[{t:2,r:"use_rate",p:[69,44,3228]},"/s"]}," ",{t:4,f:[{p:[71,8,3291],t:7,e:"ui-section",a:{label:"Trigger Cost"},f:[{t:2,r:"trigger_cost",p:[71,41,3324]}]}," ",{p:[72,8,3362],t:7,e:"ui-section",a:{label:"Trigger Cooldown"},f:[{t:2,r:"trigger_cooldown",p:[72,45,3399]}," seconds"]}],n:50,r:"can_trigger",p:[70,7,3263]}," ",{t:4,f:[{t:4,f:[{p:[76,9,3534],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"activation_delay",p:[76,46,3571]}]}],n:50,r:"activation_delay",p:[75,8,3500]}," ",{t:4,f:[{p:[79,9,3652],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"timer",p:[79,35,3678]}]}," ",{p:[80,9,3710],t:7,e:"ui-section",a:{label:"Timer Type"},f:[{t:2,r:"timer_type",p:[80,40,3741]}]}],n:50,r:"timer",p:[78,8,3629]}," ",{t:4,f:[{t:4,f:[{p:[84,11,3865],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[84,30,3884]}]},f:[{t:2,r:"value",p:[84,40,3894]}]}],n:52,r:"extra_settings",p:[83,9,3829]}],n:50,r:"has_extra_settings",p:[82,8,3793]}," ",{t:4,f:[{t:4,f:[{p:[89,10,4032],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"activation_code",p:[89,46,4068]}]}],n:50,r:"activation_code",p:[88,9,3998]}," ",{t:4,f:[{p:[92,10,4163],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"deactivation_code",p:[92,48,4201]}]}],n:50,r:"deactivation_code",p:[91,9,4127]}," ",{t:4,f:[{p:[95,10,4290],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"kill_code",p:[95,40,4320]}]}],n:50,r:"kill_code",p:[94,9,4262]}," ",{t:4,f:[{p:[98,10,4404],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"trigger_code",p:[98,43,4437]}]}],n:50,r:"trigger_code",p:[97,9,4373]}],n:50,x:{r:["data.scan_level"],s:"_0>=4"},p:[87,8,3960]}],n:50,x:{r:["data.scan_level"],s:"_0>=3"},p:[74,7,3463]}],n:50,x:{r:["data.scan_level"],s:"_0>=2"},p:[67,6,3058]}]}],n:52,r:"data.mob_programs",p:[63,5,2811]}]}]}],x:{r:["data.has_nanites"],s:"!_0"}}]}],r:"data.status_msg"}]}]},e.exports=a.extend(r.exports)},{341:341}],411:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Cloud Console"},f:[{p:[2,1,43],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{t:4,f:[{p:[4,3,104],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]},{p:[4,64,165],t:7,e:"br"}," ",{t:4,f:[{p:[6,4,202],t:7,e:"ui-section",f:[{p:[7,5,220],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[7,38,253]}]}," ",{p:[8,5,290],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[8,37,322]}]}," ",{p:[9,5,359],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["data.disk.activated"],s:'_0?"Active":"Inactive"'},p:[9,43,397]}]}," ",{t:4,f:[{p:[11,6,505],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"data.disk.activation_delay",p:[11,43,542]}]}],n:50,r:"data.disk.activation_delay",p:[10,5,464]}," ",{t:4,f:[{p:[14,6,634],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"data.disk.timer",p:[14,32,660]}]}," ",{p:[15,6,699],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"data.disk.timer_type",p:[15,38,731]}]}],n:50,r:"data.disk.timer",p:[13,5,604]}," ",{t:4,f:[{p:[18,6,827],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"data.disk.activation_code",p:[18,42,863]}]}],n:50,r:"data.disk.activation_code",p:[17,5,787]}," ",{t:4,f:[{p:[21,6,966],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"data.disk.deactivation_code",p:[21,44,1004]}]}],n:50,r:"data.disk.deactivation_code",p:[20,5,924]}," ",{t:4,f:[{p:[24,6,1101],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"data.disk.kill_code",p:[24,36,1131]}]}],n:50,r:"data.disk.kill_code",p:[23,5,1067]}," ",{t:4,f:[{p:[27,6,1223],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"data.disk.trigger_code",p:[27,39,1256]}]}],n:50,r:"data.disk.trigger_code",p:[26,5,1186]}," ",{t:4,f:[{t:4,f:[{p:[31,8,1400],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[31,27,1419]}]},f:[{t:2,r:"value",p:[31,37,1429]}]}],n:52,r:"data.disk.extra_settings",p:[30,6,1357]}],n:50,r:"data.disk.has_extra_settings",p:[29,5,1314]}]}],n:50,r:"data.has_program",p:[5,3,173]},{t:4,n:51,f:[{p:[36,4,1515],t:7,e:"ui-notice",f:["No program detected."]}],r:"data.has_program"}],n:50,r:"data.has_disk",p:[3,2,79]},{t:4,n:51,f:[{p:[39,3,1584],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"}]}," ",{p:[42,1,1646],t:7,e:"ui-display",a:{title:"Cloud Storage"},f:[{t:4,f:[{p:[44,3,1713],t:7,e:"ui-button",a:{icon:"plus-circle",action:"create_backup"},f:["Create New Backup"]}," ",{p:[45,3,1799],t:7,e:"ui-display",a:{title:"Active Backups"},f:[{t:4,f:[{p:[47,5,1873],t:7,e:"ui-button",a:{action:"set_view",params:['{"view": "',{t:2,r:"cloud_id",p:[47,52,1920]},'"}']},f:["Backup #",{t:2,r:"cloud_id",p:[47,76,1944]}]}],n:52,r:"data.cloud_backups",p:[46,4,1839]}]}],n:50,x:{r:["data.current_view"],s:"!_0"},p:[43,2,1683]},{t:4,n:51,f:[{p:[51,3,2014],t:7,e:"ui-button",a:{icon:"undo",action:"set_view",params:'{"view": "0"}'},f:["Return"]}," ",{t:4,f:[{p:[53,4,2131],t:7,e:"ui-notice",f:["ERROR: Backup not found."]}],n:50,x:{r:["data.cloud_backup"],s:"!_0"},p:[52,3,2100]},{t:4,n:51,f:[{p:[55,4,2195],t:7,e:"ui-display",a:{title:["Backup #",{t:2,r:"data.current_view",p:[55,31,2222]}]},f:[{t:4,f:[{p:[57,6,2282],t:7,e:"ui-button",a:{icon:"upload",action:"upload_program",style:"selected"},f:["Upload Program From Disk"]},{p:[57,108,2384],t:7,e:"br"}],n:50,r:"data.has_program",p:[56,5,2251]}," ",{t:4,f:[{p:[60,6,2443],t:7,e:"hr"}," ",{p:[61,6,2454],t:7,e:"ui-section",f:[{p:[62,7,2474],t:7,e:"h3",f:[{t:2,r:"name",p:[62,11,2478]}]}," ",{p:[63,7,2499],t:7,e:"div",a:{style:"float:right"},f:[{p:[64,8,2533],t:7,e:"ui-button",a:{icon:"minus-circle",action:"remove_program",style:"danger",params:['{"program_id": "',{t:2,r:"id",p:[64,102,2627]},'"}']},f:["Uninstall"]}]}]}," ",{p:[67,6,2699],t:7,e:"ui-section",f:[{p:[68,7,2719],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"desc",p:[68,39,2751]}]}," ",{p:[69,7,2780],t:7,e:"ui-section",a:{label:"Activation Status"},f:[{t:2,x:{r:["activated"],s:'_0?"Active":"Inactive"'},p:[69,45,2818]}]}," ",{p:[70,7,2877],t:7,e:"ui-section",a:{label:"Nanites Consumed"},f:[{t:2,r:"use_rate",p:[70,44,2914]},"/s"]}," ",{t:4,f:[{p:[72,8,2977],t:7,e:"ui-section",a:{label:"Trigger Cost"},f:[{t:2,r:"trigger_cost",p:[72,41,3010]},"/s"]}," ",{p:[73,8,3050],t:7,e:"ui-section",a:{label:"Trigger Cooldown"},f:[{t:2,r:"trigger_cooldown",p:[73,45,3087]},"/s"]}],n:50,r:"can_trigger",p:[71,7,2949]}," ",{t:4,f:[{p:[76,8,3178],t:7,e:"ui-section",a:{label:"Activation Delay"},f:[{t:2,r:"activation_delay",p:[76,45,3215]}]}],n:50,r:"activation_delay",p:[75,7,3145]}," ",{t:4,f:[{p:[79,8,3293],t:7,e:"ui-section",a:{label:"Timer"},f:[{t:2,r:"timer",p:[79,34,3319]}]}," ",{p:[80,8,3350],t:7,e:"ui-section",a:{label:"Timer Type "},f:[{t:2,r:"timer_type",p:[80,40,3382]}]}],n:50,r:"timer",p:[78,7,3271]}," ",{t:4,f:[{p:[83,8,3464],t:7,e:"ui-section",a:{label:"Activation Code"},f:[{t:2,r:"activation_code",p:[83,44,3500]}]}],n:50,r:"activation_code",p:[82,7,3432]}," ",{t:4,f:[{p:[86,8,3589],t:7,e:"ui-section",a:{label:"Deactivation Code"},f:[{t:2,r:"deactivation_code",p:[86,46,3627]}]}],n:50,r:"deactivation_code",p:[85,7,3555]}," ",{t:4,f:[{p:[89,8,3710],t:7,e:"ui-section",a:{label:"Kill Code"},f:[{t:2,r:"kill_code",p:[89,38,3740]}]}],n:50,r:"kill_code",p:[88,7,3684]}," ",{t:4,f:[{p:[92,8,3818],t:7,e:"ui-section",a:{label:"Trigger Code"},f:[{t:2,r:"trigger_code",p:[92,41,3851]}]}],n:50,r:"trigger_code",p:[91,7,3789]}," ",{t:4,f:[{t:4,f:[{p:[96,10,3973],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[96,29,3992]}]},f:[{t:2,r:"value",p:[96,39,4002]}]}],n:52,r:"extra_settings",p:[95,8,3938]}],n:50,r:"has_extra_settings",p:[94,7,3903]}]}],n:52,r:"data.cloud_programs",p:[59,5,2407]}]}],x:{r:["data.cloud_backup"],s:"!_0"}}],x:{r:["data.current_view"],s:"!_0"}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],412:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Program Hub"},f:[{t:4,f:[{p:[3,2,65],t:7,e:"ui-display",a:{title:"Program Disk"},f:[{p:[4,3,102],t:7,e:"ui-section",f:[{p:[5,4,119],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]}," ",{p:[6,4,185],t:7,e:"ui-button",a:{icon:"minus-circle",action:"clear"},f:["Delete Program"]}]}," ",{t:4,f:[{p:[9,4,307],t:7,e:"ui-section",a:{label:"Program Name"},f:[{t:2,r:"data.disk.name",p:[9,37,340]}]}," ",{p:[10,4,376],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.disk.desc",p:[10,36,408]}]}],n:50,r:"data.has_program",p:[8,3,278]},{t:4,n:51,f:[{p:[12,4,456],t:7,e:"ui-notice",f:["No program installed."]}],r:"data.has_program"}]}],n:50,r:"data.has_disk",p:[2,1,41]},{t:4,n:51,f:[{p:[16,2,540],t:7,e:"ui-notice",f:["Insert disk."]}],r:"data.has_disk"},{p:[18,1,586],t:7,e:"br"}," ",{p:[19,1,592],t:7,e:"ui-display",a:{title:"Programs"},f:[{p:[20,2,624],t:7,e:"ui-section",f:[{p:[21,3,640],t:7,e:"ui-button",a:{icon:"undo",action:"set_category",params:'{"category": "Main"}'},f:["Return"]}," ",{p:[22,3,737],t:7,e:"ui-button",a:{icon:"align-justify ",action:"toggle_details"},f:[{t:2,x:{r:["data.detail_view"],s:'_0?"Compact View":"Detailed View"'},p:[22,60,794]}]}]}," ",{t:4,f:[{p:[25,3,916],t:7,e:"ui-display",f:[{t:4,f:[{p:[27,5,964],t:7,e:"ui-section",f:[{p:[27,17,976],t:7,e:"ui-button",a:{action:"set_category",params:['{"category": "',{t:2,r:"name",p:[27,72,1031]},'"}']},f:[{t:2,r:"name",p:[27,84,1043]}]}]}],n:52,r:"data.categories",p:[26,4,933]}]}],n:50,x:{r:["data.category"],s:'_0=="Main"'},p:[24,2,881]},{t:4,n:51,f:[{p:[31,3,1122],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[31,22,1141]}]},f:[{t:4,f:[{t:4,f:[{p:[34,6,1229],t:7,e:"ui-display",f:[{p:[35,7,1249],t:7,e:"ui-section",f:[{p:[35,19,1261],t:7,e:"b",f:[{t:2,r:"name",p:[35,22,1264]}]}]}," ",{p:[36,7,1297],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[36,19,1309]}]}," ",{p:[37,7,1338],t:7,e:"ui-section",f:[{p:[38,8,1359],t:7,e:"ui-button",a:{icon:"download",action:"download",params:['{"program_id": "',{t:2,r:"id",p:[38,77,1428]},'"}'],state:[{t:2,x:{r:["data.has_disk"],s:'_0?null:"disabled"'},p:[38,94,1445]}]},f:["Download"]}]}]}],n:50,r:"data.detail_view",p:[33,5,1198]},{t:4,n:51,f:[{p:[44,6,1585],t:7,e:"ui-section",f:[{p:[44,18,1597],t:7,e:"ui-button",a:{action:"download",params:['{"program_id": "',{t:2,r:"id",p:[44,71,1650]},'"}']},f:[{t:2,r:"name",p:[44,81,1660]}]}]}],r:"data.detail_view"}],n:52,r:"data.program_list",p:[32,4,1165]}]}],x:{r:["data.category"],s:'_0=="Main"'}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],413:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Programming"},f:[{t:4,f:[{p:[3,3,67],t:7,e:"ui-notice",f:["Insert a nanite program disk."]}],n:50,x:{r:["data.has_disk"],s:"!_0"},p:[2,1,41]},{t:4,n:51,f:[{p:[5,3,133],t:7,e:"ui-button",a:{icon:"eject",action:"eject"},f:["Eject Disk"]}," ",{t:4,f:[{p:[7,5,229],t:7,e:"ui-notice",f:["No program detected."]}],n:50,x:{r:["data.has_program"],s:"!_0"},p:[6,3,198]},{t:4,n:51,f:[{p:[9,5,290],t:7,e:"ui-section",f:[{p:[10,7,310],t:7,e:"ui-display",a:{title:[{t:2,r:"data.name",p:[10,26,329]}]},f:[{t:2,r:"data.desc",p:[11,9,354]}]}]}," ",{p:[14,5,413],t:7,e:"ui-section",f:[{p:[15,7,433],t:7,e:"ui-section",a:{label:"Program Info"},f:["Nanites Consumed: ",{t:2,r:"data.use_rate",p:[16,26,493]},{p:[16,43,510],t:7,e:"br"}," ",{t:4,f:["Trigger Cost: ",{t:2,r:"data.trigger_cost",p:[18,25,574]},"u",{p:[18,47,596],t:7,e:"br"}],n:50,r:"data.can_trigger",p:[17,9,524]}]}," ",{p:[22,7,648],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[23,9,685],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.activated"],s:'_0?"toggle-on":"toggle-off"'},p:[24,17,713]}],action:"toggle_active"},f:[{t:2,x:{r:["data.activated"],s:'_0?"Active":"Inactive"'},p:[26,11,809]}]}]}," ",{p:[30,7,905],t:7,e:"ui-section",a:{label:"Settings"},f:[{p:[31,9,944],t:7,e:"ui-button",a:{icon:"pencil",action:"set_activation_delay"}}," Activation Delay: ",{t:2,r:"data.activation_delay",p:[31,95,1030]}," ",{p:[31,121,1056],t:7,e:"br"}," ",{p:[32,9,1070],t:7,e:"ui-button",a:{icon:"pencil",action:"set_timer"}}," Timer: ",{t:2,r:"data.timer",p:[32,73,1134]}," ",{p:[32,88,1149],t:7,e:"br"}," ",{p:[33,9,1163],t:7,e:"ui-button",a:{icon:"pencil",action:"set_timer_type"}}," Timer Type: ",{t:2,r:"data.timer_type",p:[33,83,1237]}," ",{p:[33,103,1257],t:7,e:"br"}]}," ",{p:[36,7,1292],t:7,e:"ui-section",a:{label:"Codes"},f:[{p:[37,9,1328],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "activation"}'}}," Activation Code: ",{t:2,r:"data.activation_code",p:[37,121,1440]}," ",{p:[37,146,1465],t:7,e:"br"}," ",{p:[38,9,1479],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "deactivation"}'}}," Deactivation Code: ",{t:2,r:"data.deactivation_code",p:[38,125,1595]}," ",{p:[38,152,1622],t:7,e:"br"}," ",{p:[39,9,1636],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "kill"}'}}," Kill Code: ",{t:2,r:"data.kill_code",p:[39,109,1736]}," ",{p:[39,128,1755],t:7,e:"br"}," ",{t:4,f:[{p:[41,11,1805],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code",params:'{"target_code": "trigger"}'}}," Trigger Code: ",{t:2,r:"data.trigger_code",p:[41,117,1911]}," ",{p:[41,139,1933],t:7,e:"br"}],n:50,r:"data.can_trigger",p:[40,9,1769]}]}," ",{t:4,f:[{p:[46,9,2026],t:7,e:"ui-section",a:{label:"Special"},f:[{t:4,f:[{p:[48,13,2109],t:7,e:"ui-button",a:{icon:"pencil",action:"set_extra_setting",params:['{"target_setting": "',{t:2,r:"name",p:[48,93,2189]},'"}']}}," ",{t:2,r:"name",p:[48,118,2214]},": ",{t:2,r:"value",p:[48,128,2224]}," ",{p:[48,138,2234],t:7,e:"br"}],n:52,r:"data.extra_settings",p:[47,11,2066]}]}],n:50,r:"data.has_extra_settings",p:[45,7,1985]}]}],x:{r:["data.has_program"],s:"!_0"}}],x:{r:["data.has_disk"],s:"!_0"}}]}]},e.exports=a.extend(r.exports)},{341:341}],414:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Nanite Control"},f:[{t:4,f:[{p:[3,3,60],t:7,e:"ui-notice",f:["The interface is locked."]}],n:50,r:"data.locked",p:[2,1,37]},{t:4,n:51,f:[{p:[5,3,121],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock Interface"]}," ",{p:[6,3,188],t:7,e:"ui-button",a:{icon:"save",action:"save"},f:["Save Current Setting"]}," ",{p:[7,3,261],t:7,e:"ui-section",a:{label:"Signal Code"},f:[{p:[8,5,299],t:7,e:"span",f:[{t:2,r:"data.code",p:[8,11,305]}]}," ",{p:[9,4,330],t:7,e:"ui-button",a:{icon:"pencil",action:"set_code"},f:["Set"]}]}," ",{t:4,f:[{p:[12,5,443],t:7,e:"ui-section",a:{label:"Relay Code"},f:[{p:[13,7,482],t:7,e:"span",f:[{t:2,r:"data.relay_code",p:[13,13,488]}]}," ",{p:[14,5,520],t:7,e:"ui-button",a:{icon:"pencil",action:"set_relay_code"},f:["Set"]}]}],n:50,x:{r:["data.mode"],s:'_0=="Relay"'},p:[11,3,409]}," ",{p:[17,3,618],t:7,e:"ui-section",a:{label:"Signal Mode"},f:[{p:[18,5,656],t:7,e:"span",f:[{t:2,r:"data.mode",p:[18,11,662]}]}," ",{p:[19,5,688],t:7,e:"br"}," ",{p:[20,4,697],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Off"}'},f:["Off"]}," ",{p:[21,5,775],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Local"}'},f:["Local"]}," ",{p:[22,5,857],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Targeted"}'},f:["Targeted"]}," ",{p:[23,5,945],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Area"}'},f:["Area"]}," ",{p:[24,5,1025],t:7,e:"ui-button",a:{action:"select_mode",params:'{"mode": "Relay"}'},f:["Relay"]}]}],r:"data.locked"}]}," ",{p:[28,1,1144],t:7,e:"ui-display",a:{title:"Saved Settings"},f:[{t:4,f:[{p:[30,3,1215],t:7,e:"ui-button",a:{icon:"load",action:"load",params:['{"save_id": "',{t:2,r:"id",p:[30,61,1273]},'"}']},f:[{t:2,r:"name",p:[30,71,1283]}]}," ",{t:4,f:[{p:[32,4,1332],t:7,e:"ui-button",a:{icon:"remove",action:"remove_save",params:['{"save_id": "',{t:2,r:"id",p:[32,71,1399]},'"}']},f:["Remove"]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[31,3,1307]}," ",{p:[34,3,1442],t:7,e:"br"}],n:52,r:"data.saved_settings",p:[29,2,1182]}]}]},e.exports=a.extend(r.exports)},{341:341}],415:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Ghost roles"},f:[{p:[2,2,35],t:7,e:"ui-section",a:{label:"Ignored roles"},f:[{t:4,f:[{p:[4,4,99],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[4,21,116]}],style:[{t:2,x:{r:["enabled"],s:'_0?"danger":null'},p:[4,73,168]}],action:"toggle_ignore",params:['{"key": "',{t:2,r:"key",p:[4,144,239]},'"}']},f:[{t:2,r:"desc",p:[4,155,250]}]}],n:52,r:"data.ignore",p:[3,3,73]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],416:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Relay"},f:[{t:4,f:[{p:[3,3,57],t:7,e:"h2",f:["NETWORK BUFFERS OVERLOADED"]}," ",{p:[4,3,96],t:7,e:"h3",f:["Overload Recovery Mode"]}," ",{p:[5,3,131],t:7,e:"i",f:["This system is suffering temporary outage due to overflow of traffic buffers. Until buffered traffic is processed, all further requests will be dropped. Frequent occurences of this error may indicate insufficient hardware capacity of your network. Please contact your network planning department for instructions on how to resolve this issue."]}," ",{p:[6,3,484],t:7,e:"h3",f:["ADMINISTRATIVE OVERRIDE"]}," ",{p:[7,3,520],t:7,e:"b",f:["CAUTION - Data loss may occur"]}," ",{p:[8,3,562],t:7,e:"ui-button",a:{icon:"signal",action:"restart"},f:["Purge buffered traffic"]}],n:50,r:"data.dos_crashed",p:[2,2,29]},{t:4,n:51,f:[{p:[12,3,663],t:7,e:"ui-section",a:{label:"Relay status"},f:[{p:[13,4,701],t:7,e:"ui-button",a:{icon:"power-off",action:"toggle"},f:[{t:2,x:{r:["data.enabled"],s:'_0?"ENABLED":"DISABLED"'},p:[14,6,752]}]}]}," ",{p:[18,3,836],t:7,e:"ui-section",a:{label:"Network buffer status"},f:[{t:2,r:"data.dos_overload",p:[19,4,883]}," / ",{t:2,r:"data.dos_capacity",p:[19,28,907]}," GQ"]}],r:"data.dos_crashed"}]}]},e.exports=a.extend(r.exports)},{
+341:341}],417:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{healthState:function(){var t=this.get("data.health");return t>70?"good":t>50?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,320],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[18,3,363],t:7,e:"ui-notice",f:[{p:[19,5,380],t:7,e:"span",f:["Reconstruction in progress!"]}]}],n:50,r:"data.restoring",p:[17,1,337]},{p:[24,1,451],t:7,e:"ui-display",f:[{p:[26,1,467],t:7,e:"div",a:{"class":"item"},f:[{p:[27,3,489],t:7,e:"div",a:{"class":"itemLabel"},f:["Inserted AI:"]}," ",{p:[30,3,541],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[31,2,569],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",state:[{t:2,x:{r:["data.nocard"],s:'_0?"disabled":null'},p:[31,52,619]}]},f:[{t:2,x:{r:["data.name"],s:'_0?_0:"---"'},p:[31,89,656]}]}]}]}," ",{t:4,f:[{p:[36,2,744],t:7,e:"b",f:["ERROR: ",{t:2,r:"data.error",p:[36,12,754]}]}],n:50,r:"data.error",p:[35,1,723]},{t:4,n:51,f:[{p:[38,2,785],t:7,e:"h2",f:["System Status"]}," ",{p:[39,2,810],t:7,e:"div",a:{"class":"item"},f:[{p:[40,3,832],t:7,e:"div",a:{"class":"itemLabel"},f:["Current AI:"]}," ",{p:[43,3,885],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.name",p:[44,4,915]}]}," ",{p:[46,3,942],t:7,e:"div",a:{"class":"itemLabel"},f:["Status:"]}," ",{p:[49,3,991],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["Nonfunctional"],n:50,r:"data.isDead",p:[50,4,1021]},{t:4,n:51,f:["Functional"],r:"data.isDead"}]}," ",{p:[56,3,1114],t:7,e:"div",a:{"class":"itemLabel"},f:["System Integrity:"]}," ",{p:[59,3,1173],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[60,4,1203],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.health",p:[60,37,1236]}],state:[{t:2,r:"healthState",p:[61,11,1264]}]},f:[{t:2,x:{r:["adata.health"],s:"Math.round(_0)"},p:[61,28,1281]},"%"]}]}," ",{p:[63,3,1336],t:7,e:"div",a:{"class":"itemLabel"},f:["Active Laws:"]}," ",{p:[66,3,1390],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[67,4,1420],t:7,e:"table",f:[{t:4,f:[{p:[69,6,1462],t:7,e:"tr",f:[{p:[69,10,1466],t:7,e:"td",f:[{p:[69,14,1470],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:".",p:[69,38,1494]}]}]}]}],n:52,r:"data.ai_laws",p:[68,5,1433]}]}]}," ",{p:[73,2,1547],t:7,e:"ui-section",a:{label:"Operations"},f:[{p:[74,3,1582],t:7,e:"ui-button",a:{icon:"plus",style:[{t:2,x:{r:["data.restoring"],s:'_0?"disabled":null'},p:[74,33,1612]}],action:"PRG_beginReconstruction"},f:["Begin Reconstruction"]}]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],418:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,1,91],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"home",params:'{"target" : "mod"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==1?"disabled":null'},p:[5,80,170]}]},f:["Access Modification"]}],n:50,r:"data.have_id_slot",p:[4,1,64]},{p:[7,1,253],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manage"}',state:[{t:2,x:{r:["data.mmode"],s:'_0==2?"disabled":null'},p:[7,90,342]}]},f:["Job Management"]}," ",{p:[8,1,411],t:7,e:"ui-button",a:{action:"PRG_switchm",icon:"folder-open",params:'{"target" : "manifest"}',state:[{t:2,x:{r:["data.mmode"],s:'!_0?"disabled":null'},p:[8,92,502]}]},f:["Crew Manifest"]}," ",{t:4,f:[{p:[10,1,593],t:7,e:"ui-button",a:{action:"PRG_print",icon:"print",state:[{t:2,x:{r:["data.has_id","data.mmode"],s:'!_1||_0&&_1==1?null:"disabled"'},p:[10,51,643]}]},f:["Print"]}],n:50,r:"data.have_printer",p:[9,1,566]},{t:4,f:[{p:[14,1,766],t:7,e:"div",a:{"class":"item"},f:[{p:[15,3,788],t:7,e:"h2",f:["Crew Manifest"]}," ",{p:[16,3,814],t:7,e:"br"},"Please use security record computer to modify entries.",{p:[16,61,872],t:7,e:"br"},{p:[16,65,876],t:7,e:"br"}]}," ",{t:4,f:[{p:[19,2,916],t:7,e:"div",a:{"class":"item"},f:[{t:2,r:"name",p:[20,2,937]}," - ",{t:2,r:"rank",p:[20,13,948]}]}],n:52,r:"data.manifest",p:[18,1,890]}],n:50,x:{r:["data.mmode"],s:"!_0"},p:[13,1,745]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.mmode"],s:"_0==2"},f:[{p:[25,1,1008],t:7,e:"div",a:{"class":"item"},f:[{p:[26,3,1030],t:7,e:"h2",f:["Job Management"]}]}," ",{p:[28,1,1063],t:7,e:"table",f:[{p:[29,1,1072],t:7,e:"tr",f:[{p:[29,5,1076],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,27,1098],t:7,e:"b",f:["Job"]}]},{p:[29,42,1113],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,64,1135],t:7,e:"b",f:["Slots"]}]},{p:[29,81,1152],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,103,1174],t:7,e:"b",f:["Open job"]}]},{p:[29,123,1194],t:7,e:"td",a:{style:"width:25%"},f:[{p:[29,145,1216],t:7,e:"b",f:["Close job"]}]}]}," ",{t:4,f:[{p:[32,2,1269],t:7,e:"tr",f:[{p:[32,6,1273],t:7,e:"td",f:[{t:2,r:"title",p:[32,10,1277]}]},{p:[32,24,1291],t:7,e:"td",f:[{t:2,r:"current",p:[32,28,1295]},"/",{t:2,r:"total",p:[32,40,1307]}]},{p:[32,54,1321],t:7,e:"td",f:[{p:[32,58,1325],t:7,e:"ui-button",a:{action:"PRG_open_job",params:['{"target" : "',{t:2,r:"title",p:[32,112,1379]},'"}'],state:[{t:2,x:{r:["status_open"],s:'_0?null:"disabled"'},p:[32,132,1399]}]},f:[{t:2,r:"desc_open",p:[32,169,1436]}]},{p:[32,194,1461],t:7,e:"br"}]},{p:[32,203,1470],t:7,e:"td",f:[{p:[32,207,1474],t:7,e:"ui-button",a:{action:"PRG_close_job",params:['{"target" : "',{t:2,r:"title",p:[32,262,1529]},'"}'],state:[{t:2,x:{r:["status_close"],s:'_0?null:"disabled"'},p:[32,282,1549]}]},f:[{t:2,r:"desc_close",p:[32,320,1587]}]}]}]}],n:52,r:"data.slots",p:[30,1,1244]}]}]},{t:4,n:50,x:{r:["data.mmode"],s:"!(_0==2)"},f:[" ",{p:[40,1,1665],t:7,e:"div",a:{"class":"item"},f:[{p:[41,3,1687],t:7,e:"h2",f:["Access Modification"]}]}," ",{t:4,f:[{p:[45,3,1751],t:7,e:"span",a:{"class":"alert"},f:[{p:[45,23,1771],t:7,e:"i",f:["Please insert the ID into the terminal to proceed."]}]},{p:[45,87,1835],t:7,e:"br"}],n:50,x:{r:["data.has_id"],s:"!_0"},p:[44,1,1727]},{p:[48,1,1852],t:7,e:"div",a:{"class":"item"},f:[{p:[49,3,1874],t:7,e:"div",a:{"class":"itemLabel"},f:["Target Identity:"]}," ",{p:[52,3,1930],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[53,2,1958],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "id"}'},f:[{t:2,r:"data.id_name",p:[53,72,2028]}]}]}]}," ",{p:[56,1,2076],t:7,e:"div",a:{"class":"item"},f:[{p:[57,3,2098],t:7,e:"div",a:{"class":"itemLabel"},f:["Auth Identity:"]}," ",{p:[60,3,2152],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[61,2,2180],t:7,e:"ui-button",a:{icon:"eject",action:"PRG_eject",params:'{"target" : "auth"}'},f:[{t:2,r:"data.auth_name",p:[61,74,2252]}]}]}]}," ",{p:[64,1,2302],t:7,e:"hr"}," ",{t:4,f:[{t:4,f:[{p:[68,2,2362],t:7,e:"div",a:{"class":"item"},f:[{p:[69,4,2385],t:7,e:"h2",f:["Details"]}]}," ",{t:4,f:[{p:[73,2,2436],t:7,e:"div",a:{"class":"item"},f:[{p:[74,4,2459],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[77,4,2518],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_owner",p:[78,3,2547]}]}]}," ",{p:[81,2,2587],t:7,e:"div",a:{"class":"item"},f:[{p:[82,4,2610],t:7,e:"div",a:{"class":"itemLabel"},f:["Rank:"]}," ",{p:[85,4,2658],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.id_rank",p:[86,3,2687]}]}]}," ",{p:[89,2,2726],t:7,e:"div",a:{"class":"item"},f:[{p:[90,4,2749],t:7,e:"div",a:{"class":"itemLabel"},f:["Demote:"]}," ",{p:[93,4,2799],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[94,3,2828],t:7,e:"ui-button",a:{action:"PRG_terminate",icon:"gear",state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Unassigned"?"disabled":null'},p:[94,56,2881]}]},f:["Demote ",{t:2,r:"data.id_owner",p:[94,117,2942]}]}]}]}],n:50,r:"data.minor",p:[72,2,2415]},{t:4,n:51,f:[{p:[99,2,3007],t:7,e:"div",a:{"class":"item"},f:[{p:[100,4,3030],t:7,e:"div",a:{"class":"itemLabel"},f:["Registered Name:"]}," ",{p:[103,4,3089],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[104,3,3118],t:7,e:"ui-button",a:{action:"PRG_edit",icon:"pencil",params:'{"name" : "1"}'},f:[{t:2,r:"data.id_owner",p:[104,70,3185]}]}]}]}," ",{p:[108,2,3239],t:7,e:"div",a:{"class":"item"},f:[{p:[109,4,3262],t:7,e:"h2",f:["Assignment"]}]}," ",{p:[111,3,3294],t:7,e:"ui-button",a:{action:"PRG_togglea",icon:"gear"},f:[{t:2,x:{r:["data.assignments"],s:'_0?"Hide assignments":"Show assignments"'},p:[111,47,3338]}]}," ",{p:[112,2,3415],t:7,e:"div",a:{"class":"item"},f:[{p:[113,4,3438],t:7,e:"span",a:{id:"allvalue.jobsslot"},f:[]}]}," ",{p:[117,2,3495],t:7,e:"div",a:{"class":"item"},f:[{t:4,f:[{p:[119,4,3547],t:7,e:"div",a:{id:"all-value.jobs"},f:[{p:[120,3,3576],t:7,e:"table",f:[{p:[121,5,3589],t:7,e:"tr",f:[{p:[122,4,3598],t:7,e:"th",f:["Command"]}," ",{p:[123,4,3619],t:7,e:"td",f:[{p:[124,6,3630],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Captain"}',state:[{t:2,x:{r:["data.id_rank"],s:'_0=="Captain"?"selected":null'},p:[124,83,3707]}]},f:["Captain"]}]}]}," ",{p:[127,5,3804],t:7,e:"tr",f:[{p:[128,4,3813],t:7,e:"th",f:["Special"]}," ",{p:[129,4,3834],t:7,e:"td",f:[{p:[130,6,3845],t:7,e:"ui-button",a:{action:"PRG_assign",params:'{"assign_target" : "Custom"}'},f:["Custom"]}]}]}," ",{p:[133,5,3959],t:7,e:"tr",f:[{p:[134,4,3968],t:7,e:"th",a:{style:"color: '#FFA500';"},f:["Engineering"]}," ",{p:[135,4,4019],t:7,e:"td",f:[{t:4,f:[{p:[137,5,4067],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[137,64,4126]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[137,82,4144]}]},f:[{t:2,r:"display_name",p:[137,127,4189]}]}],n:52,r:"data.engineering_jobs",p:[136,6,4030]}]}]}," ",{p:[141,5,4260],t:7,e:"tr",f:[{p:[142,4,4269],t:7,e:"th",a:{style:"color: '#008000';"},f:["Medical"]}," ",{p:[143,4,4316],t:7,e:"td",f:[{t:4,f:[{p:[145,5,4360],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[145,64,4419]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[145,82,4437]}]},f:[{t:2,r:"display_name",p:[145,127,4482]}]}],n:52,r:"data.medical_jobs",p:[144,6,4327]}]}]}," ",{p:[149,5,4553],t:7,e:"tr",f:[{p:[150,4,4562],t:7,e:"th",a:{style:"color: '#800080';"},f:["Science"]}," ",{p:[151,4,4609],t:7,e:"td",f:[{t:4,f:[{p:[153,5,4653],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[153,64,4712]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[153,82,4730]}]},f:[{t:2,r:"display_name",p:[153,127,4775]}]}],n:52,r:"data.science_jobs",p:[152,6,4620]}]}]}," ",{p:[157,5,4846],t:7,e:"tr",f:[{p:[158,4,4855],t:7,e:"th",a:{style:"color: '#DD0000';"},f:["Security"]}," ",{p:[159,4,4903],t:7,e:"td",f:[{t:4,f:[{p:[161,5,4948],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[161,64,5007]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[161,82,5025]}]},f:[{t:2,r:"display_name",p:[161,127,5070]}]}],n:52,r:"data.security_jobs",p:[160,6,4914]}]}]}," ",{p:[165,5,5141],t:7,e:"tr",f:[{p:[166,4,5150],t:7,e:"th",a:{style:"color: '#cc6600';"},f:["Cargo"]}," ",{p:[167,4,5195],t:7,e:"td",f:[{t:4,f:[{p:[169,5,5237],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[169,64,5296]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[169,82,5314]}]},f:[{t:2,r:"display_name",p:[169,127,5359]}]}],n:52,r:"data.cargo_jobs",p:[168,6,5206]}]}]}," ",{p:[173,5,5430],t:7,e:"tr",f:[{p:[174,4,5439],t:7,e:"th",a:{style:"color: '#808080';"},f:["Civilian"]}," ",{p:[175,4,5487],t:7,e:"td",f:[{t:4,f:[{p:[177,5,5532],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[177,64,5591]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[177,82,5609]}]},f:[{t:2,r:"display_name",p:[177,127,5654]}]}],n:52,r:"data.civilian_jobs",p:[176,6,5498]}]}]}," ",{t:4,f:[{p:[182,4,5757],t:7,e:"tr",f:[{p:[183,6,5768],t:7,e:"th",a:{style:"color: '#A52A2A';"},f:["CentCom"]}," ",{p:[184,6,5817],t:7,e:"td",f:[{t:4,f:[{p:[186,7,5862],t:7,e:"ui-button",a:{action:"PRG_assign",params:['{"assign_target" : "',{t:2,r:"job",p:[186,66,5921]},'"}'],state:[{t:2,x:{r:["data.id_rank","job"],s:'_0==_1?"selected":null'},p:[186,84,5939]}]},f:[{t:2,r:"display_name",p:[186,129,5984]}]}],n:52,r:"data.centcom_jobs",p:[185,5,5827]}]}]}],n:50,r:"data.centcom_access",p:[181,5,5725]}]}]}],n:50,r:"data.assignments",p:[118,4,3518]}]}],r:"data.minor"}," ",{t:4,f:[{p:[198,4,6153],t:7,e:"div",a:{"class":"item"},f:[{p:[199,3,6175],t:7,e:"h2",f:["Central Command"]}]}," ",{p:[201,4,6215],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[203,5,6296],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[204,5,6331],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[204,64,6390]},'", "allowed" : "',{t:2,r:"allowed",p:[204,87,6413]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[204,109,6435]}]},f:[{t:2,r:"desc",p:[204,140,6466]}]}]}],n:52,r:"data.all_centcom_access",p:[202,3,6257]}]}],n:50,r:"data.centcom_access",p:[197,2,6121]},{t:4,n:51,f:[{p:[209,4,6538],t:7,e:"div",a:{"class":"item"},f:[{p:[210,3,6560],t:7,e:"h2",f:[{t:2,r:"data.station_name",p:[210,7,6564]}]}]}," ",{p:[212,4,6606],t:7,e:"div",a:{"class":"item",style:"width: 100%"},f:[{t:4,f:[{p:[214,5,6676],t:7,e:"div",a:{style:"float: left; width: 175px; min-height: 250px"},f:[{p:[215,4,6739],t:7,e:"div",a:{"class":"average"},f:[{p:[215,25,6760],t:7,e:"ui-button",a:{action:"PRG_regsel",state:[{t:2,x:{r:["selected"],s:'_0?"toggle":null'},p:[215,63,6798]}],params:['{"region" : "',{t:2,r:"regid",p:[215,116,6851]},'"}']},f:[{p:[215,129,6864],t:7,e:"b",f:[{t:2,r:"name",p:[215,132,6867]}]}]}]}," ",{p:[216,4,6902],t:7,e:"br"}," ",{t:4,f:[{p:[218,6,6938],t:7,e:"div",a:{"class":"itemContentWide"},f:[{p:[219,5,6973],t:7,e:"ui-button",a:{action:"PRG_access",params:['{"access_target" : "',{t:2,r:"ref",p:[219,64,7032]},'", "allowed" : "',{t:2,r:"allowed",p:[219,87,7055]},'"}'],state:[{t:2,x:{r:["allowed"],s:'_0?"toggle":null'},p:[219,109,7077]}]},f:[{t:2,r:"desc",p:[219,140,7108]}]}]}],n:52,r:"accesses",p:[217,6,6913]}]}],n:52,r:"data.regions",p:[213,3,6648]}]}],r:"data.centcom_access"}],n:50,r:"data.has_id",p:[67,3,2340]}],n:50,r:"data.authenticated",p:[66,1,2310]}]}],x:{r:["data.mmode"],s:"!_0"}}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],419:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargeState:function(t){var e=this.get("data.battery.max");return t>e/2?"good":t>e/4?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[15,1,311],t:7,e:"ntosheader"}," ",{p:[17,1,328],t:7,e:"ui-display",f:[{p:[18,2,343],t:7,e:"i",f:["Welcome to computer configuration utility. Please consult your system administrator if you have any questions about your device."]},{p:[18,137,478],t:7,e:"hr"}," ",{p:[19,2,485],t:7,e:"ui-display",a:{title:"Power Supply"},f:[{p:[20,3,522],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"data.power_usage",p:[21,4,559]},"W"]}," ",{t:4,f:[{p:[25,4,630],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Active"]}," ",{p:[28,4,701],t:7,e:"ui-section",a:{label:"Battery Rating"},f:[{t:2,r:"data.battery.max",p:[29,5,742]}]}," ",{p:[31,4,785],t:7,e:"ui-section",a:{label:"Battery Charge"},f:[{p:[32,5,826],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.battery.max",p:[32,26,847]}],value:[{t:2,r:"adata.battery.charge",p:[32,56,877]}],state:[{t:2,x:{r:["chargeState","adata.battery.charge"],s:"_0(_1)"},p:[32,89,910]}]},f:[{t:2,x:{r:["adata.battery.charge"],s:"Math.round(_0)"},p:[32,128,949]},"/",{t:2,r:"adata.battery.max",p:[32,165,986]}]}]}],n:50,r:"data.battery",p:[24,3,605]},{t:4,n:51,f:[{p:[35,4,1051],t:7,e:"ui-section",a:{label:"Battery Status"},f:["Not Available"]}],r:"data.battery"}]}," ",{p:[41,2,1156],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,3,1192],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,4,1231],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,25,1252]}],value:[{t:2,r:"adata.disk_used",p:[43,53,1280]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,87,1314]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,123,1350]},"GQ"]}]}]}," ",{p:[47,2,1419],t:7,e:"ui-display",a:{title:"Computer Components"},f:[{t:4,f:[{p:[49,4,1491],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[49,26,1513]}]},f:[{p:[50,5,1529],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"desc",p:[50,59,1583]}]}," ",{p:[52,5,1605],t:7,e:"ui-section",a:{label:"State"},f:[{p:[53,6,1638],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["critical"],s:'_0?"disabled":null'},p:[53,24,1656]}],action:"PC_toggle_component",params:['{"name": "',{t:2,r:"name",p:[53,105,1737]},'"}']},f:[{t:2,x:{r:["enabled"],s:'_0?"Enabled":"Disabled"'},p:[54,7,1757]}]}]}," ",{t:4,f:[{p:[59,6,1868],t:7,e:"ui-section",a:{label:"Power Usage"},f:[{t:2,r:"powerusage",p:[60,7,1908]},"W"]}],n:50,r:"powerusage",p:[58,5,1843]}]}," ",{p:[64,4,1985],t:7,e:"br"}],n:52,r:"data.hardware",p:[48,3,1463]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],420:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,3,103],t:7,e:"h2",f:["An error has occurred and this program can not continue."]}," Additional information: ",{t:2,r:"data.error",p:[8,27,196]},{p:[8,41,210],t:7,e:"br"}," ",{p:[9,3,218],t:7,e:"i",f:["Please try again. If the problem persists contact your system administrator for assistance."]}," ",{p:[10,3,320],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["Restart program"]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,f:[{p:[13,4,422],t:7,e:"h2",f:["Viewing file ",{t:2,r:"data.filename",p:[13,21,439]}]}," ",{p:[14,4,466],t:7,e:"div",a:{"class":"item"},f:[{p:[15,4,489],t:7,e:"ui-button",a:{action:"PRG_closefile"},f:["CLOSE"]}," ",{p:[16,4,545],t:7,e:"ui-button",a:{action:"PRG_edit"},f:["EDIT"]}," ",{p:[17,4,595],t:7,e:"ui-button",a:{action:"PRG_printfile"},f:["PRINT"]}," "]},{p:[18,10,657],t:7,e:"hr"}," ",{t:3,r:"data.filedata",p:[19,4,666]}],n:50,r:"data.filename",p:[12,3,396]},{t:4,n:51,f:[{p:[21,4,702],t:7,e:"h2",f:["Available files (local):"]}," ",{p:[22,4,740],t:7,e:"table",f:[{p:[23,5,753],t:7,e:"tr",f:[{p:[24,6,764],t:7,e:"th",f:["File name"]}," ",{p:[25,6,789],t:7,e:"th",f:["File type"]}," ",{p:[26,6,814],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[27,6,844],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[30,6,907],t:7,e:"tr",f:[{p:[31,7,919],t:7,e:"td",f:[{t:2,r:"name",p:[31,11,923]}]}," ",{p:[32,7,944],t:7,e:"td",f:[".",{t:2,r:"type",p:[32,12,949]}]}," ",{p:[33,7,970],t:7,e:"td",f:[{t:2,r:"size",p:[33,11,974]},"GQ"]}," ",{p:[34,7,997],t:7,e:"td",f:[{p:[35,8,1010],t:7,e:"ui-button",a:{action:"PRG_openfile",params:['{"name": "',{t:2,r:"name",p:[35,59,1061]},'"}']},f:["VIEW"]}," ",{p:[36,8,1098],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[36,26,1116]}],action:"PRG_deletefile",params:['{"name": "',{t:2,r:"name",p:[36,105,1195]},'"}']},f:["DELETE"]}," ",{p:[37,8,1234],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[37,26,1252]}],action:"PRG_rename",params:['{"name": "',{t:2,r:"name",p:[37,101,1327]},'"}']},f:["RENAME"]}," ",{p:[38,8,1366],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[38,26,1384]}],action:"PRG_clone",params:['{"name": "',{t:2,r:"name",p:[38,100,1458]},'"}']},f:["CLONE"]}," ",{t:4,f:[{p:[40,9,1531],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[40,27,1549]}],action:"PRG_copytousb",params:['{"name": "',{t:2,r:"name",p:[40,105,1627]},'"}']},f:["EXPORT"]}],n:50,r:"data.usbconnected",p:[39,8,1496]}]}]}],n:52,r:"data.files",p:[29,5,880]}]}," ",{t:4,f:[{p:[47,4,1761],t:7,e:"h2",f:["Available files (portable device):"]}," ",{p:[48,4,1809],t:7,e:"table",f:[{p:[49,5,1822],t:7,e:"tr",f:[{p:[50,6,1833],t:7,e:"th",f:["File name"]}," ",{p:[51,6,1858],t:7,e:"th",f:["File type"]}," ",{p:[52,6,1883],t:7,e:"th",f:["File size (GQ)"]}," ",{p:[53,6,1913],t:7,e:"th",f:["Operations"]}]}," ",{t:4,f:[{p:[56,6,1979],t:7,e:"tr",f:[{p:[57,7,1991],t:7,e:"td",f:[{t:2,r:"name",p:[57,11,1995]}]}," ",{p:[58,7,2016],t:7,e:"td",f:[".",{t:2,r:"type",p:[58,12,2021]}]}," ",{p:[59,7,2042],t:7,e:"td",f:[{t:2,r:"size",p:[59,11,2046]},"GQ"]}," ",{p:[60,7,2069],t:7,e:"td",f:[{p:[61,8,2082],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[61,26,2100]}],action:"PRG_usbdeletefile",params:['{"name": "',{t:2,r:"name",p:[61,108,2182]},'"}']},f:["DELETE"]}," ",{t:4,f:[{p:[63,9,2256],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["undeletable"],s:'_0?"disabled":null'},p:[63,27,2274]}],action:"PRG_copyfromusb",params:['{"name": "',{t:2,r:"name",p:[63,107,2354]},'"}']},f:["IMPORT"]}],n:50,r:"data.usbconnected",p:[62,8,2221]}]}]}],n:52,r:"data.usbfiles",p:[55,5,1949]}]}],n:50,r:"data.usbconnected",p:[46,4,1731]}," ",{p:[70,4,2470],t:7,e:"ui-button",a:{action:"PRG_newtextfile"},f:["NEW DATA FILE"]}],r:"data.filename"}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],421:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["No program loaded. Please select program from list below."]}," ",{p:[6,2,146],t:7,e:"table",f:[{t:4,f:[{p:[8,4,185],t:7,e:"tr",f:[{p:[8,8,189],t:7,e:"td",f:[{p:[8,12,193],t:7,e:"ui-button",a:{action:"PC_runprogram",params:['{"name": "',{t:2,r:"name",p:[8,64,245]},'"}']},f:[{t:2,r:"desc",p:[9,5,263]}]}]},{p:[11,4,293],t:7,e:"td",f:[{p:[11,8,297],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["running"],s:'_0?null:"disabled"'},p:[11,26,315]}],icon:"close",action:"PC_killprogram",params:['{"name": "',{t:2,r:"name",p:[11,114,403]},'"}']}}]}]}],n:52,r:"data.programs",p:[7,3,157]}]}," ",{p:[14,2,454],t:7,e:"br"},{p:[14,6,458],t:7,e:"br"}," ",{t:4,f:[{p:[16,3,491],t:7,e:"ui-button",a:{action:"PC_toggle_light",style:[{t:2,x:{r:["data.light_on"],s:'_0?"selected":null'},p:[16,46,534]}]},f:["Toggle Flashlight"]},{p:[16,114,602],t:7,e:"br"}," ",{p:[17,3,610],t:7,e:"ui-button",a:{action:"PC_light_color"},f:["Change Flashlight Color ",{p:[17,62,669],t:7,e:"span",a:{style:["border:1px solid #161616; background-color: ",{t:2,r:"data.comp_light_color",p:[17,119,726]},";"]},f:[" "]}]}],n:50,r:"data.has_light",p:[15,2,465]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],422:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[6,3,105],t:7,e:"h1",f:["ADMINISTRATIVE MODE"]}],n:50,r:"data.adminmode",p:[5,2,79]}," ",{t:4,f:[{p:[10,3,170],t:7,e:"div",a:{"class":"itemLabel"},f:["Current channel:"]}," ",{p:[13,3,229],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.title",p:[14,4,259]}]}," ",{p:[16,3,287],t:7,e:"div",a:{"class":"itemLabel"},f:["Operator access:"]}," ",{p:[19,3,346],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:[{p:[21,5,406],t:7,e:"b",f:["Enabled"]}],n:50,r:"data.is_operator",p:[20,4,376]},{t:4,n:51,f:[{p:[23,5,439],t:7,e:"b",f:["Disabled"]}],r:"data.is_operator"}]}," ",{p:[26,3,480],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[29,3,532],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[30,4,562],t:7,e:"table",f:[{p:[31,5,575],t:7,e:"tr",f:[{p:[31,9,579],t:7,e:"td",f:[{p:[31,13,583],t:7,e:"ui-button",a:{action:"PRG_speak"},f:["Send message"]}]}]},{p:[32,5,643],t:7,e:"tr",f:[{p:[32,9,647],t:7,e:"td",f:[{p:[32,13,651],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[33,5,719],t:7,e:"tr",f:[{p:[33,9,723],t:7,e:"td",f:[{p:[33,13,727],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]},{p:[34,5,807],t:7,e:"tr",f:[{p:[34,9,811],t:7,e:"td",f:[{p:[34,13,815],t:7,e:"ui-button",a:{action:"PRG_leavechannel"},f:["Leave channel"]}]}]},{p:[35,5,883],t:7,e:"tr",f:[{p:[35,9,887],t:7,e:"td",f:[{p:[35,13,891],t:7,e:"ui-button",a:{action:"PRG_savelog"},f:["Save log to local drive"]}," ",{t:4,f:[{p:[37,6,995],t:7,e:"tr",f:[{p:[37,10,999],t:7,e:"td",f:[{p:[37,14,1003],t:7,e:"ui-button",a:{action:"PRG_renamechannel"},f:["Rename channel"]}]}]},{p:[38,6,1074],t:7,e:"tr",f:[{p:[38,10,1078],t:7,e:"td",f:[{p:[38,14,1082],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}]}]},{p:[39,6,1149],t:7,e:"tr",f:[{p:[39,10,1153],t:7,e:"td",f:[{p:[39,14,1157],t:7,e:"ui-button",a:{action:"PRG_deletechannel"},f:["Delete channel"]}]}]}],n:50,r:"data.is_operator",p:[36,5,964]}]}]}]}]}," ",{p:[43,3,1263],t:7,e:"b",f:["Chat Window"]}," ",{p:[44,4,1286],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[45,4,1342],t:7,e:"div",a:{"class":"item"},f:[{p:[46,5,1366],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"msg",p:[48,7,1450]},{p:[48,14,1457],t:7,e:"br"}],n:52,r:"data.messages",p:[47,6,1419]}]}]}]}," ",{p:[53,3,1516],t:7,e:"b",f:["Connected Users"]},{p:[53,25,1538],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"name",p:[55,4,1573]},{p:[55,12,1581],t:7,e:"br"}],n:52,r:"data.clients",p:[54,3,1546]}],n:50,r:"data.title",p:[9,2,148]},{t:4,n:51,f:[{p:[58,3,1613],t:7,e:"b",f:["Controls:"]}," ",{p:[59,3,1633],t:7,e:"table",f:[{p:[60,4,1645],t:7,e:"tr",f:[{p:[60,8,1649],t:7,e:"td",f:[{p:[60,12,1653],t:7,e:"ui-button",a:{action:"PRG_changename"},f:["Change nickname"]}]}]},{p:[61,4,1720],t:7,e:"tr",f:[{p:[61,8,1724],t:7,e:"td",f:[{p:[61,12,1728],t:7,e:"ui-button",a:{action:"PRG_newchannel"},f:["New Channel"]}]}]},{p:[62,4,1791],t:7,e:"tr",f:[{p:[62,8,1795],t:7,e:"td",f:[{p:[62,12,1799],t:7,e:"ui-button",a:{action:"PRG_toggleadmin"},f:["Toggle administration mode"]}]}]}]}," ",{p:[64,3,1889],t:7,e:"b",f:["Available channels:"]}," ",{p:[65,3,1919],t:7,e:"table",f:[{t:4,f:[{p:[67,4,1964],t:7,e:"tr",f:[{p:[67,8,1968],t:7,e:"td",f:[{p:[67,12,1972],t:7,e:"ui-button",a:{action:"PRG_joinchannel",params:['{"id": "',{t:2,r:"id",p:[67,64,2024]},'"}']},f:[{t:2,r:"chan",p:[67,74,2034]}]},{p:[67,94,2054],t:7,e:"br"}]}]}],n:52,r:"data.all_channels",p:[66,3,1930]}]}],r:"data.title"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],423:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:["##SYSTEM ERROR: ",{t:2,r:"data.error",p:[6,19,117]},{p:[6,33,131],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["RESET"]}],n:50,r:"data.error",p:[5,2,79]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.target"],s:"_0"},f:["##DoS traffic generator active. Tx: ",{t:2,r:"data.speed",p:[8,39,243]},"GQ/s",{p:[8,57,261],t:7,e:"br"}," ",{t:4,f:[{t:2,r:"nums",p:[10,4,300]},{p:[10,12,308],t:7,e:"br"}],n:52,r:"data.dos_strings",p:[9,3,269]}," ",{p:[12,3,329],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["ABORT"]}]},{t:4,n:50,x:{r:["data.target"],s:"!(_0)"},f:[" ##DoS traffic generator ready. Select target device.",{p:[14,55,443],t:7,e:"br"}," ",{t:4,f:["Targeted device ID: ",{t:2,r:"data.focus",p:[16,24,494]}],n:50,r:"data.focus",p:[15,3,451]},{t:4,n:51,f:["Targeted device ID: None"],r:"data.focus"}," ",{p:[20,3,564],t:7,e:"ui-button",a:{action:"PRG_execute"},f:["EXECUTE"]},{p:[20,54,615],t:7,e:"div",a:{style:"clear:both"}}," Detected devices on network:",{p:[21,31,677],t:7,e:"br"}," ",{t:4,f:[{p:[23,4,711],t:7,e:"ui-button",a:{action:"PRG_target_relay",params:['{"targid": "',{t:2,r:"id",p:[23,61,768]},'"}']},f:[{t:2,r:"id",p:[23,71,778]}]}],n:52,r:"data.relays",p:[22,3,685]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],424:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"i",f:["Welcome to software download utility. Please select which software you wish to download."]},{p:[5,97,174],t:7,e:"hr"}," ",{t:4,f:[{p:[7,3,203],t:7,e:"ui-display",a:{title:"Download Error"},f:[{p:[8,4,243],t:7,e:"ui-section",a:{label:"Information"},f:[{t:2,r:"data.error",p:[9,5,281]}]}," ",{p:[11,4,318],t:7,e:"ui-section",a:{label:"Reset Program"},f:[{p:[12,5,358],t:7,e:"ui-button",a:{icon:"times",action:"PRG_reseterror"},f:["RESET"]}]}]}],n:50,r:"data.error",p:[6,2,181]},{t:4,n:51,f:[{t:4,f:[{p:[19,4,516],t:7,e:"ui-display",a:{title:"Download Running"},f:[{p:[20,5,559],t:7,e:"i",f:["Please wait..."]}," ",{p:[21,5,586],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"data.downloadname",p:[22,6,623]}]}," ",{p:[24,5,669],t:7,e:"ui-section",a:{label:"File description"},f:[{t:2,r:"data.downloaddesc",p:[25,6,713]}]}," ",{p:[27,5,759],t:7,e:"ui-section",a:{label:"File size"},f:[{t:2,r:"data.downloadsize",p:[28,6,796]},"GQ"]}," ",{p:[30,5,844],t:7,e:"ui-section",a:{label:"Transfer Rate"},f:[{t:2,r:"data.downloadspeed",p:[31,6,885]}," GQ/s"]}," ",{p:[33,5,937],t:7,e:"ui-section",a:{label:"Download progress"},f:[{p:[34,6,982],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.downloadsize",p:[34,27,1003]}],value:[{t:2,r:"adata.downloadcompletion",p:[34,58,1034]}],state:"good"},f:[{t:2,x:{r:["adata.downloadcompletion"],s:"Math.round(_0)"},p:[34,101,1077]},"GQ / ",{t:2,r:"adata.downloadsize",p:[34,146,1122]},"GQ"]}]}]}],n:50,r:"data.downloadname",p:[18,3,486]}],r:"data.error"}," ",{t:4,f:[{t:4,f:[{p:[41,4,1270],t:7,e:"ui-display",a:{title:"File System"},f:[{p:[42,5,1308],t:7,e:"ui-section",a:{label:"Used Capacity"},f:[{p:[43,6,1349],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.disk_size",p:[43,27,1370]}],value:[{t:2,r:"adata.disk_used",p:[43,55,1398]}],state:"good"},f:[{t:2,x:{r:["adata.disk_used"],s:"Math.round(_0)"},p:[43,89,1432]},"GQ / ",{t:2,r:"adata.disk_size",p:[43,125,1468]},"GQ"]}]}]}," ",{p:[47,4,1545],t:7,e:"ui-display",a:{title:"Primary Software Repository"},f:[{t:4,f:[{p:[49,6,1642],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[49,28,1664]}]},f:[{p:[50,7,1686],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[50,61,1740]}]}," ",{p:[52,7,1774],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[53,8,1813]}," (",{t:2,r:"size",p:[53,22,1827]}," GQ)"]}," ",{p:[55,7,1868],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[56,8,1911]}]}," ",{p:[58,7,1957],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",p:[58,80,2030]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[62,6,2113],t:7,e:"br"}],n:52,r:"data.downloadable_programs",p:[48,5,1599]}]}," ",{t:4,f:[{p:[67,5,2194],t:7,e:"ui-display",a:{title:"UNKNOWN Software Repository"},f:[{p:[68,6,2249],t:7,e:"i",f:["Please note that Nanotrasen does not recommend download of software from non-official servers."]}," ",{t:4,f:[{p:[70,7,2395],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"filedesc",p:[70,29,2417]}]},f:[{p:[71,8,2440],t:7,e:"div",a:{style:"display: table-caption; margin-left: 3px"},f:[{t:2,r:"fileinfo",p:[71,62,2494]}]}," ",{p:[73,8,2530],t:7,e:"ui-section",a:{label:"File name"},f:[{t:2,r:"filename",p:[74,9,2570]}," (",{t:2,r:"size",p:[74,23,2584]}," GQ)"]}," ",{p:[76,8,2627],t:7,e:"ui-section",a:{label:"Compatibility"},f:[{t:2,r:"compatibility",p:[77,9,2671]}]}," ",{p:[79,8,2719],t:7,e:"ui-button",a:{icon:"signal",action:"PRG_downloadfile",params:['{"filename": "',{t:2,r:"filename",
+p:[79,81,2792]},'"}']},f:["DOWNLOAD"]}]}," ",{p:[83,7,2879],t:7,e:"br"}],n:52,r:"data.hacked_programs",p:[69,6,2357]}]}],n:50,r:"data.hackedavailable",p:[66,4,2160]}],n:50,x:{r:["data.error"],s:"!_0"},p:[40,3,1246]}],n:50,x:{r:["data.downloadname"],s:"!_0"},p:[39,2,1216]}," ",{p:[89,2,2954],t:7,e:"br"},{p:[89,6,2958],t:7,e:"br"},{p:[89,10,2962],t:7,e:"hr"},{p:[89,14,2966],t:7,e:"i",f:["NTOS v2.0.4b Copyright Nanotrasen 2557 - 2559"]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],425:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[6,2,81],t:7,e:"ui-display",a:{title:"WIRELESS CONNECTIVITY"},f:[{p:[8,3,129],t:7,e:"ui-section",a:{label:"Active NTNetRelays"},f:[{p:[9,4,173],t:7,e:"b",f:[{t:2,r:"data.ntnetrelays",p:[9,7,176]}]}]}," ",{t:4,f:[{p:[12,4,250],t:7,e:"ui-section",a:{label:"System status"},f:[{p:[13,6,291],t:7,e:"b",f:[{t:2,x:{r:["data.ntnetstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[13,9,294]}]}]}," ",{p:[15,4,366],t:7,e:"ui-section",a:{label:"Control"},f:[{p:[17,4,401],t:7,e:"ui-button",a:{icon:"plus",action:"toggleWireless"},f:["TOGGLE"]}]}," ",{p:[21,4,500],t:7,e:"br"},{p:[21,8,504],t:7,e:"br"}," ",{p:[22,4,513],t:7,e:"i",f:["Caution - Disabling wireless transmitters when using wireless device may prevent you from re-enabling them again!"]}],n:50,r:"data.ntnetrelays",p:[11,3,221]},{t:4,n:51,f:[{p:[24,4,650],t:7,e:"br"},{p:[24,8,654],t:7,e:"p",f:["Wireless coverage unavailable, no relays are connected."]}],r:"data.ntnetrelays"}]}," ",{p:[29,2,750],t:7,e:"ui-display",a:{title:"FIREWALL CONFIGURATION"},f:[{p:[31,2,798],t:7,e:"table",f:[{p:[32,3,809],t:7,e:"tr",f:[{p:[33,4,818],t:7,e:"th",f:["PROTOCOL"]},{p:[34,4,835],t:7,e:"th",f:["STATUS"]},{p:[35,4,850],t:7,e:"th",f:["CONTROL"]}]},{p:[36,3,865],t:7,e:"tr",f:[" ",{p:[37,4,874],t:7,e:"td",f:["Software Downloads"]},{p:[38,4,901],t:7,e:"td",f:[{t:2,x:{r:["data.config_softwaredownload"],s:'_0?"ENABLED":"DISABLED"'},p:[38,8,905]}]},{p:[39,4,967],t:7,e:"td",f:[" ",{p:[39,9,972],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "1"}'},f:["TOGGLE"]}]}]},{p:[40,3,1051],t:7,e:"tr",f:[" ",{p:[41,4,1060],t:7,e:"td",f:["Peer to Peer Traffic"]},{p:[42,4,1089],t:7,e:"td",f:[{t:2,x:{r:["data.config_peertopeer"],s:'_0?"ENABLED":"DISABLED"'},p:[42,8,1093]}]},{p:[43,4,1149],t:7,e:"td",f:[{p:[43,8,1153],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "2"}'},f:["TOGGLE"]}]}]},{p:[44,3,1232],t:7,e:"tr",f:[" ",{p:[45,4,1241],t:7,e:"td",f:["Communication Systems"]},{p:[46,4,1271],t:7,e:"td",f:[{t:2,x:{r:["data.config_communication"],s:'_0?"ENABLED":"DISABLED"'},p:[46,8,1275]}]},{p:[47,4,1334],t:7,e:"td",f:[{p:[47,8,1338],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "3"}'},f:["TOGGLE"]}]}]},{p:[48,3,1417],t:7,e:"tr",f:[" ",{p:[49,4,1426],t:7,e:"td",f:["Remote System Control"]},{p:[50,4,1456],t:7,e:"td",f:[{t:2,x:{r:["data.config_systemcontrol"],s:'_0?"ENABLED":"DISABLED"'},p:[50,8,1460]}]},{p:[51,4,1519],t:7,e:"td",f:[{p:[51,8,1523],t:7,e:"ui-button",a:{action:"toggle_function",params:'{"id": "4"}'},f:["TOGGLE"]}]}]}]}]}," ",{p:[55,2,1630],t:7,e:"ui-display",a:{title:"SECURITY SYSTEMS"},f:[{t:4,f:[{p:[58,4,1699],t:7,e:"ui-notice",f:[{p:[59,5,1716],t:7,e:"h1",f:["NETWORK INCURSION DETECTED"]}]}," ",{p:[61,5,1774],t:7,e:"i",f:["An abnormal activity has been detected in the network. Please verify system logs for more information"]}],n:50,r:"data.idsalarm",p:[57,3,1673]}," ",{p:[64,3,1902],t:7,e:"ui-section",a:{label:"Intrusion Detection System"},f:[{p:[65,4,1954],t:7,e:"b",f:[{t:2,x:{r:["data.idsstatus"],s:'_0?"ENABLED":"DISABLED"'},p:[65,7,1957]}]}]}," ",{p:[68,3,2029],t:7,e:"ui-section",a:{label:"Maximal Log Count"},f:[{p:[69,4,2072],t:7,e:"b",f:[{t:2,r:"data.ntnetmaxlogs",p:[69,7,2075]}]}]}," ",{p:[72,3,2125],t:7,e:"ui-section",a:{label:"Controls"},f:[]}," ",{p:[74,4,2176],t:7,e:"table",f:[{p:[75,4,2188],t:7,e:"tr",f:[{p:[75,8,2192],t:7,e:"td",f:[{p:[75,12,2196],t:7,e:"ui-button",a:{action:"resetIDS"},f:["RESET IDS"]}]}]},{p:[76,4,2251],t:7,e:"tr",f:[{p:[76,8,2255],t:7,e:"td",f:[{p:[76,12,2259],t:7,e:"ui-button",a:{action:"toggleIDS"},f:["TOGGLE IDS"]}]}]},{p:[77,4,2316],t:7,e:"tr",f:[{p:[77,8,2320],t:7,e:"td",f:[{p:[77,12,2324],t:7,e:"ui-button",a:{action:"updatemaxlogs"},f:["SET LOG LIMIT"]}]}]},{p:[78,4,2388],t:7,e:"tr",f:[{p:[78,8,2392],t:7,e:"td",f:[{p:[78,12,2396],t:7,e:"ui-button",a:{action:"purgelogs"},f:["PURGE LOGS"]}]}]}]}," ",{p:[81,3,2467],t:7,e:"ui-subdisplay",a:{title:"System Logs"},f:[{p:[82,3,2506],t:7,e:"div",a:{"class":"statusDisplay",style:"overflow: auto;"},f:[{p:[83,3,2561],t:7,e:"div",a:{"class":"item"},f:[{p:[84,4,2584],t:7,e:"div",a:{"class":"itemContent",style:"width: 100%;"},f:[{t:4,f:[{t:2,r:"entry",p:[86,6,2667]},{p:[86,15,2676],t:7,e:"br"}],n:52,r:"data.ntnetlogs",p:[85,5,2636]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],426:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{t:4,f:[{p:[7,2,102],t:7,e:"div",a:{"class":"item"},f:[{p:[8,3,124],t:7,e:"h2",f:["An error has occurred during operation..."]}," ",{p:[9,3,178],t:7,e:"b",f:["Additional information:"]},{t:2,r:"data.error",p:[9,34,209]},{p:[9,48,223],t:7,e:"br"}," ",{p:[10,3,231],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Clear"]}]}],n:50,r:"data.error",p:[6,2,81]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.downloading"],s:"_0"},f:[{p:[13,3,321],t:7,e:"h2",f:["Download in progress..."]}," ",{p:[14,3,357],t:7,e:"div",a:{"class":"itemLabel"},f:["Downloaded file:"]}," ",{p:[17,3,416],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_name",p:[18,4,446]}]}," ",{p:[20,3,483],t:7,e:"div",a:{"class":"itemLabel"},f:["Download progress:"]}," ",{p:[23,3,544],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_progress",p:[24,4,574]}," / ",{t:2,r:"data.download_size",p:[24,33,603]}," GQ"]}," ",{p:[26,3,642],t:7,e:"div",a:{"class":"itemLabel"},f:["Transfer speed:"]}," ",{p:[29,3,700],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.download_netspeed",p:[30,4,730]},"GQ/s"]}," ",{p:[32,3,774],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[35,3,826],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[36,4,856],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Abort download"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading"],s:"(!(_0))&&(_1)"},f:[" ",{p:[39,3,954],t:7,e:"h2",f:["Server enabled"]}," ",{p:[40,3,981],t:7,e:"div",a:{"class":"itemLabel"},f:["Connected clients:"]}," ",{p:[43,3,1042],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_clients",p:[44,4,1072]}]}," ",{p:[46,3,1109],t:7,e:"div",a:{"class":"itemLabel"},f:["Provided file:"]}," ",{p:[49,3,1166],t:7,e:"div",a:{"class":"itemContent"},f:[{t:2,r:"data.upload_filename",p:[50,4,1196]}]}," ",{p:[52,3,1234],t:7,e:"div",a:{"class":"itemLabel"},f:["Server password:"]}," ",{p:[55,3,1293],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ENABLED"],n:50,r:"data.upload_haspassword",p:[56,4,1323]},{t:4,n:51,f:["DISABLED"],r:"data.upload_haspassword"}]}," ",{p:[62,3,1420],t:7,e:"div",a:{"class":"itemLabel"},f:["Commands:"]}," ",{p:[65,3,1472],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[66,4,1502],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[67,4,1567],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Exit server"]}]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(_2))"},f:[" ",{p:[70,3,1668],t:7,e:"h2",f:["File transfer server ready. Select file to upload:"]}," ",{p:[71,3,1732],t:7,e:"table",f:[{p:[72,3,1743],t:7,e:"tr",f:[{p:[72,7,1747],t:7,e:"th",f:["File name"]},{p:[72,20,1760],t:7,e:"th",f:["File size"]},{p:[72,33,1773],t:7,e:"th",f:["Controls ",{t:4,f:[{p:[74,4,1824],t:7,e:"tr",f:[{p:[74,8,1828],t:7,e:"td",f:[{t:2,r:"filename",p:[74,12,1832]}]},{p:[75,4,1849],t:7,e:"td",f:[{t:2,r:"size",p:[75,8,1853]},"GQ"]},{p:[76,4,1868],t:7,e:"td",f:[{p:[76,8,1872],t:7,e:"ui-button",a:{action:"PRG_uploadfile",params:['{"id": "',{t:2,r:"uid",p:[76,59,1923]},'"}']},f:["Select"]}]}]}],n:52,r:"data.upload_filelist",p:[73,3,1789]}]}]}]}," ",{p:[79,3,1981],t:7,e:"hr"}," ",{p:[80,3,1989],t:7,e:"ui-button",a:{action:"PRG_setpassword"},f:["Set password"]}," ",{p:[81,3,2053],t:7,e:"ui-button",a:{action:"PRG_reset"},f:["Return"]}]},{t:4,n:50,x:{r:["data.downloading","data.uploading","data.upload_filelist"],s:"(!(_0))&&((!(_1))&&(!(_2)))"},f:[" ",{p:[83,3,2116],t:7,e:"h2",f:["Available files:"]}," ",{p:[84,3,2145],t:7,e:"table",a:{border:"1",style:"border-collapse: collapse"},f:[{p:[84,55,2197],t:7,e:"tr",f:[{p:[84,59,2201],t:7,e:"th",f:["Server UID"]},{p:[84,73,2215],t:7,e:"th",f:["File Name"]},{p:[84,86,2228],t:7,e:"th",f:["File Size"]},{p:[84,99,2241],t:7,e:"th",f:["Password Protection"]},{p:[84,122,2264],t:7,e:"th",f:["Operations ",{t:4,f:[{p:[86,5,2311],t:7,e:"tr",f:[{p:[86,9,2315],t:7,e:"td",f:[{t:2,r:"uid",p:[86,13,2319]}]},{p:[87,5,2332],t:7,e:"td",f:[{t:2,r:"filename",p:[87,9,2336]}]},{p:[88,5,2354],t:7,e:"td",f:[{t:2,r:"size",p:[88,9,2358]},"GQ ",{t:4,f:[{p:[90,6,2400],t:7,e:"td",f:["Enabled"]}],n:50,r:"haspassword",p:[89,5,2374]}," ",{t:4,f:[{p:[93,6,2457],t:7,e:"td",f:["Disabled"]}],n:50,x:{r:["haspassword"],s:"!_0"},p:[92,5,2430]}]},{p:[96,5,2494],t:7,e:"td",f:[{p:[96,9,2498],t:7,e:"ui-button",a:{action:"PRG_downloadfile",params:['{"id": "',{t:2,r:"uid",p:[96,62,2551]},'"}']},f:["Download"]}]}]}],n:52,r:"data.servers",p:[85,4,2283]}]}]}]}," ",{p:[99,3,2612],t:7,e:"hr"}," ",{p:[100,3,2620],t:7,e:"ui-button",a:{action:"PRG_uploadmenu"},f:["Send file"]}]}],r:"data.error"}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],427:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[43,1,1082],t:7,e:"ntosheader"}," ",{p:[45,1,1099],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[47,5,1157],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[47,27,1179]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[49,38,1331]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[50,15,1387]}],yinc:"9"}}],n:50,r:"config.fancy",p:[46,3,1131]},{t:4,n:51,f:[{p:[52,5,1437],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[53,7,1475],t:7,e:"span",f:[{t:2,r:"data.supply",p:[53,13,1481]}]}]}," ",{p:[55,5,1528],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[56,9,1563],t:7,e:"span",f:[{t:2,r:"data.demand",p:[56,15,1569]}]}]}],r:"config.fancy"}]}," ",{p:[60,1,1638],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[61,3,1668],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[62,5,1693],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[63,5,1730],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[64,5,1769],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[65,5,1806],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[66,5,1845],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[67,5,1887],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[68,5,1928],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[71,5,2013],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[71,24,2032]}],nowrap:0},f:[{p:[72,7,2057],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[72,28,2078]}," %"]}," ",{p:[73,7,2136],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[73,28,2157]}]}," ",{p:[74,7,2199],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2220],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[74,41,2233]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[74,70,2262]}]}]}," ",{p:[75,7,2309],t:7,e:"div",a:{"class":"content"},f:[{p:[75,28,2330],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[75,41,2343]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[75,64,2366]}," [",{p:[75,87,2389],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[75,93,2395]}]},"]"]}]}," ",{p:[76,7,2444],t:7,e:"div",a:{"class":"content"},f:[{p:[76,28,2465],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[76,41,2478]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[76,64,2501]}," [",{p:[76,87,2524],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[76,93,2530]}]},"]"]}]}," ",{p:[77,7,2579],t:7,e:"div",a:{"class":"content"},f:[{p:[77,28,2600],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[77,41,2613]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[77,64,2636]}," [",{p:[77,87,2659],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[77,93,2665]}]},"]"]}]}]}],n:52,r:"data.areas",p:[70,3,1987]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],428:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{p:[4,1,64],t:7,e:"ui-display",f:[{p:[5,2,79],t:7,e:"div",a:{"class":"item"},f:[{p:[6,3,101],t:7,e:"div",a:{"class":"itemLabel"},f:["Payload status:"]}," ",{p:[9,3,158],t:7,e:"div",a:{"class":"itemContent"},f:[{t:4,f:["ARMED"],n:50,r:"data.armed",p:[10,4,188]},{t:4,n:51,f:["DISARMED"],r:"data.armed"}]}," ",{p:[16,3,270],t:7,e:"div",a:{"class":"itemLabel"},f:["Controls:"]}," ",{p:[19,3,321],t:7,e:"div",a:{"class":"itemContent"},f:[{p:[20,4,351],t:7,e:"table",f:[{p:[21,4,363],t:7,e:"tr",f:[{p:[21,8,367],t:7,e:"td",f:[{p:[21,12,371],t:7,e:"ui-button",a:{action:"PRG_obfuscate"},f:["OBFUSCATE PROGRAM NAME"]}]}]},{p:[22,4,444],t:7,e:"tr",f:[{p:[22,8,448],t:7,e:"td",f:[{p:[22,12,452],t:7,e:"ui-button",a:{action:"PRG_arm",state:[{t:2,x:{r:["data.armed"],s:'_0?"danger":null'},p:[22,47,487]}]},f:[{t:2,x:{r:["data.armed"],s:'_0?"DISARM":"ARM"'},p:[22,81,521]}]}," ",{p:[23,4,571],t:7,e:"ui-button",a:{icon:"radiation",state:[{t:2,x:{r:["data.armed"],s:'_0?null:"disabled"'},p:[23,39,606]}],action:"PRG_activate"},f:["ACTIVATE"]}]}]}]}]}]}]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],429:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[2,1,47],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[5,3,95],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[5,22,114]}," Alarms"]},f:[{p:[6,5,138],t:7,e:"ul",f:[{t:4,f:[{p:[8,9,171],t:7,e:"li",f:[{t:2,r:".",p:[8,13,175]}]}],n:52,r:".",p:[7,7,150]},{t:4,n:51,f:[{p:[10,9,211],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[4,1,64]}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],430:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{integState:function(t){var e=100;return t==e?"good":t>e/2?"average":"bad"},bigState:function(t,e,n){return charge>n?"bad":t>e?"average":"good"}}}}(r),r.exports.template={v:3,t:[" "," ",{p:[23,1,421],t:7,e:"ntosheader"}," ",{t:4,f:[{p:[27,2,462],t:7,e:"ui-button",a:{action:"PRG_clear"},f:["Back to Menu"]},{p:[27,56,516],t:7,e:"br"}," ",{p:[28,3,524],t:7,e:"ui-display",a:{title:"Supermatter Status:"},f:[{p:[29,3,568],t:7,e:"ui-section",a:{label:"Core Integrity"},f:[{p:[30,5,609],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"adata.SM_integrity",p:[30,38,642]}],state:[{t:2,x:{r:["integState","adata.SM_integrity"],s:"_0(_1)"},p:[30,69,673]}]},f:[{t:2,r:"data.SM_integrity",p:[30,105,709]},"%"]}]}," ",{p:[32,3,761],t:7,e:"ui-section",a:{label:"Relative EER"},f:[{p:[33,5,800],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_power"],s:"_0(_1,150,300)"},p:[33,18,813]}]},f:[{t:2,r:"data.SM_power",p:[33,55,850]}," MeV/cm3"]}]}," ",{p:[35,3,903],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[36,5,941],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambienttemp"],s:"_0(_1,4000,5000)"},p:[36,18,954]}]},f:[{t:2,r:"data.SM_ambienttemp",p:[36,63,999]}," K"]}]}," ",{p:[38,3,1052],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[39,5,1087],t:7,e:"span",a:{"class":[{t:2,x:{r:["bigState","data.SM_ambientpressure"],s:"_0(_1,5000,10000)"},p:[39,18,1100]}]},f:[{t:2,r:"data.SM_ambientpressure",p:[39,68,1150]}," kPa"]}]}]}," ",{p:[42,3,1227],t:7,e:"hr"},{p:[42,7,1231],t:7,e:"br"}," ",{p:[43,3,1239],t:7,e:"ui-display",a:{title:"Gas Composition:"},f:[{t:4,f:[{p:[45,5,1307],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[45,24,1326]}]},f:[{t:2,r:"amount",p:[46,6,1343]}," %"]}],n:52,r:"data.gases",p:[44,4,1281]}]}],n:50,r:"data.active",p:[26,1,440]},{t:4,n:51,f:[{p:[51,2,1418],t:7,e:"ui-button",a:{action:"PRG_refresh"},f:["Refresh"]},{p:[51,53,1469],t:7,e:"br"}," ",{p:[52,2,1476],t:7,e:"ui-display",a:{title:"Detected Supermatters"},f:[{t:4,f:[{p:[54,3,1552],t:7,e:"ui-section",a:{label:"Area"},f:[{t:2,r:"area_name",p:[55,5,1583]}," - (#",{t:2,r:"uid",p:[55,23,1601]},")"]}," ",{p:[57,3,1630],t:7,e:"ui-section",a:{label:"Integrity"},f:[{t:2,r:"integrity",p:[58,5,1666]}," %"]}," ",{p:[60,3,1702],t:7,e:"ui-section",a:{label:"Options"},f:[{p:[61,5,1736],t:7,e:"ui-button",a:{action:"PRG_set",params:['{"target" : "',{t:2,r:"uid",p:[61,54,1785]},'"}']},f:["View Details"]}]}],n:52,r:"data.supermatters",p:[53,2,1521]}]}],r:"data.active"}]},r.exports.components=r.exports.components||{};var i={ntosheader:t(431)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,431:431}],431:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"div",a:{"class":"item",style:"float: left"},f:[{p:[2,2,41],t:7,e:"table",f:[{p:[2,9,48],t:7,e:"tr",f:[{t:4,f:[{p:[4,3,113],t:7,e:"td",f:[{p:[4,7,117],t:7,e:"img",a:{src:[{t:2,r:"data.PC_batteryicon",p:[4,17,127]}]}}]}],n:50,x:{r:["data.PC_batteryicon","data.PC_showbatteryicon"],s:"_0&&_1"},p:[3,2,55]}," ",{t:4,f:[{p:[7,3,226],t:7,e:"td",f:[{p:[7,7,230],t:7,e:"b",f:[{t:2,r:"data.PC_batterypercent",p:[7,10,233]}]}]}],n:50,x:{r:["data.PC_batterypercent","data.PC_showbatteryicon"],s:"_0&&_1"},p:[6,2,165]}," ",{t:4,f:[{p:[10,3,305],t:7,e:"td",f:[{p:[10,7,309],t:7,e:"img",a:{src:[{t:2,r:"data.PC_ntneticon",p:[10,17,319]}]}}]}],n:50,r:"data.PC_ntneticon",p:[9,2,276]}," ",{t:4,f:[{p:[13,3,386],t:7,e:"td",f:[{p:[13,7,390],t:7,e:"img",a:{src:[{t:2,r:"data.PC_apclinkicon",p:[13,17,400]}]}}]}],n:50,r:"data.PC_apclinkicon",p:[12,2,355]}," ",{t:4,f:[{p:[16,3,469],t:7,e:"td",f:[{p:[16,7,473],t:7,e:"b",f:[{t:2,r:"data.PC_stationtime",p:[16,10,476]}]}]}],n:50,r:"data.PC_stationtime",p:[15,2,438]}," ",{t:4,f:[{p:[19,3,552],t:7,e:"td",f:[{p:[19,7,556],t:7,e:"img",a:{src:[{t:2,r:"icon",p:[19,17,566]}]}}]}],n:52,r:"data.PC_programheaders",p:[18,2,516]}]}]}]}," ",{p:[23,1,609],t:7,e:"div",a:{style:"float: right; margin-top: 5px"},f:[{p:[24,2,655],t:7,e:"ui-button",a:{action:"PC_shutdown"},f:["Shutdown"]}," ",{t:4,f:[{p:[26,3,745],t:7,e:"ui-button",a:{action:"PC_exit"},f:["EXIT PROGRAM"]}," ",{p:[27,3,801],t:7,e:"ui-button",a:{action:"PC_minimize"},f:["Minimize Program"]}],n:50,r:"data.PC_showexitprogram",p:[25,2,710]}]}," ",{p:[30,1,881],t:7,e:"div",a:{style:"clear: both"}}]},e.exports=a.extend(r.exports)},{341:341}],432:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Auth. Disk:"},f:[{t:4,f:[{p:[3,7,69],t:7,e:"ui-button",a:{icon:"eject",style:"selected",action:"eject_disk"},f:["++++++++++"]}],n:50,r:"data.disk_present",p:[2,3,36]},{t:4,n:51,f:[{p:[5,7,172],t:7,e:"ui-button",a:{icon:"plus",action:"insert_disk"},f:["----------"]}],r:"data.disk_present"}]}," ",{p:[8,1,266],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[9,3,297],t:7,e:"span",f:[{t:2,r:"data.status1",p:[9,9,303]},"-",{t:2,r:"data.status2",p:[9,26,320]}]}]}," ",{p:[11,1,360],t:7,e:"ui-display",a:{title:"Timer"},f:[{p:[12,3,390],t:7,e:"ui-section",a:{label:"Time to Detonation"},f:[{p:[13,5,435],t:7,e:"span",f:[{t:2,x:{r:["data.timing","data.time_left","data.timer_set"],s:"_0?_1:_2"},p:[13,11,441]}]}]}," ",{t:4,f:[{p:[16,5,540],t:7,e:"ui-section",a:{label:"Adjust Timer"},f:[{p:[17,7,581],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_default"],s:'_0&&_1&&_2?null:"disabled"'},p:[17,40,614]}],action:"timer",params:'{"change": "reset"}'},f:["Reset"]}," ",{p:[19,7,786],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_min"],s:'_0&&_1&&_2?null:"disabled"'},p:[19,38,817]}],action:"timer",params:'{"change": "decrease"}'},f:["Decrease"]}," ",{p:[21,7,991],t:7,e:"ui-button",a:{icon:"pencil",state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[21,39,1023]}],action:"timer",params:'{"change": "input"}'},f:["Set"]}," ",{p:[22,7,1155],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.timer_is_not_max"],s:'_0&&_1&&_2?null:"disabled"'},p:[22,37,1185]}],action:"timer",params:'{"change": "increase"}'},f:["Increase"]}]}],n:51,r:"data.timing",p:[15,3,518]}," ",{p:[26,3,1394],t:7,e:"ui-section",a:{label:"Timer"},f:[{p:[27,5,1426],t:7,e:"ui-button",a:{icon:"clock-o",style:[{t:2,x:{r:["data.timing"],s:'_0?"danger":"caution"'},p:[27,38,1459]}],action:"toggle_timer",state:[{t:2,x:{r:["data.disk_present","data.code_approved","data.safety"],s:'_0&&_1&&!_2?null:"disabled"'},p:[29,14,1542]}]},f:[{t:2,x:{r:["data.timing"],s:'_0?"On":"Off"'},p:[30,7,1631]}]}]}]}," ",{p:[34,1,1713],t:7,e:"ui-display",a:{title:"Anchoring"},f:[{p:[35,3,1747],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[36,12,1770]}],icon:[{t:2,x:{r:["data.anchored"],s:'_0?"lock":"unlock"'},p:[37,11,1846]}],style:[{t:2,x:{r:["data.anchored"],s:'_0?null:"caution"'},p:[38,12,1897]}],action:"anchor"},f:[{t:2,x:{r:["data.anchored"],s:'_0?"Engaged":"Off"'},p:[39,21,1956]}]}]}," ",{p:[41,1,2022],t:7,e:"ui-display",a:{title:"Safety"},f:[{p:[42,3,2053],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.disk_present","data.code_approved"],s:'_0&&_1?null:"disabled"'},p:[43,12,2076]}],icon:[{t:2,x:{r:["data.safety"],s:'_0?"lock":"unlock"'},p:[44,11,2152]}],action:"safety",style:[{t:2,x:{r:["data.safety"],s:'_0?"caution":"danger"'},p:[45,12,2217]}]},f:[{p:[46,7,2265],t:7,e:"span",f:[{t:2,x:{r:["data.safety"],s:'_0?"On":"Off"'},p:[46,13,2271]}]}]}]}," ",{p:[49,1,2341],t:7,e:"ui-display",a:{title:"Code"},f:[{p:[50,3,2370],t:7,e:"ui-section",a:{label:"Message"},f:[{t:2,r:"data.message",p:[50,31,2398]}]}," ",{p:[51,3,2431],t:7,e:"ui-section",a:{label:"Keypad"},f:[{p:[52,5,2464],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[52,39,2498]}],params:'{"digit":"1"}'},f:["1"]}," ",{p:[53,5,2583],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[53,39,2617]}],params:'{"digit":"2"}'},f:["2"]}," ",{p:[54,5,2702],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[54,39,2736]}],params:'{"digit":"3"}'},f:["3"]}," ",{p:[55,5,2821],t:7,e:"br"}," ",{p:[56,5,2831],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[56,39,2865]}],params:'{"digit":"4"}'},f:["4"]}," ",{p:[57,5,2950],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[57,39,2984]}],params:'{"digit":"5"}'},f:["5"]}," ",{p:[58,5,3069],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[58,39,3103]}],params:'{"digit":"6"}'},f:["6"]}," ",{p:[59,5,3188],t:7,e:"br"}," ",{p:[60,5,3198],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[60,39,3232]}],params:'{"digit":"7"}'},f:["7"]}," ",{p:[61,5,3317],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[61,39,3351]}],params:'{"digit":"8"}'},f:["8"]}," ",{p:[62,5,3436],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[62,39,3470]}],params:'{"digit":"9"}'},f:["9"]}," ",{p:[63,5,3555],t:7,e:"br"}," ",{p:[64,5,3565],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[64,39,3599]}],params:'{"digit":"R"}'},f:["R"]}," ",{p:[65,5,3684],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[65,39,3718]}],params:'{"digit":"0"}'},f:["0"]}," ",{p:[66,5,3803],t:7,e:"ui-button",a:{action:"keypad",state:[{t:2,x:{r:["data.disk_present"],s:'_0?null:"disabled"'},p:[66,39,3837]}],params:'{"digit":"E"}'},f:["E"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],433:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,25],t:7,e:"ui-button",a:{icon:"undo",action:"change_menu",params:'{"menu": "1"}'},f:["Return"]}," ",{p:[3,2,113],t:7,e:"ui-display",a:{title:"Advanced Surgery Procedures"},f:[{p:[4,3,165],t:7,e:"ui-button",a:{icon:"download",action:"sync"},f:["Sync with research database"]}," ",{t:4,f:[{p:[6,4,278],t:7,e:"ui-display",f:[{p:[7,6,297],t:7,e:"ui-section",f:[{p:[7,18,309],t:7,e:"b",f:[{t:2,r:"name",p:[7,21,312]}]}]}," ",{p:[8,6,344],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[8,18,356]}]}]}],n:52,r:"data.surgeries",p:[5,3,249]}]}],n:50,x:{r:["data.menu"],s:"_0==2"},p:[1,1,0]},{t:4,n:51,f:[{p:[13,2,437],t:7,e:"ui-button",a:{action:"change_menu",params:'{"menu": "2"}'},f:["View Surgery Procedures"]}," ",{t:4,f:[{p:[15,3,556],t:7,e:"ui-notice",f:["No table detected!"]}],n:51,r:"data.table",p:[14,2,530]}," ",{p:[19,2,623],t:7,e:"ui-display",f:[{p:[20,3,639],t:7,e:"ui-display",a:{title:"Patient State"},f:[{t:4,f:[{p:[22,5,704],t:7,e:"ui-section",a:{label:"State"},f:[{p:[23,6,737],t:7,e:"span",a:{"class":[{t:2,r:"data.patient.statstate",p:[23,19,750]}]},f:[{t:2,r:"data.patient.stat",p:[23,47,778]}]}]}," ",{p:[25,5,831],t:7,e:"ui-section",a:{label:"Blood Type"},f:[{p:[26,6,869],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"data.patient.blood_type",p:[26,28,891]}]}]}," ",{p:[28,5,950],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[29,6,984],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.patient.minHealth",p:[29,19,997]}],max:[{t:2,r:"data.patient.maxHealth",p:[29,52,1030]}],value:[{t:2,r:"data.patient.health",p:[29,87,1065]}],state:[{t:2,x:{r:["data.patient.health"],s:'_0>=0?"good":"average"'},p:[30,13,1103]}]},f:[{t:2,x:{r:["adata.patient.health"],s:"Math.round(_0)"},p:[30,64,1154]}]}]}," ",{t:4,f:[{p:[33,6,1389],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[33,25,1408]}]},f:[{p:[34,7,1427],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.patient.maxHealth",p:[34,28,1448]}],value:[{t:2,rx:{r:"data.patient",m:[{t:30,n:"type"}]},p:[34,63,1483]}],state:"bad"},f:[{t:2,x:{r:["type","adata.patient"],s:"Math.round(_1[_0])"},p:[34,99,1519]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Burn",type:"fireLoss"},{label:"Toxin",type:"toxLoss"},{label:"Respiratory",type:"oxyLoss"}]'},p:[32,5,1224]}],n:50,r:"data.patient",p:[21,4,678]},{t:4,n:51,f:["No patient detected."],r:"data.patient"}]}," ",{p:[41,3,1670],t:7,e:"ui-display",a:{title:"Initiated Procedures"},f:[{t:4,f:[{t:4,f:[{p:[44,6,1777],t:7,e:"ui-subdisplay",a:{title:[{t:2,r:"name",p:[44,28,1799]}]},f:[{p:[45,7,1817],t:7,e:"ui-section",a:{label:"Next Step"},f:[{p:[46,8,1856],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"next_step",p:[46,30,1878]}]}," ",{t:4,f:[{p:[48,9,1937],t:7,e:"span",a:{"class":"content"},f:[{p:[48,31,1959],t:7,e:"b",f:["Required chemicals:"]},{p:[48,57,1985],t:7,e:"br"}," ",{t:2,r:"chems_needed",p:[48,62,1990]}]}],n:50,r:"chems_needed",p:[47,8,1907]}]}," ",{t:4,f:[{p:[52,8,2091],t:7,e:"ui-section",a:{label:"Alternative Step"},f:[{p:[53,9,2138],t:7,e:"span",a:{"class":"content"},f:[{t:2,r:"alternative_step",p:[53,31,2160]}]}," ",{t:4,f:[{p:[55,10,2232],t:7,e:"span",a:{"class":"content"},f:[{p:[55,32,2254],t:7,e:"b",f:["Required chemicals:"]},{p:[55,58,2280],t:7,e:"br"}," ",{t:2,r:"chems_needed",p:[55,63,2285]}]}],n:50,r:"alt_chems_needed",p:[54,9,2197]}]}],n:50,r:"alternative_step",p:[51,7,2058]}]}],n:52,r:"data.procedures",p:[43,5,1745]}],n:50,r:"data.procedures",p:[42,4,1716]},{t:4,n:51,f:["No active procedures."],r:"data.procedures"}]}]}],x:{r:["data.menu"],s:"_0==2"}}]},e.exports=a.extend(r.exports)},{341:341}],434:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,2,15],t:7,e:"ui-section",f:["This machine only accepts ore. Gibtonite and Slag are not accepted."]}," ",{p:[5,2,117],t:7,e:"ui-section",f:["Current unclaimed credits: ",{t:2,r:"data.unclaimedPoints",p:[6,30,160]}," ",{p:[7,4,189],t:7,e:"ui-button",a:{action:"Claim"},f:["Claim"]}]}]}," ",{p:[12,1,276],t:7,e:"ui-display",f:[{t:4,f:[{p:[14,3,315],t:7,e:"ui-section",f:[{p:[15,4,332],t:7,e:"ui-button",a:{action:"diskEject",icon:"eject"},f:["Eject Disk"]}]}," ",{t:4,f:[{p:[20,4,460],t:7,e:"ui-section",a:{"class":"candystripe"},f:[{p:[21,5,496],t:7,e:"ui-button",a:{action:"diskUpload",state:[{t:2,x:{r:["canupload"],s:'(_0)?null:"disabled"'},p:[21,42,533]}],icon:"upload",align:"right",params:['{ "design" : "',{t:2,r:"index",p:[21,129,620]},'" }']},f:["Upload"]}," File ",{t:2,r:"index",p:[24,10,676]},": ",{t:2,r:"name",p:[24,21,687]}]}],n:52,r:"data.diskDesigns",p:[19,3,429]}],n:50,r:"data.hasDisk",p:[13,2,291]},{t:4,n:51,f:[{p:[28,3,741],t:7,e:"ui-section",f:[{p:[29,4,758],t:7,e:"ui-button",a:{action:"diskInsert",icon:"floppy-o"},f:["Insert Disk"]}]}],r:"data.hasDisk"}]}," ",{t:4,f:[{p:[36,2,911],t:7,e:"ui-display",f:[{p:[37,3,927],t:7,e:"ui-section",f:[{p:[38,4,944],t:7,e:"b",f:["Warning"]},": ",{t:2,r:"data.disconnected",p:[38,20,960]},". Please contact the quartermaster."]}]}],n:50,r:"data.disconnected",p:[35,1,883]},{t:4,f:[{p:[43,2,1100],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[44,3,1133],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[45,5,1168],t:7,e:"section",a:{"class":"cell"},f:["Mineral"]}," ",{p:[48,5,1226],t:7,e:"section",a:{"class":"cell"},f:["Sheets"]}," ",{p:[51,5,1283],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[53,5,1327],t:7,e:"section",a:{"class":"cell"},f:[]}," ",{p:[55,5,1371],t:7,e:"section",a:{"class":"cell"},f:["Ore Value"]}]}," ",{t:4,f:[{p:[60,4,1473],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[61,5,1508],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[62,6,1537]}]}," ",{p:[64,5,1567],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[65,6,1610]}]}," ",{p:[67,5,1642],t:7,e:"section",a:{"class":"cell"},f:[{p:[68,6,1671],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[68,19,1684]}],placeholder:"###","class":"number"}}]}," ",{p:[70,5,1751],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[71,6,1794],
+t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[71,60,1848]}],params:['{ "id" : ',{t:2,r:"id",p:[71,115,1903]},', "sheets" : ',{t:2,r:"sheets",p:[71,134,1922]}," }"]},f:["Release"]}]}," ",{p:[75,5,1993],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"value",p:[76,6,2036]}]}]}],n:52,r:"data.materials",p:[59,3,1444]}," ",{t:4,f:[{p:[81,4,2119],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[82,5,2154],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[83,6,2183]}]}," ",{p:[85,5,2213],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[86,6,2256]}]}," ",{p:[88,5,2288],t:7,e:"section",a:{"class":"cell"},f:[{p:[89,6,2317],t:7,e:"input",a:{value:[{t:2,r:"sheets",p:[89,19,2330]}],placeholder:"###","class":"number"}}]}," ",{p:[91,5,2397],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{p:[92,6,2440],t:7,e:"ui-button",a:{"class":"center",grid:0,action:"Smelt",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[92,58,2492]}],params:['{ "id" : ',{t:2,r:"id",p:[92,114,2548]},', "sheets" : ',{t:2,r:"sheets",p:[92,133,2567]}," }"]},f:["Smelt"]}]}," ",{p:[96,5,2635],t:7,e:"section",a:{"class":"cell",align:"right"},f:[]}]}],n:52,r:"data.alloys",p:[80,3,2093]}]}],n:50,x:{r:["data.materials","data.alloys"],s:"_0||_1"},p:[42,1,1060]}]},e.exports=a.extend(r.exports)},{341:341}],435:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,4,87],t:7,e:"ui-button",a:{icon:"remove",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[4,36,119]}],action:"empty_eject_beaker"},f:["Empty and eject"]}," ",{p:[7,4,231],t:7,e:"ui-button",a:{icon:"trash",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[7,35,262]}],action:"empty_beaker"},f:["Empty"]}," ",{p:[10,4,358],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.has_beaker"],s:'_0?null:"disabled"'},p:[10,35,389]}],action:"eject_beaker"},f:["Eject"]}]},t:7,e:"ui-display",a:{title:"Beaker",button:0},f:[" ",{t:4,f:[{p:[15,4,528],t:7,e:"ui-section",f:[{t:4,f:[{p:[17,6,578],t:7,e:"span",a:{"class":"bad"},f:["The beaker is empty!"]}],n:50,r:"data.beaker_empty",p:[16,5,546]},{t:4,n:51,f:[{p:[19,6,644],t:7,e:"ui-subdisplay",a:{title:"Blood"},f:[{t:4,f:[{p:[21,8,712],t:7,e:"ui-section",a:{label:"Blood DNA"},f:[{t:2,r:"data.blood.dna",p:[21,38,742]}]}," ",{p:[22,8,782],t:7,e:"ui-section",a:{label:"Blood type"},f:[{t:2,r:"data.blood.type",p:[22,39,813]}]}],n:50,r:"data.has_blood",p:[20,7,681]},{t:4,n:51,f:[{p:[24,8,870],t:7,e:"ui-section",f:[{p:[25,9,892],t:7,e:"span",a:{"class":"average"},f:["No blood sample detected."]}]}],r:"data.has_blood"}]}],r:"data.beaker_empty"}]}],n:50,r:"data.has_beaker",p:[14,3,500]},{t:4,n:51,f:[{p:[32,4,1054],t:7,e:"ui-section",f:[{p:[33,5,1072],t:7,e:"span",a:{"class":"bad"},f:["No beaker loaded."]}]}],r:"data.has_beaker"}]}," ",{t:4,f:[{p:[38,3,1188],t:7,e:"ui-display",a:{title:"Diseases"},f:[{t:4,f:[{p:{button:[{t:4,f:[{p:[43,8,1343],t:7,e:"ui-button",a:{icon:"pencil",action:"rename_disease",state:[{t:2,x:{r:["can_rename"],s:'_0?"":"disabled"'},p:[43,64,1399]}],params:['{"index": ',{t:2,r:"index",p:[43,116,1451]},"}"]},f:["Name advanced disease"]}],n:50,r:"is_adv",p:[42,7,1320]}," ",{p:[47,7,1538],t:7,e:"ui-button",a:{icon:"flask",action:"create_culture_bottle",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[47,69,1600]}],params:['{"index": ',{t:2,r:"index",p:[47,124,1655]},"}"]},f:["Create virus culture bottle"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[40,24,1269]}],button:0},f:[" ",{p:[51,6,1749],t:7,e:"ui-section",a:{label:"Disease agent"},f:[{t:2,r:"agent",p:[51,40,1783]}]}," ",{p:[52,6,1812],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[52,38,1844]}]}," ",{p:[53,6,1879],t:7,e:"ui-section",a:{label:"Spread"},f:[{t:2,r:"spread",p:[53,33,1906]}]}," ",{p:[54,6,1936],t:7,e:"ui-section",a:{label:"Possible cure"},f:[{t:2,r:"cure",p:[54,40,1970]}]}," ",{t:4,f:[{p:[56,7,2021],t:7,e:"ui-section",a:{label:"Symptoms"},f:[{t:4,f:[{p:[58,9,2087],t:7,e:"ui-button",a:{action:"symptom_details",state:"",params:['{"picked_symptom": ',{t:2,r:"sym_index",p:[58,81,2159]},', "index": ',{t:2,r:"index",p:[58,105,2183]},"}"]},f:[{t:2,r:"name",p:[59,10,2206]}," "]},{p:[60,21,2236],t:7,e:"br"}],n:52,r:"symptoms",p:[57,8,2059]}]}," ",{p:[63,7,2289],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[63,38,2320]}]}," ",{p:[64,7,2355],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[64,35,2383]}]}," ",{p:[65,7,2415],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[65,39,2447]}]}," ",{p:[66,7,2483],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[66,44,2520]}]}],n:50,r:"is_adv",p:[55,6,1999]}]}],n:52,r:"data.viruses",p:[39,4,1222]},{t:4,n:51,f:[{p:[70,5,2601],t:7,e:"ui-section",f:[{p:[71,6,2620],t:7,e:"span",a:{"class":"average"},f:["No detectable virus in the blood sample."]}]}],r:"data.viruses"}]}," ",{p:[75,3,2743],t:7,e:"ui-display",a:{title:"Antibodies"},f:[{t:4,f:[{p:[77,5,2811],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[77,24,2830]}]},f:[{p:[78,7,2848],t:7,e:"ui-button",a:{icon:"eyedropper",state:[{t:2,x:{r:["data.is_ready"],s:'_0?"":"disabled"'},p:[78,43,2884]}],action:"create_vaccine_bottle",params:['{"index": ',{t:2,r:"id",p:[78,129,2970]},"}"]},f:["Create vaccine bottle"]}]}],n:52,r:"data.resistances",p:[76,4,2779]},{t:4,n:51,f:[{p:[83,5,3067],t:7,e:"ui-section",f:[{p:[84,6,3086],t:7,e:"span",a:{"class":"average"},f:["No antibodies detected in the blood sample."]}]}],r:"data.resistances"}]}],n:50,r:"data.has_blood",p:[37,2,1162]}],n:50,x:{r:["data.mode"],s:"_0==1"},p:[1,1,0]},{t:4,n:51,f:[{p:[90,2,3231],t:7,e:"ui-button",a:{icon:"undo",state:"",action:"back"},f:["Back"]}," ",{t:4,f:[{p:[94,4,3330],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[94,23,3349]}]},f:[{p:[95,4,3364],t:7,e:"ui-section",f:[{t:2,r:"desc",p:[96,5,3382]}," ",{t:4,f:[{p:[98,5,3417],t:7,e:"br"}," ",{p:[99,5,3428],t:7,e:"b",f:["This symptom has been neutered, and has no effect. It will still affect the virus' statistics."]}],n:50,r:"neutered",p:[97,4,3395]}]}," ",{p:[102,4,3564],t:7,e:"ui-section",f:[{p:[103,5,3582],t:7,e:"ui-section",a:{label:"Level"},f:[{t:2,r:"level",p:[103,31,3608]}]}," ",{p:[104,5,3636],t:7,e:"ui-section",a:{label:"Resistance"},f:[{t:2,r:"resistance",p:[104,36,3667]}]}," ",{p:[105,5,3700],t:7,e:"ui-section",a:{label:"Stealth"},f:[{t:2,r:"stealth",p:[105,33,3728]}]}," ",{p:[106,5,3758],t:7,e:"ui-section",a:{label:"Stage speed"},f:[{t:2,r:"stage_speed",p:[106,37,3790]}]}," ",{p:[107,5,3824],t:7,e:"ui-section",a:{label:"Transmittability"},f:[{t:2,r:"transmission",p:[107,42,3861]}]}]}," ",{p:[109,4,3913],t:7,e:"ui-subdisplay",a:{title:"Effect Thresholds"},f:[{p:[110,5,3960],t:7,e:"ui-section",f:[{t:3,r:"threshold_desc",p:[110,17,3972]}]}]}]}],n:53,r:"data.symptom",p:[93,2,3303]}],x:{r:["data.mode"],s:"_0==1"}}]},e.exports=a.extend(r.exports)},{341:341}],436:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(484);e.exports={data:{filter:"",tooltiptext:function(t,e,n){var a="";return t&&(a+="REQUIREMENTS: "+t+" "),e&&(a+="CATALYSTS: "+e+" "),n&&(a+="TOOLS: "+n),a}},oninit:function(){var t=this;this.on({hover:function(t){this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}}),this.observe("filter",function(e,a,r){var i=null;i=t.get("data.display_compact")?t.findAll(".section"):t.findAll(".display:not(:first-child)"),(0,n.filterMulti)(i,t.get("filter").toLowerCase())},{init:!1})}}}(r),r.exports.template={v:3,t:[" ",{p:[48,1,1342],t:7,e:"ui-display",a:{title:[{t:2,r:"data.category",p:[48,20,1361]},{t:4,f:[" : ",{t:2,r:"data.subcategory",p:[48,64,1405]}],n:50,r:"data.subcategory",p:[48,37,1378]}]},f:[{t:4,f:[{p:[50,3,1459],t:7,e:"ui-section",f:["Crafting... ",{p:[51,16,1488],t:7,e:"i",a:{"class":"fa-spin fa fa-spinner"}}]}],n:50,r:"data.busy",p:[49,2,1438]},{t:4,n:51,f:[{p:[54,3,1557],t:7,e:"ui-section",f:[{p:[55,4,1574],t:7,e:"table",a:{style:"width:100%"},f:[{p:[56,5,1606],t:7,e:"tr",f:[{p:[57,6,1617],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[58,7,1659],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardCat"},f:[{t:2,r:"data.prev_cat",p:[59,8,1718]}]}]}," ",{p:[62,6,1774],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[63,7,1816],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardCat"},f:[{t:2,r:"data.next_cat",p:[64,7,1874]}]}]}," ",{p:[67,6,1930],t:7,e:"td",a:{style:"float:right!important"},f:[{t:4,f:[{p:[69,7,2014],t:7,e:"ui-button",a:{icon:"lock",action:"toggle_recipes"},f:["Showing Craftable Recipes"]}],n:50,r:"data.display_craftable_only",p:[68,6,1971]},{t:4,n:51,f:[{p:[73,7,2138],t:7,e:"ui-button",a:{icon:"unlock",action:"toggle_recipes"},f:["Showing All Recipes"]}],r:"data.display_craftable_only"}]}," ",{p:[78,6,2268],t:7,e:"td",a:{style:"float:right!important"},f:[{p:[79,7,2310],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.display_compact"],s:'_0?"check-square-o":"square-o"'},p:[79,24,2327]}],action:"toggle_compact"},f:["Compact"]}]}]}," ",{p:[84,5,2474],t:7,e:"tr",f:[{t:4,f:[{p:[86,6,2515],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[87,7,2557],t:7,e:"ui-button",a:{icon:"arrow-left",action:"backwardSubCat"},f:[{t:2,r:"data.prev_subcat",p:[88,8,2619]}]}]}," ",{p:[91,6,2678],t:7,e:"td",a:{style:"width:150px!important"},f:[{p:[92,7,2720],t:7,e:"ui-button",a:{icon:"arrow-right",action:"forwardSubCat"},f:[{t:2,r:"data.next_subcat",p:[93,8,2782]}]}]}],n:50,r:"data.subcategory",p:[85,5,2484]}]}]}," ",{t:4,f:[{t:4,f:[" ",{p:[101,6,2992],t:7,e:"ui-input",a:{value:[{t:2,r:"filter",p:[101,23,3009]}],placeholder:"Filter.."}}],n:51,r:"data.display_compact",p:[100,5,2902]}],n:50,r:"config.fancy",p:[99,4,2876]}]}," ",{t:4,f:[{p:[106,5,3144],t:7,e:"ui-display",f:[{t:4,f:[{p:[108,6,3193],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[108,25,3212]}]},f:[{p:[109,7,3230],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[109,27,3250]}],"tooltip-side":"right",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[109,135,3358]},'"}'],icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.can_craft",p:[107,5,3162]}," ",{t:4,f:[{t:4,f:[{p:[116,7,3567],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[116,26,3586]}]},f:[{p:[117,8,3605],t:7,e:"ui-button",a:{tooltip:[{t:2,x:{r:["tooltiptext","req_text","catalyst_text","tool_text"],s:"_0(_1,_2,_3)"},p:[117,28,3625]}],"tooltip-side":"right",state:"disabled",icon:"gears"},v:{hover:"hover",unhover:"unhover"},f:["Craft"]}]}],n:52,r:"data.cant_craft",p:[115,6,3534]}],n:51,r:"data.display_craftable_only",p:[114,5,3495]}]}],n:50,r:"data.display_compact",p:[105,4,3110]},{t:4,n:51,f:[{t:4,f:[{p:[126,6,3947],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[126,25,3966]}]},f:[{t:4,f:[{p:[128,8,4009],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[129,9,4052]}]}],n:50,r:"req_text",p:[127,7,3984]}," ",{t:4,f:[{p:[133,8,4139],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[134,9,4179]}]}],n:50,r:"catalyst_text",p:[132,7,4109]}," ",{t:4,f:[{p:[138,8,4267],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[139,9,4303]}]}],n:50,r:"tool_text",p:[137,7,4241]}," ",{p:[142,7,4361],t:7,e:"ui-section",f:[{p:[143,8,4382],t:7,e:"ui-button",a:{icon:"gears",action:"make",params:['{"recipe": "',{t:2,r:"ref",p:[143,66,4440]},'"}']},f:["Craft"]}]}]}],n:52,r:"data.can_craft",p:[125,5,3916]}," ",{t:4,f:[{t:4,f:[{p:[151,7,4621],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[151,26,4640]}]},f:[{t:4,f:[{p:[153,9,4685],t:7,e:"ui-section",a:{label:"Requirements"},f:[{t:2,r:"req_text",p:[154,10,4729]}]}],n:50,r:"req_text",p:[152,8,4659]}," ",{t:4,f:[{p:[158,9,4820],t:7,e:"ui-section",a:{label:"Catalysts"},f:[{t:2,r:"catalyst_text",p:[159,10,4861]}]}],n:50,r:"catalyst_text",p:[157,8,4789]}," ",{t:4,f:[{p:[163,9,4953],t:7,e:"ui-section",a:{label:"Tools"},f:[{t:2,r:"tool_text",p:[164,10,4990]}]}],n:50,r:"tool_text",p:[162,8,4926]}]}],n:52,r:"data.cant_craft",p:[150,6,4588]}],n:51,r:"data.display_craftable_only",p:[149,5,4549]}],r:"data.display_compact"}],r:"data.busy"}]}]},e.exports=a.extend(r.exports)},{341:341,484:484}],437:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-notice",f:[{p:[2,3,15],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[2,23,35]}," connected to a tank."]}]}," ",{p:[4,1,113],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[5,3,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,5,186],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[6,11,192]}," kPa"]}]}," ",{p:[8,3,254],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[9,5,285],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[9,18,298]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[9,59,339]}]}]}]}," ",{p:[12,1,430],t:7,e:"ui-display",a:{title:"Pump"},f:[{p:[13,3,459],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,5,491],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[14,22,508]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[15,14,559]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[16,22,616]}]}]}," ",{p:[18,3,675],t:7,e:"ui-section",a:{label:"Direction"},f:[{p:[19,5,711],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"sign-out":"sign-in"'},p:[19,22,728]}],action:"direction"},f:[{t:2,x:{r:["data.direction"],s:'_0=="out"?"Out":"In"'},p:[20,26,808]}]}]}," ",{p:[22,3,883],t:7,e:"ui-section",a:{label:"Target Pressure"},f:[{p:[23,5,925],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.min_pressure",p:[23,18,938]}],max:[{t:2,r:"data.max_pressure",p:[23,46,966]}],value:[{t:2,r:"data.target_pressure",p:[24,14,1003]}]},f:[{t:2,x:{r:["adata.target_pressure"],s:"Math.round(_0)"},p:[24,40,1029]}," kPa"]}]}," ",{p:[26,3,1100],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,1145],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.target_pressure","data.default_pressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,1178]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1328],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.target_pressure","data.min_pressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1359]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1500],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1595],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.target_pressure","data.max_pressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1625]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}," ",{p:{button:[{t:4,f:[{p:[39,7,1891],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[39,38,1922]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[38,5,1863]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[43,3,2042],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[44,4,2073]}]}," ",{p:[46,3,2115],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[47,4,2149]}," kPa"]}],n:50,r:"data.holding",p:[42,3,2018]},{t:4,n:51,f:[{p:[50,3,2223],t:7,e:"ui-section",f:[{p:[51,4,2240],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}]},e.exports=a.extend(r.exports)},{341:341}],438:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" ",{p:[3,1,69],t:7,e:"ui-notice",f:[{p:[4,3,84],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.holding"],s:'_0?"is":"is not"'},p:[4,23,104]}," connected to a tank."]}]}," ",{p:[6,1,182],t:7,e:"ui-display",a:{title:"Status",button:0},f:[{p:[7,3,220],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[8,5,255],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.round(_0)"},p:[8,11,261]}," kPa"]}]}," ",{p:[10,3,323],t:7,e:"ui-section",a:{label:"Port"},f:[{p:[11,5,354],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected"],s:'_0?"good":"average"'},p:[11,18,367]}]},f:[{t:2,x:{r:["data.connected"],s:'_0?"Connected":"Not Connected"'},p:[11,59,408]}]}]}]}," ",{p:[14,1,499],t:7,e:"ui-display",a:{title:"Filter"},f:[{p:[15,3,530],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[16,5,562],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[16,22,579]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":"null"'},p:[17,14,630]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[18,22,687]}]}]}]}," ",{p:{button:[{t:4,f:[{p:[24,7,856],t:7,e:"ui-button",a:{icon:"eject",style:[{t:2,x:{r:["data.on"],s:'_0?"danger":null'},p:[24,38,887]}],action:"eject"},f:["Eject"]}],n:50,r:"data.holding",p:[23,5,828]}]},t:7,e:"ui-display",a:{title:"Holding Tank",button:0},f:[" ",{t:4,f:[{p:[28,3,1007],t:7,e:"ui-section",a:{label:"Label"},f:[{t:2,r:"data.holding.name",p:[29,4,1038]}]}," ",{p:[31,3,1080],t:7,e:"ui-section",a:{label:"Pressure"},f:[{t:2,x:{r:["adata.holding.pressure"],s:"Math.round(_0)"},p:[32,4,1114]}," kPa"]}],n:50,r:"data.holding",p:[27,3,983]},{t:4,n:51,f:[{p:[35,3,1188],t:7,e:"ui-section",f:[{p:[36,4,1205],t:7,e:"span",a:{"class":"average"},f:["No Holding Tank"]}]}],r:"data.holding"}]}," ",{p:[40,1,1293],t:7,e:"ui-display",a:{title:"Filters"},f:[{t:4,f:[{p:[42,5,1345],t:7,e:"filters"}],n:53,r:"data",p:[41,3,1325]}]}]},r.exports.components=r.exports.components||{};var i={filters:t(457)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,457:457}],439:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{chargingState:function(t){switch(t){case 2:return"good";case 1:return"average";default:return"bad"}},chargingMode:function(t){return 2==t?"Full":1==t?"Charging":"Draining"},channelState:function(t){return t>=2?"good":"bad"},channelPower:function(t){return t>=2?"On":"Off"},channelMode:function(t){return 1==t||3==t?"Auto":"Manual"}},computed:{graphData:function(){var t=this.get("data.history");return Object.keys(t).map(function(e){return t[e].map(function(t,e){return{x:e,y:t}})})}}}}(r),r.exports.template={v:3,t:[" ",{p:[42,1,1035],t:7,e:"ui-display",a:{title:"Network"},f:[{t:4,f:[{p:[44,5,1093],t:7,e:"ui-linegraph",a:{points:[{t:2,r:"graphData",p:[44,27,1115]}],height:"500",legend:'["Available", "Load"]',colors:'["rgb(0, 102, 0)", "rgb(153, 0, 0)"]',xunit:"seconds ago",xfactor:[{t:2,r:"data.interval",p:[46,38,1267]}],yunit:"W",yfactor:"1",xinc:[{t:2,x:{r:["data.stored"],s:"_0/10"},p:[47,15,1323]}],yinc:"9"}}],n:50,r:"config.fancy",p:[43,3,1067]},{t:4,n:51,f:[{p:[49,5,1373],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[50,7,1411],t:7,e:"span",f:[{t:2,r:"data.supply",p:[50,13,1417]}]}]}," ",{p:[52,5,1464],t:7,e:"ui-section",a:{label:"Load"},f:[{p:[53,9,1499],t:7,e:"span",f:[{t:2,r:"data.demand",p:[53,15,1505]}]}]}],r:"config.fancy"}]}," ",{p:[57,1,1574],t:7,e:"ui-display",a:{title:"Areas"},f:[{p:[58,3,1604],t:7,e:"ui-section",a:{nowrap:0},f:[{p:[59,5,1629],t:7,e:"div",a:{"class":"content"},f:["Area"]}," ",{p:[60,5,1666],t:7,e:"div",a:{"class":"content"},f:["Charge"]}," ",{p:[61,5,1705],t:7,e:"div",a:{"class":"content"},f:["Load"]}," ",{p:[62,5,1742],t:7,e:"div",a:{"class":"content"},f:["Status"]}," ",{p:[63,5,1781],t:7,e:"div",a:{"class":"content"},f:["Equipment"]}," ",{p:[64,5,1823],t:7,e:"div",a:{"class":"content"},f:["Lighting"]}," ",{p:[65,5,1864],t:7,e:"div",a:{"class":"content"},f:["Environment"]}]}," ",{t:4,f:[{p:[68,5,1949],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[68,24,1968]}],nowrap:0},f:[{p:[69,7,1993],t:7,e:"div",a:{"class":"content"},f:[{t:2,x:{r:["@index","adata.areas"],s:"Math.round(_1[_0].charge)"},p:[69,28,2014]}," %"]}," ",{p:[70,7,2072],t:7,e:"div",a:{"class":"content"},f:[{t:2,rx:{r:"adata.areas",m:[{t:30,n:"@index"},"load"]},p:[70,28,2093]}]}," ",{p:[71,7,2135],t:7,e:"div",a:{"class":"content"},f:[{p:[71,28,2156],t:7,e:"span",a:{"class":[{t:2,x:{r:["chargingState","charging"],s:"_0(_1)"},p:[71,41,2169]}]},f:[{t:2,x:{r:["chargingMode","charging"],s:"_0(_1)"},p:[71,70,2198]}]}]}," ",{p:[72,7,2245],t:7,e:"div",a:{"class":"content"},f:[{p:[72,28,2266],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","eqp"],s:"_0(_1)"},p:[72,41,2279]}]},f:[{t:2,x:{r:["channelPower","eqp"],s:"_0(_1)"},p:[72,64,2302]}," [",{p:[72,87,2325],t:7,e:"span",f:[{t:2,x:{r:["channelMode","eqp"],s:"_0(_1)"},p:[72,93,2331]}]},"]"]}]}," ",{p:[73,7,2380],t:7,e:"div",a:{"class":"content"},f:[{p:[73,28,2401],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","lgt"],s:"_0(_1)"},p:[73,41,2414]}]},f:[{t:2,x:{r:["channelPower","lgt"],s:"_0(_1)"},p:[73,64,2437]}," [",{p:[73,87,2460],t:7,e:"span",f:[{t:2,x:{r:["channelMode","lgt"],s:"_0(_1)"},p:[73,93,2466]}]},"]"]}]}," ",{p:[74,7,2515],t:7,e:"div",a:{"class":"content"},f:[{p:[74,28,2536],t:7,e:"span",a:{"class":[{t:2,x:{r:["channelState","env"],s:"_0(_1)"},p:[74,41,2549]}]},f:[{t:2,x:{r:["channelPower","env"],s:"_0(_1)"},p:[74,64,2572]}," [",{p:[74,87,2595],t:7,e:"span",f:[{t:2,x:{r:["channelMode","env"],s:"_0(_1)"},p:[74,93,2601]}]},"]"]}]}]}],n:52,r:"data.areas",p:[67,3,1923]}]}]},e.exports=a.extend(r.exports)},{341:341}],440:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{readableFrequency:function(){return Math.round(this.get("adata.frequency"))/10}}}}(r),r.exports.template={v:3,t:[" ",{p:[11,1,177],t:7,e:"ui-display",a:{title:"Settings"},f:[{t:4,f:[{p:[13,5,236],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[14,7,270],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[14,24,287]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[14,75,338]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"On":"Off"'},p:[16,9,413]}]}]}],n:50,r:"data.headset",p:[12,3,210]},{t:4,n:51,f:[{p:[19,5,494],t:7,e:"ui-section",a:{label:"Microphone"},f:[{p:[20,7,533],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.broadcasting"],s:'_0?"power-off":"close"'},p:[20,24,550]}],style:[{t:2,x:{r:["data.broadcasting"],s:'_0?"selected":null'},p:[20,78,604]}],action:"broadcast"},f:[{t:2,x:{r:["data.broadcasting"],s:'_0?"Engaged":"Disengaged"'},p:[22,9,685]}]}]}," ",{p:[24,5,769],t:7,e:"ui-section",a:{label:"Speaker"},f:[{p:[25,7,805],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.listening"],s:'_0?"power-off":"close"'},p:[25,24,822]}],style:[{t:2,x:{r:["data.listening"],s:'_0?"selected":null'},p:[25,75,873]}],action:"listen"},f:[{t:2,x:{r:["data.listening"],s:'_0?"Engaged":"Disengaged"'},p:[27,9,948]}]}]}],r:"data.headset"}," ",{t:4,f:[{p:[31,5,1064],t:7,e:"ui-section",a:{label:"High Volume"},f:[{p:[32,7,1104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.useCommand"],s:'_0?"power-off":"close"'},p:[32,24,1121]}],style:[{t:2,x:{r:["data.useCommand"],s:'_0?"selected":null'},p:[32,76,1173]}],action:"command"},f:[{t:2,x:{r:["data.useCommand"],s:'_0?"On":"Off"'},p:[34,9,1250]}]}]}],n:50,r:"data.command",p:[30,3,1038]}]}," ",{p:[38,1,1342],t:7,e:"ui-display",a:{title:"Channel"},f:[{p:[39,3,1374],t:7,e:"ui-section",a:{label:"Frequency"},f:[{t:4,f:[{p:[41,7,1439],t:7,e:"span",f:[{t:2,r:"readableFrequency",p:[41,13,1445]}]}],n:50,r:"data.freqlock",p:[40,5,1410]},{t:4,n:51,f:[{p:[43,7,1495],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[43,46,1534]}],action:"frequency",params:'{"adjust": -1}'}}," ",{p:[44,7,1646],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.frequency","data.minFrequency"],s:'_0==_1?"disabled":null'},p:[44,41,1680]}],action:"frequency",params:'{"adjust": -.2}'}}," ",{p:[45,7,1793],t:7,e:"ui-button",a:{icon:"pencil",action:"frequency",params:'{"tune": "input"}'},f:[{t:2,r:"readableFrequency",p:[45,78,1864]}]}," ",{p:[46,7,1905],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[46,40,1938]}],action:"frequency",params:'{"adjust": .2}'}}," ",{p:[47,7,2050],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.frequency","data.maxFrequency"],s:'_0==_1?"disabled":null'},p:[47,45,2088]}],action:"frequency",params:'{"adjust": 1}'}}],r:"data.freqlock"}]}," ",{t:4,f:[{p:[51,5,2262],t:7,e:"ui-section",a:{label:"Subspace Transmission"},f:[{p:[52,7,2312],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.subspace"],s:'_0?"power-off":"close"'},p:[52,24,2329]}],style:[{t:2,x:{r:["data.subspace"],s:'_0?"selected":null'},p:[52,74,2379]}],action:"subspace"},f:[{t:2,x:{r:["data.subspace"],s:'_0?"Active":"Inactive"'},p:[53,29,2447]}]}]}],n:50,r:"data.subspaceSwitchable",p:[50,3,2225]}," ",{t:4,f:[{p:[57,5,2578],t:7,e:"ui-section",a:{label:"Channels"},f:[{t:4,f:[{p:[59,9,2656],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["."],s:'_0?"check-square-o":"square-o"'},p:[59,26,2673]}],style:[{t:2,x:{r:["."],s:'_0?"selected":null'},p:[60,18,2730]}],action:"channel",params:['{"channel": "',{t:2,r:"channel",p:[61,49,2806]},'"}']},f:[{t:2,r:"channel",p:[62,11,2833]}]},{p:[62,34,2856],t:7,e:"br"}],n:52,i:"channel",r:"data.channels",p:[58,7,2615]}]}],n:50,x:{r:["data.subspace","data.channels"],s:"_0&&_1"},p:[56,3,2534]}]}]},e.exports=a.extend(r.exports)},{341:341}],441:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," "," "," "," "," "," "," "," ",{p:[11,1,560],t:7,e:"rdheader"}," ",{t:4,f:[{p:[13,2,595],t:7,e:"ui-display",a:{title:"CONSOLE LOCKED"},f:[{p:[14,3,634],t:7,e:"ui-button",a:{action:"Unlock"},f:["Unlock"]}]}],n:50,r:"data.locked",p:[12,1,573]},{t:4,f:[{p:[18,2,729],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[18,17,744]}]},f:[{p:[19,3,763],t:7,e:"tab",a:{name:"Technology"},f:[{p:[20,4,791],t:7,e:"techweb"}]}," ",{p:[22,3,815],t:7,e:"tab",a:{name:"View Node"},f:[{p:[23,4,842],t:7,e:"nodeview"}]}," ",{p:[25,3,867],t:7,e:"tab",a:{name:"View Design"},f:[{p:[26,4,896],t:7,e:"designview"}]}," ",{p:[28,3,923],t:7,e:"tab",a:{name:"Disk Operations - Design"},f:[{p:[29,4,965],t:7,e:"diskopsdesign"}]}," ",{p:[31,3,995],t:7,e:"tab",a:{name:"Disk Operations - Technology"},f:[{p:[32,4,1041],t:7,e:"diskopstech"}]}," ",{p:[34,3,1069],t:7,e:"tab",a:{name:"Deconstructive Analyzer"},f:[{p:[35,4,1110],t:7,e:"destruct"}]}," ",{p:[37,3,1135],t:7,e:"tab",a:{name:"Protolathe"},f:[{p:[38,4,1163],t:7,e:"protolathe"}]}," ",{p:[40,3,1190],t:7,e:"tab",a:{name:"Circuit Imprinter"},f:[{p:[41,4,1225],t:7,e:"circuit"}]}," ",{p:[43,3,1249],t:7,e:"tab",a:{name:"Settings"},f:[{p:[44,4,1275],t:7,e:"settings"}]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[17,1,706]}]},r.exports.components=r.exports.components||{};var i={settings:t(450),circuit:t(442),protolathe:t(448),destruct:t(444),diskopsdesign:t(445),diskopstech:t(446),designview:t(443),nodeview:t(447),techweb:t(451),rdheader:t(449)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,442:442,443:443,444:444,445:445,446:446,447:447,448:448,449:449,450:450,451:451}],442:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[3,3,58],t:7,e:"ui-display",a:{title:"Circuit Imprinter Busy!"}}],n:50,r:"data.circuitbusy",p:[2,2,30]},{t:4,n:51,f:[{p:[5,3,130],t:7,e:"ui-display",f:[{p:[6,4,147],t:7,e:"ui-section",f:["Search Available Designs: ",{p:[7,4,189],t:7,e:"input",a:{value:[{t:2,r:"textsearch",p:[7,17,202]}],placeholder:"Type Here","class":"text"}}," ",{p:[8,5,261],t:7,e:"ui-button",a:{action:"textSearch",params:['{"latheType" : "circuit", "inputText" : ',{t:2,r:"textsearch",p:[8,84,340]},"}"]},f:["Search"]}]}," ",{p:[10,4,398],t:7,e:"ui-section",f:["Materials: ",{t:2,r:"data.circuitmats",p:[10,27,421]}," / ",{t:2,r:"data.circuitmaxmats",p:[10,50,444]}]}," ",{p:[11,4,485],t:7,e:"ui-section",f:["Reagents: ",{t:2,r:"data.circuitchems",p:[11,26,507]}," / ",{t:2,r:"data.circuitmaxchems",p:[11,50,531]}]}," ",{p:[12,3,572],t:7,e:"ui-display",f:[{p:[14,3,590],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.lathe_tabs",p:[14,18,605]}]},f:[{p:[15,4,631],t:7,e:"tab",a:{name:"Category List"},f:[{t:4,f:[{p:[17,6,696],t:7,e:"ui-button",a:{action:"switchcat",state:[{t:2,x:{r:["data.circuitcat"],s:'_0=="{{name}}"?"selected":null'},p:[17,43,733]}],params:['{"type" : "circuit", "cat" : "',{t:2,r:"name",p:[17,135,825]},'"}']},f:[{t:2,r:"name",p:[17,147,837]}]}],n:52,r:"data.circuitcats",p:[16,5,663]}]}," ",{p:[20,4,888],t:7,e:"tab",a:{name:"Selected Category"},f:[{t:4,f:[{p:[22,6,956],t:7,e:"ui-section",f:[{t:2,r:"name",p:[22,18,968]},{t:2,r:"matstring",p:[22,26,976]}," ",{p:[23,7,997],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[23,40,1030]}],params:['{"latheType" : "circuit", "id" : "',{t:2,r:"id",p:[23,119,1109]},'"}']},f:["Print"]}]}],n:52,r:"data.circuitdes",p:[21,5,924]}]}," ",{p:[27,4,1187],t:7,e:"tab",a:{name:"Search Results"},f:[{t:4,f:[{p:[29,6,1254],t:7,e:"ui-section",f:[{t:2,r:"name",p:[29,18,1266]},{t:2,r:"matstring",p:[29,26,1274]}," ",{p:[30,7,1295],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[30,40,1328]}],params:['{"latheType" : "circuit", "id" : "',{t:2,r:"id",p:[30,119,1407]},'"}']},f:["Print"]}]}],n:52,r:"data.circuitmatch",p:[28,5,1220]}]}," ",{p:[34,4,1485],t:7,e:"tab",a:{name:"Materials"},f:[{t:4,f:[{p:[36,6,1550],t:7,e:"ui-section",f:[{t:2,r:"name",p:[36,18,1562]}," : ",{t:2,r:"amount",p:[36,29,1573]}," cm3 - ",{t:4,f:[{p:[38,7,1623],t:7,e:"input",a:{value:[{t:2,r:"number",p:[38,20,1636]}],placeholder:["1-",{t:2,r:"sheets",p:[38,46,1662]}],"class":"number"}}," ",{p:[39,7,1698],t:7,e:"ui-button",a:{action:"releasemats",params:['{"latheType" : "circuit", "mat_id" : ',{t:2,r:"mat_id",p:[39,84,1775]},', "sheets" : ',{t:2,r:"number",p:[39,107,1798]},"}"]},f:["Release"]}],n:50,x:{r:["sheets"],s:"_0>0"},p:[37,6,1597]}]}],n:52,r:"data.circuitmat_list",p:[35,5,1513]}]}," ",{p:[44,4,1895],t:7,e:"tab",a:{name:"Chemicals"},f:[{t:4,f:[{p:[46,6,1961],t:7,e:"ui-section",f:[{t:2,r:"name",p:[46,18,1973]}," : ",{t:2,r:"amount",p:[46,29,1984]}," - ",{p:[47,7,2005],t:7,e:"ui-button",a:{action:"purgechem",params:['{"latheType" : "circuit", "name" : ',{t:2,r:"name",p:[47,80,2078]},', "id" : ',{t:2,r:"reagentid",p:[47,97,2095]},"}"]},f:["Purge"]}]}],n:52,r:"data.circuitchem_list",p:[45,5,1923]}]}]}]}]}],r:"data.circuitbusy"}],n:50,r:"data.circuit_linked",p:[1,1,0]},{t:4,n:51,f:[{p:[55,2,2216],t:7,e:"ui-display",a:{title:"No Linked Circuit Imprinter"}}],r:"data.circuit_linked"}]},e.exports=a.extend(r.exports)},{341:341}],443:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,31],t:7,e:"ui-display",a:{title:[{t:2,r:"data.sdesign_name",p:[2,21,50]}]},f:[{p:[3,3,77],t:7,e:"ui-section",a:{title:"Description"},f:[{t:2,r:"data.sdesign_desc",p:[3,35,109]}]}]}," ",{p:[5,2,162],t:7,e:"ui-display",a:{title:"Lathe Types"},f:[{t:4,f:[{p:[7,4,239],t:7,e:"ui-section",a:{title:"Circuit Imprinter"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&1"},p:[6,3,198]}," ",{t:4,f:[{p:[10,4,346],t:7,e:"ui-section",a:{title:"Protolathe"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&2"},p:[9,3,305]}," ",{t:4,f:[{p:[13,4,446],t:7,e:"ui-section",a:{title:"Autolathe"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&4"},p:[12,3,405]}," ",{t:4,f:[{p:[16,4,545],t:7,e:"ui-section",a:{title:"Crafting Fabricator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&8"},p:[15,3,504]}," ",{t:4,f:[{p:[19,4,655],t:7,e:"ui-section",a:{title:"Exosuit Fabricator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&16"},p:[18,3,613]}," ",{t:4,f:[{p:[22,4,764],t:7,e:"ui-section",a:{title:"Biogenerator"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&32"},p:[21,3,722]}," ",{t:4,f:[{p:[25,4,867],t:7,e:"ui-section",a:{title:"Limb Grower"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&64"},p:[24,3,825]}," ",{t:4,f:[{p:[28,4,970],t:7,e:"ui-section",a:{title:"Ore Smelter"}}],n:50,x:{r:["data.sdesign_buildtype"],s:"_0&128"
+},p:[27,3,927]}]}," ",{p:[31,2,1045],t:7,e:"ui-display",a:{title:"Materials"},f:[{t:4,f:[{p:[33,4,1116],t:7,e:"ui-section",a:{title:[{t:2,r:"matname",p:[33,23,1135]}]},f:[{t:2,r:"matamt",p:[33,36,1148]}," cm^3"]}],n:52,r:"data.sdesign_materials",p:[32,3,1079]}]}],n:50,r:"data.design_selected",p:[1,1,0]},{t:4,f:[{p:[38,2,1248],t:7,e:"ui-display",a:{title:"No Design Selected."}}],n:50,x:{r:["data.design_selected"],s:"!_0"},p:[37,1,1216]}]},e.exports=a.extend(r.exports)},{341:341}],444:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[4,3,60],t:7,e:"ui-display",a:{title:"Destructive Analyzer Busy!"}}],n:50,r:"data.destroybusy",p:[3,2,32]},{t:4,n:51,f:[{t:4,f:[{p:[7,4,168],t:7,e:"ui-display",a:{title:"Destructive Analyzer Unloaded"}}],n:50,x:{r:["data.destroy_loaded"],s:"!_0"},p:[6,3,135]},{t:4,n:51,f:[{p:[9,4,248],t:7,e:"ui-display",a:{title:"Loaded Item"},f:[{p:[10,4,285],t:7,e:"ui-section",a:{title:"Name"},f:[{t:2,r:"data.destroy_name",p:[10,29,310]}]}]}," ",{p:[12,4,367],t:7,e:"ui-display",a:{title:"Boost Nodes"},f:[{t:4,f:[{p:[14,6,438],t:7,e:"ui-section",a:{title:[{t:2,r:"name",p:[14,25,457]}," | ",{t:2,r:"value",p:[14,36,468]}]},f:[{p:[15,7,487],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["allow"],s:'_0?null:"disabled"'},p:[15,25,505]}],action:"deconstruct",params:['{"id":',{t:2,r:"id",p:[15,90,570]},"}"]},f:["Deconstruct and Boost"]}]}],n:52,r:"data.boost_paths",p:[13,5,405]}]}," ",{p:[19,4,670],t:7,e:"ui-button",a:{action:"eject_da"},f:["Eject Item"]}],x:{r:["data.destroy_loaded"],s:"!_0"}}],r:"data.destroybusy"}],n:50,r:"data.destroy_linked",p:[2,1,2]},{t:4,n:51,f:[{p:[23,2,755],t:7,e:"ui-display",a:{title:"No Linked Destructive Analyzer"}}],r:"data.destroy_linked"}]},e.exports=a.extend(r.exports)},{341:341}],445:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[3,2,24],t:7,e:"ui-display",a:{title:"No Design Disk Loaded"}}],n:50,x:{r:["data.ddisk"],s:"!_0"},p:[2,1,2]},{t:4,n:51,f:[{t:4,f:[{p:[6,3,121],t:7,e:"ui-display",a:{title:"Design Disk Updating"}}],n:50,r:"data.ddisk_update",p:[5,2,92]},{t:4,n:51,f:[{t:4,f:[{p:[9,4,221],t:7,e:"ui-display",a:{title:"Design Disk"},f:[{p:[10,5,259],t:7,e:"ui-section",a:{title:"Disk Space"},f:["Disk Capacity: ",{t:2,r:"data.ddisk_size",p:[10,51,305]}," blueprints."]}," ",{p:[11,5,355],t:7,e:"ui-section",a:{title:"Disk IO"},f:[{p:[11,33,383],t:7,e:"ui-button",a:{action:"ddisk_upall"},f:["Upload all designs"]}]}," ",{p:[12,5,464],t:7,e:"ui-section",a:{title:"Clear Disk"},f:[{p:[12,36,495],t:7,e:"ui-button",a:{action:"clear_designdisk",style:"danger"},f:["WIPE ALL DATA"]}]}," ",{p:[13,5,591],t:7,e:"ui-section",a:{title:"Eject Disk"},f:[{p:[13,36,622],t:7,e:"ui-button",a:{action:"eject_designdisk"},f:["Eject Disk"]}]}]}," ",{p:[15,4,717],t:7,e:"ui-display",a:{title:"Disk Contents"},f:[{t:4,f:[{p:[17,6,792],t:7,e:"ui-section",a:{title:"Number"},f:["#",{t:2,r:"pos",p:[17,34,820]},": ",{t:4,f:[{p:[19,8,866],t:7,e:"ui-button",a:{action:"upload_empty_ddisk_slot",params:['{"slot": "',{t:2,r:"pos",p:[19,70,928]},'"}']},f:["Upload to Empty Slot"]}],n:50,x:{r:["id"],s:'_0=="null"'},p:[18,7,837]},{t:4,n:51,f:[{p:[21,8,996],t:7,e:"ui-button",a:{action:"select_design",params:['{"id": "',{t:2,r:"id",p:[21,58,1046]},'"}'],state:[{t:2,x:{r:["data.sdesign_id","id"],s:'_0==_1?"selected":null'},p:[21,75,1063]}]},f:[{t:2,r:"name",p:[21,122,1110]}]}," ",{p:[22,8,1139],t:7,e:"ui-button",a:{action:"ddisk_erasepos",style:"danger",params:['{"id": "',{t:2,r:"id",p:[22,74,1205]},'"}'],state:[{t:2,x:{r:["id"],s:'_0=="null"?"disabled":null'},p:[22,91,1222]}]},f:["Delete Slot"]}],x:{r:["id"],s:'_0=="null"'}}]}],n:52,r:"data.ddisk_designs",p:[16,5,757]}]}],n:50,x:{r:["data.ddisk_upload"],s:"!_0"},p:[8,3,190]},{t:4,n:51,f:[{p:[28,4,1367],t:7,e:"ui-display",a:{title:"Upload Design to Disk"},f:[{p:[28,46,1409],t:7,e:"ui-section",f:["Available Designs:"]}]}," ",{t:4,f:[{p:[30,5,1513],t:7,e:"ui-section",f:[{p:[30,17,1525],t:7,e:"ui-button",a:{action:"ddisk_uploaddesign",params:['{"id": "',{t:2,r:"id",p:[30,72,1580]},'"}']},f:[{t:2,r:"name",p:[30,82,1590]}]}]}],n:52,r:"data.ddisk_possible_designs",p:[29,4,1470]}],x:{r:["data.ddisk_upload"],s:"!_0"}}],r:"data.ddisk_update"}],x:{r:["data.ddisk"],s:"!_0"}}]},e.exports=a.extend(r.exports)},{341:341}],446:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[3,2,24],t:7,e:"ui-display",a:{title:"No Technology Disk Loaded"}}],n:50,x:{r:["data.tdisk"],s:"!_0"},p:[2,1,2]},{t:4,n:51,f:[{t:4,f:[{p:[6,3,125],t:7,e:"ui-display",a:{title:"Technology Disk Updating"}}],n:50,r:"data.tdisk_update",p:[5,2,96]},{t:4,n:51,f:[{p:[8,3,198],t:7,e:"ui-display",a:{title:"Technology Disk"},f:[{p:[9,4,239],t:7,e:"ui-section",a:{title:"Disk IO"},f:[{p:[9,32,267],t:7,e:"ui-button",a:{action:"tdisk_down"},f:["Download Research to Disk"]},{p:[9,100,335],t:7,e:"ui-button",a:{action:"tdisk_up"},f:["Upload Research from Disk"]}," ",{p:[10,4,406],t:7,e:"ui-section",a:{title:"Clear Disk"},f:[{p:[10,35,437],t:7,e:"ui-button",a:{action:"clear_techdisk",style:"danger"},f:["WIPE ALL DATA"]}]}," ",{p:[11,4,530],t:7,e:"ui-section",a:{title:"Eject Disk"},f:[{p:[11,35,561],t:7,e:"ui-button",a:{action:"eject_techdisk"},f:["Eject Disk"]}]}]}]}," ",{p:[13,3,652],t:7,e:"ui-display",a:{title:"Disk Contents"},f:[{t:4,f:[{p:[15,5,723],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[15,53,771]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[15,70,788]}]},f:[{t:2,r:"display_name",p:[15,115,833]}]}],n:52,r:"data.tdisk_nodes",p:[14,4,691]}]}],r:"data.tdisk_update"}],x:{r:["data.tdisk"],s:"!_0"}}]},e.exports=a.extend(r.exports)},{341:341}],447:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,2,29],t:7,e:"ui-display",a:{title:[{t:2,r:"data.snode_name",p:[2,21,48]}]},f:[{p:[3,3,73],t:7,e:"ui-section",a:{title:"Description"},f:["Description: ",{t:2,r:"data.snode_desc",p:[3,48,118]}]}," ",{p:[4,3,154],t:7,e:"ui-section",a:{title:"Point Cost"},f:["Point Cost: ",{t:2,r:"data.snode_cost",p:[4,46,197]}]}," ",{p:[5,3,233],t:7,e:"ui-section",a:{title:"Export Price"},f:["Export Price: ",{t:2,r:"data.snode_export",p:[5,50,280]}]}," ",{p:[6,3,318],t:7,e:"ui-button",a:{action:"research_node",params:['{"id"="',{t:2,r:"id",p:[6,52,367]},'"}'],state:[{t:2,x:{r:["data.snode_researched"],s:'_0?"disabled":null'},p:[6,69,384]}]},f:[{t:2,x:{r:["data.snode_researched"],s:'_0?"Researched":"Research Node"'},p:[6,115,430]}]}]}," ",{p:[8,2,518],t:7,e:"ui-display",a:{title:"Prerequisites"},f:[{t:4,f:[{p:[10,4,588],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[10,52,636]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[10,69,653]}]},f:[{t:2,r:"display_name",p:[10,114,698]}]}],n:52,r:"data.node_prereqs",p:[9,3,556]}]}," ",{p:[13,2,759],t:7,e:"ui-display",a:{title:"Unlocks"},f:[{t:4,f:[{p:[15,4,823],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[15,52,871]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[15,69,888]}]},f:[{t:2,r:"display_name",p:[15,114,933]}]}],n:52,r:"data.node_unlocks",p:[14,3,791]}]}," ",{p:[18,2,994],t:7,e:"ui-display",a:{title:"Designs"},f:[{t:4,f:[{p:[20,4,1058],t:7,e:"ui-button",a:{action:"select_design",params:['{"id": "',{t:2,r:"id",p:[20,54,1108]},'"}'],state:[{t:2,x:{r:["data.sdesign_id","id"],s:'_0==_1?"selected":null'},p:[20,71,1125]}]},f:[{t:2,r:"name",p:[20,118,1172]}]}],n:52,r:"data.node_designs",p:[19,3,1026]}]}],n:50,r:"data.node_selected",p:[1,1,0]},{t:4,f:[{p:[25,2,1263],t:7,e:"ui-display",a:{title:"No Node Selected."}}],n:50,x:{r:["data.node_selected"],s:"!_0"},p:[24,1,1233]}]},e.exports=a.extend(r.exports)},{341:341}],448:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{t:4,f:[{p:[3,3,59],t:7,e:"ui-display",a:{title:"Protolathe Busy!"}}],n:50,r:"data.protobusy",p:[2,2,33]},{t:4,n:51,f:[{p:[5,3,124],t:7,e:"ui-display",f:[{p:[6,4,141],t:7,e:"ui-section",f:["Search Available Designs: ",{p:[7,4,183],t:7,e:"input",a:{value:[{t:2,r:"textsearch",p:[7,17,196]}],placeholder:"Type Here","class":"text"}}," ",{p:[8,5,255],t:7,e:"ui-button",a:{action:"textSearch",params:['{"latheType" : "proto", "inputText" : ',{t:2,r:"textsearch",p:[8,82,332]},"}"]},f:["Search"]}]}," ",{p:[10,4,390],t:7,e:"ui-section",f:["Materials: ",{t:2,r:"data.protomats",p:[10,27,413]}," / ",{t:2,r:"data.protomaxmats",p:[10,48,434]}]}," ",{p:[11,4,473],t:7,e:"ui-section",f:["Reagents: ",{t:2,r:"data.protochems",p:[11,26,495]}," / ",{t:2,r:"data.protomaxchems",p:[11,48,517]}]}," ",{p:[12,3,556],t:7,e:"ui-display",f:[{p:[14,3,574],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.lathe_tabs",p:[14,18,589]}]},f:[{p:[15,4,615],t:7,e:"tab",a:{name:"Category List"},f:[{t:4,f:[{p:[17,6,678],t:7,e:"ui-button",a:{action:"switchcat",state:[{t:2,x:{r:["data.protocat","name"],s:'_0==_1?"selected":null'},p:[17,43,715]}],params:['{"type" : "proto", "cat" : "',{t:2,r:"name",p:[17,125,797]},'"}']},f:[{t:2,r:"name",p:[17,137,809]}]}],n:52,r:"data.protocats",p:[16,5,647]}]}," ",{p:[20,4,860],t:7,e:"tab",a:{name:"Selected Category"},f:[{t:4,f:[{p:[22,6,926],t:7,e:"ui-section",f:[{t:2,r:"name",p:[22,18,938]},{t:2,r:"matstring",p:[22,26,946]}," ",{t:4,f:[{p:[24,8,996],t:7,e:"input",a:{value:[{t:2,r:"number",p:[24,21,1009]}],placeholder:["1-",{t:2,x:{r:["canprint"],s:"_0>10?10:_0"},p:[24,47,1035]}],"class":"number"}}],n:50,x:{r:["canprint"],s:"_0>1"},p:[23,7,967]}," ",{p:[26,7,1108],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[26,40,1141]}],params:['{"latheType" : "proto", "id" : "',{t:2,r:"id",p:[26,117,1218]},'", "amount" : "',{t:2,r:"number",p:[26,138,1239]},'"}']},f:["Print"]}]}],n:52,r:"data.protodes",p:[21,5,896]}]}," ",{p:[30,4,1321],t:7,e:"tab",a:{name:"Search Results"},f:[{t:4,f:[{p:[32,6,1386],t:7,e:"ui-section",f:[{t:2,r:"name",p:[32,18,1398]},{t:2,r:"matstring",p:[32,26,1406]}," ",{t:4,f:[{p:[34,8,1456],t:7,e:"input",a:{value:[{t:2,r:"number",p:[34,21,1469]}],placeholder:["1-",{t:2,x:{r:["canprint"],s:"_0>10?10:_0"},p:[34,47,1495]}],"class":"number"}}],n:50,x:{r:["canprint"],s:"_0>1"},p:[33,7,1427]}," ",{p:[36,7,1568],t:7,e:"ui-button",a:{action:"print",state:[{t:2,x:{r:["canprint"],s:'_0>1?null:"disabled"'},p:[36,40,1601]}],params:['{"latheType" : "proto", "id" : "',{t:2,r:"id",p:[36,117,1678]},'", "amount" : "',{t:2,r:"number",p:[36,138,1699]},'"}']},f:["Print"]}]}],n:52,r:"data.protomatch",p:[31,5,1354]}]}," ",{p:[40,4,1781],t:7,e:"tab",a:{name:"Materials"},f:[{t:4,f:[{p:[42,6,1844],t:7,e:"ui-section",f:[{t:2,r:"name",p:[42,18,1856]}," : ",{t:2,r:"amount",p:[42,29,1867]}," cm3 - ",{t:4,f:[{p:[44,7,1917],t:7,e:"input",a:{value:[{t:2,r:"number",p:[44,20,1930]}],placeholder:["1-",{t:2,r:"sheets",p:[44,46,1956]}],"class":"number"}}," ",{p:[45,7,1992],t:7,e:"ui-button",a:{action:"releasemats",params:['{"latheType" : "proto", "mat_id" : ',{t:2,r:"mat_id",p:[45,82,2067]},', "sheets" : ',{t:2,r:"number",p:[45,105,2090]},"}"]},f:["Release"]}],n:50,x:{r:["sheets"],s:"_0>0"},p:[43,6,1891]}]}],n:52,r:"data.protomat_list",p:[41,5,1809]}]}," ",{p:[50,4,2187],t:7,e:"tab",a:{name:"Chemicals"},f:[{t:4,f:[{p:[52,6,2251],t:7,e:"ui-section",f:[{t:2,r:"name",p:[52,18,2263]}," : ",{t:2,r:"amount",p:[52,29,2274]}," - ",{p:[53,7,2295],t:7,e:"ui-button",a:{action:"purgechem",params:['{"latheType" : "proto", "name" : ',{t:2,r:"name",p:[53,78,2366]},', "id" : ',{t:2,r:"reagentid",p:[53,95,2383]},"}"]},f:["Purge"]}]}],n:52,r:"data.protochem_list",p:[51,5,2215]}]}]}]}]}],r:"data.protobusy"}],n:50,r:"data.protolathe_linked",p:[1,1,0]},{t:4,n:51,f:[{p:[61,2,2504],t:7,e:"ui-display",a:{title:"No Linked Protolathe"}}],r:"data.protolathe_linked"}]},e.exports=a.extend(r.exports)},{341:341}],449:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,1,14],t:7,e:"span",a:{"class":"memoedit"},f:["Nanotrasen R&D Console"]},{p:[2,53,66],t:7,e:"br"}," Available Points: ",{p:[3,19,91],t:7,e:"ui-section",a:{title:"Research Points"},f:[{t:2,r:"data.research_points_stored",p:[3,55,127]}]}," ",{p:[4,1,173],t:7,e:"ui-section",a:{title:["Page Selection - ",{t:2,r:"page",p:[4,37,209]}]},f:[{p:[4,47,219],t:7,e:"input",a:{value:[{t:2,r:"pageselect",p:[4,60,232]}],placeholder:"1","class":"number"}}," Select Page: ",{p:[5,14,294],t:7,e:"ui-button",a:{action:"page",params:['{"num" : "',{t:2,r:"pageselect",p:[5,57,337]},'"}']},f:["[Go]"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],450:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"span",a:{"class":"bad"},f:["Settings"]},{p:[1,34,33],t:7,e:"br"},{p:[1,39,38],t:7,e:"br"}," ",{p:[2,1,45],t:7,e:"ui-button",a:{action:"Resync"},f:["RESYNC MACHINERY"]},{p:[2,56,100],t:7,e:"br"}," ",{p:[3,1,107],t:7,e:"ui-button",a:{action:"Lock"},f:["LOCK"]}," ",{p:[4,1,150],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "destroy"}',state:[{t:2,x:{r:["data.destroy_linked"],s:'_0?null:"disabled"'},p:[4,71,220]}]},f:["Disconnect Destructive Analyzer"]}," ",{p:[5,1,309],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "lathe"}',state:[{t:2,x:{r:["data.protolathe_linked"],s:'_0?null:"disabled"'},p:[5,69,377]}]},f:["Disconnect Protolathe"]}," ",{p:[6,1,459],t:7,e:"ui-button",a:{action:"disconnect",params:'{"type" : "imprinter"}',state:[{t:2,x:{r:["data.circuit_linked"],s:'_0?null:"disabled"'},p:[6,73,531]}]},f:["Disconnect Circuit Imprinter"]}]},e.exports=a.extend(r.exports)},{341:341}],451:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Available for Research"},f:[{t:4,f:[{p:[3,3,78],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[3,51,126]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[3,68,143]}]},f:[{t:2,r:"display_name",p:[3,113,188]}]}],n:52,r:"data.techweb_avail",p:[2,2,46]}]}," ",{p:[6,1,245],t:7,e:"ui-display",a:{title:"Locked Nodes"},f:[{t:4,f:[{p:[8,3,314],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[8,51,362]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[8,68,379]}]},f:[{t:2,r:"display_name",p:[8,113,424]}]}],n:52,r:"data.techweb_locked",p:[7,2,281]}]}," ",{p:[11,1,482],t:7,e:"ui-display",a:{title:"Researched Nodes"},f:[{t:4,f:[{p:[13,3,559],t:7,e:"ui-button",a:{action:"select_node",params:['{"id": "',{t:2,r:"id",p:[13,51,607]},'"}'],state:[{t:2,x:{r:["data.snode_id","id"],s:'_0==_1?"selected":null'},p:[13,68,624]}]},f:[{t:2,r:"display_name",p:[13,113,669]}]}],n:52,r:"data.techweb_researched",p:[12,2,522]}]}]},e.exports=a.extend(r.exports)},{341:341}],452:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,1,25],t:7,e:"ui-notice",f:[{p:[3,3,40],t:7,e:"span",f:["The grinder is currently processing and cannot be used."]}]}],n:50,r:"data.processing",p:[1,1,0]},{p:{button:[{p:[8,5,208],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[8,36,239]}],action:"eject"},f:["Eject Contents"]}]},t:7,e:"ui-display",a:{title:"Processing Chamber",button:0},f:[" ",{p:[10,3,364],t:7,e:"ui-section",a:{label:"Grinding"},f:[{p:[11,5,399],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.operating"],s:'_0?"average":"good"'},p:[11,18,412]}]},f:[{t:2,x:{r:["data.operating"],s:'_0?"Busy":"Ready"'},p:[11,59,453]}]}," ",{p:[12,2,500],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.operating","data.contents"],s:'(_0==0)&&_1?null:"disabled"'},p:[12,35,533]}],action:"grind"},f:["Activate"]}]}," ",{p:[14,3,653],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{t:4,f:[{p:[17,9,755],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:["The ",{t:2,r:"name",p:[17,56,802]}]},{p:[17,71,817],t:7,e:"br"}],n:52,r:"adata.contentslist",p:[16,7,717]},{t:4,n:51,f:[{p:[19,9,848],t:7,e:"span",f:["No Contents"]}],r:"adata.contentslist"}],n:50,r:"data.contents",p:[15,5,688]},{t:4,n:51,f:[{p:[22,7,911],t:7,e:"span",f:["No Contents"]}],r:"data.contents"}]}]}," ",{p:{button:[{p:[28,5,1047],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.operating","data.isBeakerLoaded"],s:'(_0==0)&&_1?null:"disabled"'},p:[28,36,1078]}],action:"detach"},f:["Detach"]}]},t:7,e:"ui-display",a:{title:"Container",button:0},f:[" ",{p:[30,3,1202],t:7,e:"ui-section",a:{label:"Reagents"},f:[{t:4,f:[{p:[32,7,1272],t:7,e:"span",f:[{t:2,x:{r:["adata.beakerCurrentVolume"],s:"Math.round(_0)"},p:[32,13,1278]},"/",{t:2,r:"data.beakerMaxVolume",p:[32,55,1320]}," Units"]}," ",{p:[33,7,1365],t:7,e:"br"}," ",{t:4,f:[{p:[35,9,1418],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[35,52,1461]}," units of ",{t:2,r:"name",p:[35,87,1496]}]},{p:[35,102,1511],t:7,e:"br"}],n:52,r:"adata.beakerContents",p:[34,7,1378]},{t:4,n:51,f:[{p:[37,9,1542],t:7,e:"span",a:{"class":"bad"},f:["Container Empty"]}],r:"adata.beakerContents"}],n:50,r:"data.isBeakerLoaded",p:[31,5,1237]},{t:4,n:51,f:[{p:[40,7,1621],t:7,e:"span",a:{"class":"average"},f:["No Container"]}],r:"data.isBeakerLoaded"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],453:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,105],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,123]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,195]},', "flipped": ',{t:2,r:"flipped",p:[6,42,215]},"}"]},f:[{p:[6,56,229],t:7,e:"span",a:{"class":["pipes32x32 ",{t:2,r:"dir",p:[6,80,253]},"-",{t:2,r:"icon_state",p:[6,88,261]}],title:[{t:2,r:"dir_name",p:[6,111,284]}]}}]}],n:52,r:"previews",p:[4,4,81]}]}],n:52,r:"data.preview_rows",p:[2,2,33]}]}," ",{t:4,f:[{p:[12,2,406],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[14,4,468],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["@key","data.selected_color"],s:'_0==_1?"selected":null'},p:[14,22,486]}],action:"color",params:['{"paint_color": ',{t:2,r:"@key",p:[15,44,583]},"}"]},f:[{t:2,r:"@key",p:[15,55,594]}]}],n:52,r:"data.paint_colors",p:[13,3,436]}]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[11,1,377]},{p:[19,1,654],t:7,e:"ui-display",a:{title:"Utilities"},f:[{p:[20,2,687],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&1?"check-square-o":"square-o"'},p:[20,19,704]}],action:"mode",params:'{"mode": 1}'},f:["Build"]}," ",{p:[22,2,813],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&2?"check-square-o":"square-o"'},p:[22,19,830]}],action:"mode",params:'{"mode": 2}'},f:["Wrench"]}," ",{p:[24,2,940],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&4?"check-square-o":"square-o"'},p:[24,19,957]}],action:"mode",params:'{"mode": 4}'},f:["Destroy"]}," ",{t:4,f:[{p:[27,3,1098],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mode"],s:'_0&8?"check-square-o":"square-o"'},p:[27,20,1115]}],action:"mode",params:'{"mode": 8}'},f:["Paint"]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[26,2,1068]}]}," ",{p:[31,1,1249],t:7,e:"ui-display",a:{title:"Category"},f:[{p:[32,2,1281],t:7,e:"ui-section",f:[{p:[33,3,1297],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==0?"check-square-o":"square-o"'},p:[33,20,1314]}],state:[{t:2,x:{r:["data.category"],s:'_0<=0?"selected":null'},p:[33,83,1377]}],action:"category",params:'{"category": 0}'},f:["Atmospherics"]}," ",{p:[35,3,1496],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==1?"check-square-o":"square-o"'},p:[35,20,1513]}],state:[{t:2,x:{r:["data.category"],s:'_0==1?"selected":null'},p:[35,83,1576]}],action:"category",params:'{"category": 1}'},f:["Disposals"]}," ",{p:[37,3,1692],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.category"],s:'_0==2?"check-square-o":"square-o"'},p:[37,20,1709]}],state:[{t:2,x:{r:["data.category"],s:'_0==2?"selected":null'},p:[37,83,1772]}],action:"category",params:'{"category": 2}'},f:["Transit Tubes"]}]}," ",{t:4,f:[{p:[41,3,1937],t:7,e:"ui-section",a:{label:"Piping Layer"},f:[{p:[42,4,1975],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==1?"selected":null'},p:[42,22,1993]}],action:"piping_layer",params:'{"piping_layer": 1}'},f:["1"]}," ",{p:[44,4,2115],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==2?"selected":null'},p:[44,22,2133]}],action:"piping_layer",params:'{"piping_layer": 2}'},f:["2"]}," ",{p:[46,4,2255],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["data.piping_layer"],s:'_0==3?"selected":null'},p:[46,22,2273]}],action:"piping_layer",params:'{"piping_layer": 3}'},f:["3"]}]}],n:50,x:{r:["data.category"],s:"_0==0"},p:[40,2,1907]}]}," ",{t:4,f:[{p:[52,2,2462],t:7,e:"ui-display",a:{title:[{t:2,r:"cat_name",p:[52,21,2481]}]},f:[{t:4,f:[{p:[54,4,2521],t:7,e:"ui-section",f:[{p:[55,5,2539],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[55,23,2557]}],action:"pipe_type",params:['{"pipe_type": ',{t:2,r:"pipe_index",p:[56,28,2638]},', "category": ',{t:2,r:"cat_name",p:[56,56,2666]},"}"]},f:[{t:2,r:"pipe_name",p:[56,71,2681]}]}]}],n:52,r:"recipes",p:[53,3,2499]}]}],n:52,r:"data.categories",p:[51,1,2434]}]},e.exports=a.extend(r.exports)},{341:341}],454:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Color"},f:[{t:4,f:[{p:[3,3,60],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[3,21,78]}],action:"color",params:['{"paint_color": ',{t:2,r:"color_name",p:[4,28,155]},"}"]},f:[{t:2,r:"color_name",p:[4,45,172]}]}],n:52,r:"data.paint_colors",p:[2,2,29]}]}]},e.exports=a.extend(r.exports)},{341:341}],455:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Direction"},f:[{t:4,f:[{p:[3,3,64],t:7,e:"ui-section",f:[{t:4,f:[{p:[5,5,105],t:7,e:"ui-button",a:{state:[{t:2,x:{r:["selected"],s:'_0?"selected":null'},p:[5,23,123]}],action:"setdir",params:['{"dir": ',{t:2,r:"dir",p:[6,22,195]},', "flipped": ',{t:2,r:"flipped",p:[6,42,215]},"}"]},f:[{p:[6,56,229],t:7,e:"img",a:{src:["pipe.",{t:2,r:"dir",p:[6,71,244]},".",{t:2,r:"icon_state",p:[6,79,252]},".png"],title:[{t:2,r:"dir_name",p:[6,106,279]}]}}]}],n:52,r:"previews",p:[4,4,81]}]}],n:52,r:"data.preview_rows",p:[2,2,33]}]}]},e.exports=a.extend(r.exports)},{341:341}],456:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,23],t:7,e:"ui-notice",f:[{t:2,r:"data.notice",p:[3,5,40]}]}],n:50,r:"data.notice",p:[1,1,0]},{p:[6,1,82],t:7,e:"ui-display",a:{title:"Satellite Network Control",button:0},f:[{t:4,f:[{p:[8,4,168],t:7,e:"ui-section",a:{candystripe:0,nowrap:0},f:[{p:[9,9,209],t:7,e:"div",a:{"class":"content"},f:["#",{t:2,r:"id",p:[9,31,231]}]}," ",{p:[10,9,253],t:7,e:"div",a:{"class":"content"},f:[{t:2,r:"mode",p:[10,30,274]}]}," ",{p:[11,9,298],t:7,e:"div",a:{"class":"content"},f:[{p:[12,11,331],t:7,e:"ui-button",a:{action:"toggle",params:['{"id": "',{t:2,r:"id",p:[12,54,374]},'"}']},f:[{t:2,x:{r:["active"],s:'_0?"Deactivate":"Activate"'},p:[12,64,384]}]}]}]}],n:52,r:"data.satellites",p:[7,2,138]}]}," ",{t:4,f:[{p:[18,1,528],t:7,e:"ui-display",a:{title:"Station Shield Coverage"},f:[{p:[19,3,576],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.meteor_shield_coverage_max",p:[19,24,597]}],value:[{t:2,r:"data.meteor_shield_coverage",p:[19,68,641]}]},f:[{t:2,x:{r:["data.meteor_shield_coverage","data.meteor_shield_coverage_max"],s:"100*_0/_1"},p:[19,101,674]}," %"]}," ",{p:[20,1,758],t:7,e:"ui-display",f:[]}]}],n:50,r:"data.meteor_shield",p:[17,1,500]}]},e.exports=a.extend(r.exports)},{341:341}],457:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,26],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["enabled"],s:'_0?"check-square-o":"square-o"'},p:[2,20,43]}],style:[{t:2,x:{r:["enabled"],s:'_0?"selected":null'},p:[2,72,95]}],action:"toggle_filter",params:['{"id_tag": "',{t:2,r:"id_tag",p:[3,48,176]},'", "val": ',{t:2,r:"gas_id",p:[3,68,196]},"}"]},f:[{t:2,r:"gas_name",p:[3,81,209]}]}],n:52,r:"filter_types",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],458:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[" "," "," ",{p:[5,1,200],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.tabs",p:[5,16,215]}]},f:[{p:[6,2,233],t:7,e:"tab",a:{name:"Status"},f:[{p:[7,3,256],t:7,e:"status"}]}," ",{p:[9,2,277],t:7,e:"tab",a:{name:"Templates"},f:[{p:[10,3,303],t:7,e:"templates"}]}," ",{p:[12,2,327],t:7,e:"tab",a:{name:"Modification"},f:[{t:4,f:[{p:[14,3,381],t:7,e:"modification"}],n:50,r:"data.selected",p:[13,3,356]}," ",{t:4,f:[{p:[17,3,437],t:7,e:"span",a:{"class":"bad"},f:["No shuttle selected."]}],n:50,x:{r:["data.selected"],s:"!_0"},p:[16,3,411]}]}]}]},r.exports.components=r.exports.components||{};var i={modification:t(459),templates:t(461),status:t(460)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{341:341,459:459,460:460,461:461}],459:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:["Selected: ",{t:2,r:"data.selected.name",p:[1,30,29]}]},f:[{t:4,f:[{p:[3,5,96],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"data.selected.description",p:[3,37,128]}]}],n:50,r:"data.selected.description",p:[2,3,57]}," ",{t:4,f:[{p:[6,5,224],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"data.selected.admin_notes",p:[6,37,256]}]}],n:50,r:"data.selected.admin_notes",p:[5,3,185]}]}," ",{t:4,f:[{p:[11,3,361],t:7,e:"ui-display",a:{title:["Existing Shuttle: ",{t:2,r:"data.existing_shuttle.name",p:[11,40,398]}]},f:["Status: ",{t:2,r:"data.existing_shuttle.status",p:[12,13,444]}," ",{t:4,f:["(",{t:2,r:"data.existing_shuttle.timeleft",p:[14,8,526]},")"],n:50,r:"data.existing_shuttle.timer",p:[13,5,482]}," ",{p:[16,5,580],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"data.existing_shuttle.id",p:[17,41,649]},'"}']},f:["Jump To"]}]}],n:50,r:"data.existing_shuttle",p:[10,1,328]},{t:4,f:[{p:[24,3,778],t:7,e:"ui-display",a:{title:"Existing Shuttle: None"}}],n:50,x:{r:["data.existing_shuttle"],s:"!_0"},p:[23,1,744]},{p:[27,1,847],t:7,e:"ui-button",a:{action:"preview",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[28,27,902]},'"}']},f:["Preview"]}," ",{p:[31,1,961],t:7,e:"ui-button",a:{action:"load",params:['{"shuttle_id": "',{t:2,r:"data.selected.shuttle_id",p:[32,27,1013]},'"}'],style:"danger"},f:["Load"]}," ",{p:[37,1,1089],t:7,e:"ui-display",a:{title:"Status"},f:[]}]},e.exports=a.extend(r.exports)},{341:341}],460:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"table",a:{width:"100%"},f:[{t:4,f:[{p:[3,3,49],t:7,e:"tr",f:[{p:[4,5,59],t:7,e:"td",f:[{p:[5,7,71],t:7,e:"ui-button",a:{action:"jump_to",params:['{"type": "mobile", "id": "',{t:2,r:"id",p:[5,69,133]},'"}']},f:["JMP"]}]}," ",{p:[9,5,193],t:7,e:"td",f:[{p:[10,7,205],t:7,e:"ui-button",a:{action:"fly",params:['{"id": "',{t:2,r:"id",p:[10,47,245]},'"}'],state:[{t:2,x:{r:["can_fly"],s:'_0?null:"disabled"'},p:[10,64,262]}]},f:["Fly"]}]}," ",{p:[14,5,345],t:7,e:"td",f:[{t:2,r:"name",p:[15,7,357]}," (",{p:[15,17,367],t:7,e:"code",f:[{t:2,r:"id",p:[15,23,373]}]},")"]}," ",{p:[17,5,404],t:7,e:"td",f:[{t:2,r:"status",p:[18,7,416]}]}," ",{p:[20,5,443],t:7,e:"td",f:[{t:4,f:[{t:2,r:"mode",p:[22,9,477]}],n:50,r:"mode",p:[21,7,455]}," ",{t:4,f:["(",{t:2,r:"timeleft",p:[25,10,532]},") ",{p:[26,9,555],t:7,e:"ui-button",a:{action:"fast_travel",params:['{"id": "',{t:2,r:"id",p:[26,57,603]},'"}'],state:[{t:2,x:{r:["can_fast_travel"],s:'_0?null:"disabled"'},p:[26,74,620]}]},f:["Fast Travel"]}],n:50,r:"timer",p:[24,7,508]}]}]}],n:52,r:"data.shuttles",p:[2,1,22]}]}]},e.exports=a.extend(r.exports)},{341:341}],461:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-tabs",a:{tabs:[{t:2,r:"data.templates_tabs",p:[1,16,15]}]},f:[{t:4,f:[{p:[3,5,74],t:7,e:"tab",a:{name:[{t:2,r:"port_id",p:[3,16,85]}]},f:[{t:4,f:[{p:[5,9,135],t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[5,28,154]}]},f:[{t:4,f:[{p:[7,13,209],t:7,e:"ui-section",a:{label:"Description"},f:[{t:2,r:"description",p:[7,45,241]}]}],n:50,r:"description",p:[6,11,176]}," ",{t:4,f:[{p:[10,13,333],t:7,e:"ui-section",a:{label:"Admin Notes"},f:[{t:2,r:"admin_notes",p:[10,45,365]}]}],n:50,r:"admin_notes",p:[9,11,300]}," ",{p:[13,11,426],t:7,e:"ui-button",a:{action:"select_template",params:['{"shuttle_id": "',{t:2,r:"shuttle_id",p:[14,37,499]},'"}'],state:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"selected":null'},p:[15,20,537]}]},f:[{t:2,x:{r:["data.selected.shuttle_id","shuttle_id"],s:'_0==_1?"Selected":"Select"'},p:[17,13,630]}]}]}],n:52,r:"templates",p:[4,7,106]}]}],n:52,r:"data.templates",p:[2,3,44]}]}]},e.exports=a.extend(r.exports)},{341:341}],462:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Occupant"},f:[{p:[2,3,33],t:7,e:"ui-section",a:{label:"Occupant"},f:[{p:[3,3,66],t:7,e:"span",f:[{t:2,x:{r:["data.occupant.name"],s:'_0?_0:"No Occupant"'},p:[3,9,72]}]}]}," ",{t:4,f:[{p:[6,5,186],t:7,e:"ui-section",a:{label:"State"},f:[{p:[7,7,220],t:7,e:"span",a:{"class":[{t:2,r:"data.occupant.statstate",p:[7,20,233]}]},f:[{t:2,r:"data.occupant.stat",p:[7,49,262]}]}]}," ",{p:[9,5,315],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[10,7,350],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.occupant.minHealth",p:[10,20,363]}],max:[{t:2,r:"data.occupant.maxHealth",p:[10,54,397]}],value:[{t:2,r:"data.occupant.health",p:[10,90,433]}],state:[{t:2,x:{r:["data.occupant.health"],s:'_0>=0?"good":"average"'},p:[11,16,475]}]},f:[{t:2,x:{r:["adata.occupant.health"],s:"Math.round(_0)"},p:[11,68,527]}]}]}," ",{t:4,f:[{p:[14,7,764],t:7,e:"ui-section",a:{label:[{t:2,r:"label",p:[14,26,783]}]},f:[{p:[15,9,804],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.maxHealth",p:[15,30,825]}],value:[{t:2,rx:{r:"data.occupant",m:[{t:30,n:"type"}]},p:[15,66,861]}],state:"bad"},f:[{t:2,x:{r:["type","adata.occupant"],s:"Math.round(_1[_0])"},p:[15,103,898]}]}]}],n:52,x:{r:[],s:'[{label:"Brute",type:"bruteLoss"},{label:"Respiratory",type:"oxyLoss"},{label:"Toxin",type:"toxLoss"},{label:"Burn",type:"fireLoss"}]'},p:[13,5,598]}," ",{t:4,f:[{p:[19,7,1020],t:7,e:"ui-section",a:{label:"Blood"},f:[{p:[20,9,1056],t:7,e:"ui-section",a:{label:"Volume"},f:[{p:[21,11,1095],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.occupant.blood.maxBloodVolume",p:[21,32,1116]}],value:[{t:2,r:"data.occupant.blood.currentBloodVolume",p:[21,79,1163]}],state:[{t:2,x:{r:["data.occupant.blood.currentBloodVolume","data.occupant.blood.dangerBloodVolume"],s:'_0<=_1?"bad":"good"'},p:[21,130,1214]}]},f:[{t:3,x:{r:["data.occupant.blood.currentBloodVolume","data.occupant.blood.dangerBloodVolume"],s:'_0<=_1?"LOW ":"OK"'},p:[21,232,1316]}," - ",{t:2,x:{r:["data.occupant.blood.currentBloodVolume"],s:"Math.round(_0)"},p:[21,342,1426]}," cl"]}]}," ",{p:[23,9,1525],t:7,e:"ui-section",a:{label:"Type"},f:[{p:[24,11,1562],t:7,e:"span",a:{"class":"highlight"},f:[{t:2,r:"data.occupant.blood.bloodType",p:[24,35,1586]}]}]}]}],n:50,r:"data.occupant.blood",p:[18,5,985]}," ",{p:[28,5,1689],t:7,e:"ui-section",a:{label:"Cells"},f:[{p:[29,9,1725],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"bad":"good"'},p:[29,22,1738]}]},f:[{t:2,x:{r:["data.occupant.cloneLoss"],s:'_0?"Damaged":"Healthy"'},p:[29,68,1784]}]}]}," ",{p:[31,5,1867],t:7,e:"ui-section",a:{label:"Brain"},f:[{p:[32,9,1903],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"bad":"good"'},p:[32,22,1916]}]},f:[{t:2,x:{r:["data.occupant.brainLoss"],s:'_0?"Abnormal":"Healthy"'},p:[32,68,1962]}]}]}," ",{p:[34,5,2046],t:7,e:"ui-section",a:{label:"Bloodstream"},f:[{t:4,f:[{p:[36,11,2133],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,1)"},p:[36,54,2176]}," units of ",{t:2,r:"name",p:[36,89,2211]}]},{p:[36,104,2226],t:7,e:"br"
+}],n:52,r:"adata.occupant.reagents",p:[35,9,2088]},{t:4,n:51,f:[{p:[38,11,2261],t:7,e:"span",a:{"class":"good"},f:["Pure"]}],r:"adata.occupant.reagents"}]}],n:50,r:"data.occupied",p:[5,3,159]}]}," ",{p:[43,1,2357],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[44,2,2389],t:7,e:"ui-section",a:{label:"Door"},f:[{p:[45,5,2420],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"unlock":"lock"'},p:[45,22,2437]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Open":"Closed"'},p:[45,71,2486]}]}]}," ",{p:[47,3,2551],t:7,e:"ui-section",a:{label:"Inject"},f:[{t:4,f:[{p:[49,7,2612],t:7,e:"ui-button",a:{icon:"flask",state:[{t:2,x:{r:["data.occupied","allowed"],s:'_0&&_1?null:"disabled"'},p:[49,38,2643]}],action:"inject",params:['{"chem": "',{t:2,r:"id",p:[49,122,2727]},'"}']},f:[{t:2,r:"name",p:[49,132,2737]}]},{p:[49,152,2757],t:7,e:"br"}],n:52,r:"data.chems",p:[48,5,2584]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],463:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,25],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[2,22,44]}],labelcolor:[{t:2,r:"htmlcolor",p:[2,44,66]}],candystripe:0,right:0},f:[{p:[3,5,105],t:7,e:"ui-section",a:{label:"Status"},f:[{p:[3,32,132],t:7,e:"span",a:{"class":[{t:2,x:{r:["status"],s:'_0=="Dead"?"bad bold":_0=="Unconscious"?"average bold":"good"'},p:[3,45,145]}]},f:[{t:2,r:"status",p:[3,132,232]}]}]}," ",{p:[4,5,268],t:7,e:"ui-section",a:{label:"Jelly"},f:[{t:2,r:"exoticblood",p:[4,31,294]}]}," ",{p:[5,5,328],t:7,e:"ui-section",a:{label:"Location"},f:[{t:2,r:"area",p:[5,34,357]}]}," ",{p:[7,5,386],t:7,e:"ui-button",a:{state:[{t:2,r:"swap_button_state",p:[8,14,411]}],action:"swap",params:['{"ref": "',{t:2,r:"ref",p:[9,38,472]},'"}']},f:[{t:4,f:["You Are Here"],n:50,x:{r:["occupied"],s:'_0=="owner"'},p:[10,7,491]},{t:4,n:51,f:[{t:4,f:["Occupied"],n:50,x:{r:["occupied"],s:'_0=="stranger"'},p:[13,9,566]},{t:4,n:51,f:["Swap"],x:{r:["occupied"],s:'_0=="stranger"'}}],x:{r:["occupied"],s:'_0=="owner"'}}]}]}],n:52,r:"data.bodies",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],464:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,23,82],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.drying"],s:'_0?"stop":"tint"'},p:[4,40,99]}],action:"Dry"},f:[{t:2,x:{r:["data.drying"],s:'_0?"Stop drying":"Dry"'},p:[4,88,147]}]}],n:50,r:"data.isdryer",p:[4,3,62]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[7,3,258],t:7,e:"ui-notice",f:[{p:[8,5,275],t:7,e:"span",f:["Unfortunately, this ",{t:2,r:"data.name",p:[8,31,301]}," is empty."]}]}],n:50,x:{r:["data.contents.length"],s:"_0==0"},p:[6,1,221]},{t:4,n:51,f:[{p:[11,1,359],t:7,e:"div",a:{"class":"display tabular"},f:[{p:[12,2,391],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[13,4,425],t:7,e:"section",a:{"class":"cell bold"},f:["Item"]}," ",{p:[16,4,482],t:7,e:"section",a:{"class":"cell bold"},f:["Quantity"]}," ",{p:[19,4,543],t:7,e:"section",a:{"class":"cell bold",align:"center"},f:[{t:4,f:[{t:2,r:"data.verb",p:[20,22,608]}],n:50,r:"data.verb",p:[20,5,591]},{t:4,n:51,f:["Dispense"],r:"data.verb"}]}]}," ",{t:4,f:[{p:[24,3,703],t:7,e:"section",a:{"class":"candystripe"},f:[{p:[25,4,737],t:7,e:"section",a:{"class":"cell"},f:[{t:2,r:"name",p:[26,5,765]}]}," ",{p:[28,4,793],t:7,e:"section",a:{"class":"cell",align:"right"},f:[{t:2,r:"amount",p:[29,5,835]}]}," ",{p:[31,4,865],t:7,e:"section",a:{"class":"table",alight:"right"},f:[{p:[32,5,909],t:7,e:"section",a:{"class":"cell"}}," ",{p:[33,5,947],t:7,e:"section",a:{"class":"cell"},f:[{p:[34,6,976],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>=1)?null:"disabled"'},p:[34,45,1015]}],params:['{ "name" : ',{t:2,r:"name",p:[34,102,1072]},', "amount" : 1 }']},f:["One"]}]}," ",{p:[38,5,1151],t:7,e:"section",a:{"class":"cell"},f:[{p:[39,6,1180],t:7,e:"ui-button",a:{grid:0,action:"Release",state:[{t:2,x:{r:["amount"],s:'(_0>1)?null:"disabled"'},p:[39,45,1219]}],params:['{ "name" : ',{t:2,r:"name",p:[39,101,1275]}," }"]},f:["Many"]}]}]}]}],n:52,r:"data.contents",p:[23,2,676]}]}],x:{r:["data.contents.length"],s:"_0==0"}}]}]},e.exports=a.extend(r.exports)},{341:341}],465:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{capacityPercentState:function(){var t=this.get("data.capacityPercent");return t>50?"good":t>15?"average":"bad"},inputState:function(){return this.get("data.capacityPercent")>=100?"good":this.get("data.inputting")?"average":"bad"},outputState:function(){return this.get("data.outputting")?"good":this.get("data.charge")>0?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[24,1,663],t:7,e:"ui-display",a:{title:"Storage"},f:[{p:[25,3,695],t:7,e:"ui-section",a:{label:"Stored Energy"},f:[{p:[26,5,735],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.capacityPercent",p:[26,38,768]}],state:[{t:2,r:"capacityPercentState",p:[26,71,801]}]},f:[{t:2,x:{r:["adata.capacityPercent"],s:"Math.fixed(_0)"},p:[26,97,827]},"%"]}]}]}," ",{p:[29,1,908],t:7,e:"ui-display",a:{title:"Input"},f:[{p:[30,3,938],t:7,e:"ui-section",a:{label:"Charge Mode"},f:[{p:[31,5,976],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"refresh":"close"'},p:[31,22,993]}],style:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"selected":null'},p:[31,74,1045]}],action:"tryinput"},f:[{t:2,x:{r:["data.inputAttempt"],s:'_0?"Auto":"Off"'},p:[32,25,1113]}]}," [",{p:[34,6,1182],t:7,e:"span",a:{"class":[{t:2,r:"inputState",p:[34,19,1195]}]},f:[{t:2,x:{r:["data.capacityPercent","data.inputting"],s:'_0>=100?"Fully Charged":_1?"Charging":"Not Charging"'},p:[34,35,1211]}]},"]"]}," ",{p:[36,3,1335],t:7,e:"ui-section",a:{label:"Target Input"},f:[{p:[37,5,1374],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.inputLevelMax",p:[37,26,1395]}],value:[{t:2,r:"data.inputLevel",p:[37,57,1426]}]},f:[{t:2,r:"adata.inputLevel_text",p:[37,78,1447]}]}]}," ",{p:[39,3,1501],t:7,e:"ui-section",a:{label:"Adjust Input"},f:[{p:[40,5,1540],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[40,44,1579]}],action:"input",params:'{"target": "min"}'}}," ",{p:[41,5,1674],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.inputLevel"],s:'_0==0?"disabled":null'},p:[41,39,1708]}],action:"input",params:'{"adjust": -10000}'}}," ",{p:[42,5,1804],t:7,e:"ui-button",a:{icon:"pencil",action:"input",params:'{"target": "input"}'},f:["Set"]}," ",{p:[43,5,1894],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[43,38,1927]}],action:"input",params:'{"adjust": 10000}'}}," ",{p:[44,5,2039],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.inputLevel","data.inputLevelMax"],s:'_0==_1?"disabled":null'},p:[44,43,2077]}],action:"input",params:'{"target": "max"}'}}]}," ",{p:[46,3,2204],t:7,e:"ui-section",a:{label:"Available"},f:[{p:[47,3,2238],t:7,e:"span",f:[{t:2,r:"adata.inputAvailable",p:[47,9,2244]}]}]}]}," ",{p:[50,1,2308],t:7,e:"ui-display",a:{title:"Output"},f:[{p:[51,3,2339],t:7,e:"ui-section",a:{label:"Output Mode"},f:[{p:[52,5,2377],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"power-off":"close"'},p:[52,22,2394]}],style:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"selected":null'},p:[52,77,2449]}],action:"tryoutput"},f:[{t:2,x:{r:["data.outputAttempt"],s:'_0?"On":"Off"'},p:[53,26,2519]}]}," [",{p:[55,6,2587],t:7,e:"span",a:{"class":[{t:2,r:"outputState",p:[55,19,2600]}]},f:[{t:2,x:{r:["data.outputting","data.charge"],s:'_0?"Sending":_1>0?"Not Sending":"No Charge"'},p:[55,36,2617]}]},"]"]}," ",{p:[57,3,2724],t:7,e:"ui-section",a:{label:"Target Output"},f:[{p:[58,5,2764],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"data.outputLevelMax",p:[58,26,2785]}],value:[{t:2,r:"data.outputLevel",p:[58,58,2817]}]},f:[{t:2,r:"adata.outputLevel_text",p:[58,80,2839]}]}]}," ",{p:[60,3,2894],t:7,e:"ui-section",a:{label:"Adjust Output"},f:[{p:[61,5,2934],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[61,44,2973]}],action:"output",params:'{"target": "min"}'}}," ",{p:[62,5,3070],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.outputLevel"],s:'_0==0?"disabled":null'},p:[62,39,3104]}],action:"output",params:'{"adjust": -10000}'}}," ",{p:[63,5,3202],t:7,e:"ui-button",a:{icon:"pencil",action:"output",params:'{"target": "input"}'},f:["Set"]}," ",{p:[64,5,3293],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[64,38,3326]}],action:"output",params:'{"adjust": 10000}'}}," ",{p:[65,5,3441],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.outputLevel","data.outputLevelMax"],s:'_0==_1?"disabled":null'},p:[65,43,3479]}],action:"output",params:'{"target": "max"}'}}]}," ",{p:[67,3,3609],t:7,e:"ui-section",a:{label:"Outputting"},f:[{p:[68,3,3644],t:7,e:"span",f:[{t:2,r:"adata.outputUsed",p:[68,9,3650]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],466:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:["\ufeff",{t:4,f:[" ",{p:[2,2,33],t:7,e:"ui-display",a:{title:"Dispersal Tank"},f:[{p:[3,3,73],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[4,4,104],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.active"],s:'_0?"power-off":"close"'},p:[4,21,121]}],style:[{t:2,x:{r:["data.active"],s:'_0?"selected":null'},p:[5,12,174]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[6,12,223]}],action:"power"},f:[{t:2,x:{r:["data.active"],s:'_0?"On":"Off"'},p:[7,20,286]}]}]}," ",{p:[10,3,354],t:7,e:"ui-section",a:{label:"Smoke Radius Setting"},f:[{p:[11,5,401],t:7,e:"div",a:{"class":"content",style:"float:left"},f:[{p:[12,6,448],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=1?null:"disabled"'},p:[12,36,478]}],style:[{t:2,x:{r:["data.setting"],s:'_0==1?"selected":null'},p:[12,89,531]}],action:"setting",params:'{"amount": 1}'},f:["3"]}," ",{p:[13,6,634],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=2?null:"disabled"'},p:[13,36,664]}],style:[{t:2,x:{r:["data.setting"],s:'_0==2?"selected":null'},p:[13,89,717]}],action:"setting",params:'{"amount": 2}'},f:["6"]}," ",{p:[14,6,820],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=3?null:"disabled"'},p:[14,36,850]}],style:[{t:2,x:{r:["data.setting"],s:'_0==3?"selected":null'},p:[14,89,903]}],action:"setting",params:'{"amount": 3}'},f:["9"]}," ",{p:[15,6,1006],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=4?null:"disabled"'},p:[15,36,1036]}],style:[{t:2,x:{r:["data.setting"],s:'_0==4?"selected":null'},p:[15,89,1089]}],action:"setting",params:'{"amount": 4}'},f:["12"]}," ",{p:[16,6,1193],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.maxSetting"],s:'_0>=5?null:"disabled"'},p:[16,36,1223]}],style:[{t:2,x:{r:["data.setting"],s:'_0==5?"selected":null'},p:[16,89,1276]}],action:"setting",params:'{"amount": 5}'},f:["15"]}]}]}," ",{p:[19,3,1410],t:7,e:"ui-section",a:{label:"Contents"},f:[{t:4,f:[{p:[21,6,1476],t:7,e:"span",f:[{t:2,x:{r:["adata.TankCurrentVolume"],s:"Math.round(_0)"},p:[21,12,1482]},"/",{t:2,r:"data.TankMaxVolume",p:[21,52,1522]}," Units"]}," ",{p:[22,6,1564],t:7,e:"br"}," ",{p:[23,5,1575],t:7,e:"br"}," ",{t:4,f:[{p:[25,7,1623],t:7,e:"span",a:{"class":"highlight"},t0:"fade",f:[{t:2,x:{r:["volume"],s:"Math.fixed(_0,2)"},p:[25,50,1666]}," units of ",{t:2,r:"name",p:[25,85,1701]}]},{p:[25,100,1716],t:7,e:"br"}],n:52,r:"adata.TankContents",p:[24,6,1587]}],n:50,r:"data.isTankLoaded",p:[20,4,1444]},{t:4,n:51,f:[{p:[28,6,1757],t:7,e:"span",a:{"class":"bad"},f:["Tank Empty"]}],r:"data.isTankLoaded"}," ",{p:[30,4,1809],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Eject":"Close"'},p:[30,21,1826]}],style:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"selected":null'},p:[31,12,1881]}],state:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?null:"disabled"'},p:[32,12,1936]}],action:"purge"},f:[{t:2,x:{r:["data.isTankLoaded"],s:'_0?"Purge Contents":"No chemicals detected"'},p:[33,20,1999]}]}]}]}],n:50,x:{r:["data.screen"],s:'_0=="home"'},p:[1,2,1]}]},e.exports=a.extend(r.exports)},{341:341}],467:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,3,31],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{t:2,x:{r:["adata.generated"],s:"Math.round(_0)"},p:[3,5,73]},"W"]}," ",{p:[5,3,126],t:7,e:"ui-section",a:{label:"Orientation"},f:[{p:[6,5,164],t:7,e:"span",f:[{t:2,x:{r:["adata.angle"],s:"Math.round(_0)"},p:[6,11,170]},"° (",{t:2,r:"data.direction",p:[6,45,204]},")"]}]}," ",{p:[8,3,251],t:7,e:"ui-section",a:{label:"Adjust Angle"},f:[{p:[9,5,290],t:7,e:"ui-button",a:{icon:"step-backward",action:"angle",params:'{"adjust": -15}'},f:["15°"]}," ",{p:[10,5,387],t:7,e:"ui-button",a:{icon:"backward",action:"angle",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[11,5,477],t:7,e:"ui-button",a:{icon:"forward",action:"angle",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[12,5,565],t:7,e:"ui-button",a:{icon:"step-forward",action:"angle",params:'{"adjust": 15}'},f:["15°"]}]}]}," ",{p:[15,1,687],t:7,e:"ui-display",a:{title:"Tracking"},f:[{p:[16,3,720],t:7,e:"ui-section",a:{label:"Tracker Mode"},f:[{p:[17,5,759],t:7,e:"ui-button",a:{icon:"close",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==0?"selected":null'},p:[17,36,790]}],action:"tracking",params:'{"mode": 0}'},f:["Off"]}," ",{p:[19,5,907],t:7,e:"ui-button",a:{icon:"clock-o",state:[{t:2,x:{r:["data.tracking_state"],s:'_0==1?"selected":null'},p:[19,38,940]}],action:"tracking",params:'{"mode": 1}'},f:["Timed"]}," ",{p:[21,5,1059],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.connected_tracker","data.tracking_state"],s:'_0?_1==2?"selected":null:"disabled"'},p:[21,38,1092]}],action:"tracking",params:'{"mode": 2}'},f:["Auto"]}]}," ",{p:[24,3,1262],t:7,e:"ui-section",a:{label:"Tracking Rate"},f:[{p:[25,3,1300],t:7,e:"span",f:[{t:2,x:{r:["adata.tracking_rate"],s:"Math.round(_0)"},p:[25,9,1306]},"°/h (",{t:2,r:"data.rotating_way",p:[25,53,1350]},")"]}]}," ",{p:[27,3,1399],t:7,e:"ui-section",a:{label:"Adjust Rate"},f:[{p:[28,5,1437],t:7,e:"ui-button",a:{icon:"fast-backward",action:"rate",params:'{"adjust": -180}'},f:["180°"]}," ",{p:[29,5,1535],t:7,e:"ui-button",a:{icon:"step-backward",action:"rate",params:'{"adjust": -30}'},f:["30°"]}," ",{p:[30,5,1631],t:7,e:"ui-button",a:{icon:"backward",action:"rate",params:'{"adjust": -5}'},f:["5°"]}," ",{p:[31,5,1720],t:7,e:"ui-button",a:{icon:"forward",action:"rate",params:'{"adjust": 5}'},f:["5°"]}," ",{p:[32,5,1807],t:7,e:"ui-button",a:{icon:"step-forward",action:"rate",params:'{"adjust": 30}'},f:["30°"]}," ",{p:[33,5,1901],t:7,e:"ui-button",a:{icon:"fast-forward",action:"rate",params:'{"adjust": 180}'},f:["180°"]}]}]}," ",{p:{button:[{p:[38,5,2088],t:7,e:"ui-button",a:{icon:"refresh",action:"refresh"},f:["Refresh"]}]},t:7,e:"ui-display",a:{title:"Devices",button:0},f:[" ",{p:[40,2,2169],t:7,e:"ui-section",a:{label:"Solar Tracker"},f:[{p:[41,5,2209],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_tracker"],s:'_0?"good":"bad"'},p:[41,18,2222]}]},f:[{t:2,x:{r:["data.connected_tracker"],s:'_0?"":"Not "'},p:[41,63,2267]},"Found"]}]}," ",{p:[43,2,2338],t:7,e:"ui-section",a:{label:"Solar Panels"},f:[{p:[44,3,2375],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.connected_panels"],s:'_0?"good":"bad"'},p:[44,16,2388]}]},f:[{t:2,x:{r:["adata.connected_panels"],s:"Math.round(_0)"},p:[44,60,2432]}," Panels Connected"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],468:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:{button:[{t:4,f:[{p:[4,7,87],t:7,e:"ui-button",a:{icon:"eject",state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[4,38,118]}],action:"eject"},f:["Eject"]}],n:50,r:"data.open",p:[3,5,62]}]},t:7,e:"ui-display",a:{title:"Power",button:0},f:[" ",{p:[7,3,226],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[8,5,258],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[8,22,275]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[9,14,326]}],state:[{t:2,x:{r:["data.hasPowercell"],s:'_0?null:"disabled"'},p:[9,54,366]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[10,22,431]}]}]}," ",{p:[12,3,490],t:7,e:"ui-section",a:{label:"Cell"},f:[{t:4,f:[{p:[14,7,554],t:7,e:"ui-bar",a:{min:"0",max:"100",value:[{t:2,r:"data.powerLevel",p:[14,40,587]}]},f:[{t:2,x:{r:["adata.powerLevel"],s:"Math.fixed(_0)"},p:[14,61,608]},"%"]}],n:50,r:"data.hasPowercell",p:[13,5,521]},{t:4,n:51,f:[{p:[16,4,667],t:7,e:"span",a:{"class":"bad"},f:["No Cell"]}],r:"data.hasPowercell"}]}]}," ",{p:[20,1,744],t:7,e:"ui-display",a:{title:"Thermostat"},f:[{p:[21,3,779],t:7,e:"ui-section",a:{label:"Current Temperature"},f:[{p:[22,3,823],t:7,e:"span",f:[{t:2,x:{r:["adata.currentTemp"],s:"Math.round(_0)"},p:[22,9,829]},"°C"]}]}," ",{p:[24,2,894],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[25,3,937],t:7,e:"span",f:[{t:2,x:{r:["adata.targetTemp"],s:"Math.round(_0)"},p:[25,9,943]},"°C"]}]}," ",{t:4,f:[{p:[28,5,1031],t:7,e:"ui-section",a:{label:"Adjust Target"},f:[{p:[29,7,1073],t:7,e:"ui-button",a:{icon:"fast-backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[29,46,1112]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[30,7,1218],t:7,e:"ui-button",a:{icon:"backward",state:[{t:2,x:{r:["data.targetTemp","data.minTemp"],s:'_0>_1?null:"disabled"'},p:[30,41,1252]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[31,7,1357],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:["Set"]}," ",{p:[32,7,1450],t:7,e:"ui-button",a:{icon:"forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[32,40,1483]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[33,7,1587],t:7,e:"ui-button",a:{icon:"fast-forward",state:[{t:2,x:{r:["data.targetTemp","data.maxTemp"],s:'_0<_1?null:"disabled"'},p:[33,45,1625]}],action:"target",params:'{"adjust": 20}'}}]}],n:50,r:"data.open",p:[27,3,1008]}," ",{p:[36,3,1754],t:7,e:"ui-section",a:{label:"Mode"},f:[{t:4,f:[{p:[38,7,1808],t:7,e:"ui-button",a:{icon:"long-arrow-up",state:[{t:2,x:{r:["data.mode"],s:'_0=="heat"?"selected":null'},p:[38,46,1847]}],action:"mode",params:'{"mode": "heat"}'},f:["Heat"]}," ",{p:[39,7,1956],t:7,e:"ui-button",a:{icon:"long-arrow-down",state:[{t:2,x:{r:["data.mode"],s:'_0=="cool"?"selected":null'},p:[39,48,1997]}],action:"mode",params:'{"mode": "cool"}'},f:["Cool"]}," ",{p:[40,7,2106],t:7,e:"ui-button",a:{icon:"arrows-v",state:[{t:2,x:{r:["data.mode"],s:'_0=="auto"?"selected":null'},p:[40,41,2140]}],action:"mode",params:'{"mode": "auto"}'},f:["Auto"]}],n:50,r:"data.open",p:[37,3,1783]},{t:4,n:51,f:[{p:[42,4,2258],t:7,e:"span",f:[{t:2,x:{r:["text","data.mode"],s:"_0.titleCase(_1)"},p:[42,10,2264]}]}],r:"data.open"}]}]}]},e.exports=a.extend(r.exports)},{341:341}],469:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:{button:[{p:[4,8,97],t:7,e:"ui-button",a:{action:"jump",params:['{"name" : ',{t:2,r:"name",p:[4,51,140]},"}"]},f:["Jump"]}," ",{p:[7,9,195],t:7,e:"ui-button",a:{action:"spawn",params:['{"name" : ',{t:2,r:"name",p:[7,53,239]},"}"]},f:["Spawn"]}]},t:7,e:"ui-display",a:{title:[{t:2,r:"name",p:[2,22,46]}],button:0},f:[" ",{p:[11,3,308],t:7,e:"ui-section",a:{label:"Description"},f:[{p:[12,5,346],t:7,e:"span",f:[{t:3,r:"desc",p:[12,11,352]}]}]}," ",{p:[14,3,390],t:7,e:"ui-section",a:{label:"Spawners left"},f:[{p:[15,5,430],t:7,e:"span",f:[{t:2,r:"amount_left",p:[15,11,436]}]}]}]}],n:52,r:"data.spawners",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],470:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,31],t:7,e:"ui-display",a:{title:[{t:2,r:"class",p:[2,22,50]}," Alarms"]},f:[{p:[3,5,74],t:7,e:"ul",f:[{t:4,f:[{p:[5,9,107],t:7,e:"li",f:[{t:2,r:".",p:[5,13,111]}]}],n:52,r:".",p:[4,7,86]},{t:4,n:51,f:[{p:[7,9,147],t:7,e:"li",f:["System Nominal"]}],r:"."}]}]}],n:52,i:"class",r:"data.alarms",p:[1,1,0]}]},e.exports=a.extend(r.exports)},{341:341}],471:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{t:4,f:[{p:[2,3,42],t:7,e:"ui-notice",f:[{p:[3,5,59],t:7,e:"span",f:["Biological entity detected in contents. Please remove."]}]}],n:50,x:{r:["data.occupied","data.safeties"],s:"_0&&_1"},p:[1,1,0]},{t:4,f:[{p:[7,3,179],t:7,e:"ui-notice",f:[{p:[8,5,196],t:7,e:"span",f:["Contents are being disinfected. Please wait."]}]}],n:50,r:"data.uv_active",p:[6,1,153]},{t:4,n:51,f:[{p:{button:[{t:4,f:[{p:[13,25,369],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.locked"],s:'_0?"unlock":"lock"'},p:[13,42,386]}],action:"lock"},f:[{t:2,x:{r:["data.locked"],s:'_0?"Unlock":"Lock"'},p:[13,93,437]}]}],n:50,x:{r:["data.open"],s:"!_0"},p:[13,7,351]}," ",{t:4,f:[{p:[14,27,519],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.open"],s:'_0?"sign-out":"sign-in"'},p:[14,44,536]}],action:"door"},f:[{t:2,x:{r:["data.open"],s:'_0?"Close":"Open"'},p:[14,98,590]}]}],n:50,x:{r:["data.locked"],s:"!_0"},p:[14,7,499]}]},t:7,e:"ui-display",a:{title:"Storage",button:0},f:[" ",{t:4,f:[{p:[17,7,692],t:7,e:"ui-notice",f:[{p:[18,9,713],t:7,e:"span",f:["Unit Locked"]}]}],n:50,r:"data.locked",p:[16,5,665]},{t:4,n:51,f:[{t:4,n:50,x:{r:["data.open"],s:"_0"},f:[{p:[21,9,793],t:7,e:"ui-section",a:{label:"Helmet"},f:[{p:[22,11,832],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.helmet"],s:'_0?"square":"square-o"'},p:[22,28,849]}],state:[{t:2,x:{r:["data.helmet"],s:'_0?null:"disabled"'},p:[22,75,896]}],action:"dispense",params:'{"item": "helmet"}'},f:[{t:2,x:{r:["data.helmet"],s:'_0||"Empty"'},p:[23,59,992]}]}]}," ",{p:[25,9,1063],t:7,e:"ui-section",a:{label:"Suit"},f:[{p:[26,11,1100],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.suit"],s:'_0?"square":"square-o"'},p:[26,28,1117]}],state:[{t:2,x:{r:["data.suit"],s:'_0?null:"disabled"'},p:[26,74,1163]}],action:"dispense",params:'{"item": "suit"}'},f:[{t:2,x:{r:["data.suit"],s:'_0||"Empty"'},p:[27,57,1255]}]}]}," ",{p:[29,9,1324],t:7,e:"ui-section",a:{label:"Mask"},f:[{p:[30,11,1361],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.mask"],s:'_0?"square":"square-o"'},p:[30,28,1378]}],state:[{t:2,x:{r:["data.mask"],s:'_0?null:"disabled"'},p:[30,74,1424]}],action:"dispense",params:'{"item": "mask"}'},f:[{t:2,x:{r:["data.mask"],s:'_0||"Empty"'},p:[31,57,1516]}]}]}," ",{p:[33,9,1585],t:7,e:"ui-section",a:{label:"Storage"},f:[{p:[34,11,1625],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.storage"],s:'_0?"square":"square-o"'},p:[34,28,1642]}],state:[{t:2,x:{r:["data.storage"],s:'_0?null:"disabled"'},p:[34,77,1691]}],action:"dispense",params:'{"item": "storage"}'},f:[{t:2,x:{r:["data.storage"],s:'_0||"Empty"'},p:[35,60,1789]}]}]}]},{t:4,n:50,x:{r:["data.open"],s:"!(_0)"},f:[" ",{p:[38,7,1873],t:7,e:"ui-button",a:{icon:"recycle",state:[{t:2,x:{r:["data.occupied","data.safeties"],s:'_0&&_1?"disabled":null'},p:[38,40,1906]}],action:"uv"},f:["Disinfect"]}]}],r:"data.locked"}]}],r:"data.uv_active"}]},e.exports=a.extend(r.exports)},{341:341}],472:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{p:[2,5,18],t:7,e:"ui-section",a:{label:"Dispense"},f:[{p:[3,9,57],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.plasma"],s:'_0?"square":"square-o"'},p:[3,26,74]}],state:[{t:2,x:{r:["data.plasma"],s:'_0?null:"disabled"'},p:[3,74,122]}],action:"plasma"},f:["Plasma (",{t:2,x:{r:["adata.plasma"],s:"Math.round(_0)"},p:[4,37,196]},")"]}," ",{p:[5,9,247],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.oxygen"],s:'_0?"square":"square-o"'},p:[5,26,264]}],state:[{t:2,x:{r:["data.oxygen"],s:'_0?null:"disabled"'},p:[5,74,312]}],action:"oxygen"},f:["Oxygen (",{t:2,x:{r:["adata.oxygen"],s:"Math.round(_0)"},p:[6,37,386]},")"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],473:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={computed:{tankPressureState:function(){var t=this.get("data.tankPressure");return t>=200?"good":t>=100?"average":"bad"}}}}(r),r.exports.template={v:3,t:[" ",{p:[14,1,295],t:7,e:"ui-notice",f:[{p:[15,3,310],t:7,e:"span",f:["The regulator ",{t:2,x:{r:["data.connected"],s:'_0?"is":"is not"'},p:[15,23,330]}," connected to a mask."]}]}," ",{p:[17,1,409],t:7,e:"ui-display",f:[{p:[18,3,425],t:7,e:"ui-section",a:{label:"Tank Pressure"},f:[{p:[19,7,467],t:7,e:"ui-bar",a:{min:"0",max:"1013",value:[{t:2,r:"data.tankPressure",p:[19,41,501]}],state:[{t:2,r:"tankPressureState",p:[20,16,540]}]},f:[{t:2,x:{r:["adata.tankPressure"],s:"Math.round(_0)"},p:[20,39,563]}," kPa"]}]}," ",{p:[22,3,631],t:7,e:"ui-section",a:{label:"Release Pressure"},f:[{p:[23,5,674],t:7,e:"ui-bar",a:{min:[{t:2,r:"data.minReleasePressure",p:[23,18,687]}],max:[{t:2,r:"data.maxReleasePressure",p:[23,52,721]}],value:[{t:2,r:"data.releasePressure",p:[24,14,764]}]},f:[{t:2,x:{r:["adata.releasePressure"],s:"Math.round(_0)"},p:[24,40,790]}," kPa"]}]}," ",{p:[26,3,861],t:7,e:"ui-section",a:{label:"Pressure Regulator"},f:[{p:[27,5,906],t:7,e:"ui-button",a:{icon:"refresh",state:[{t:2,x:{r:["data.releasePressure","data.defaultReleasePressure"],s:'_0!=_1?null:"disabled"'},p:[27,38,939]}],action:"pressure",params:'{"pressure": "reset"}'},f:["Reset"]}," ",{p:[29,5,1095],t:7,e:"ui-button",a:{icon:"minus",state:[{t:2,x:{r:["data.releasePressure","data.minReleasePressure"],s:'_0>_1?null:"disabled"'},p:[29,36,1126]}],action:"pressure",params:'{"pressure": "min"}'},f:["Min"]}," ",{p:[31,5,1273],t:7,e:"ui-button",a:{icon:"pencil",action:"pressure",params:'{"pressure": "input"}'},f:["Set"]}," ",{p:[32,5,1368],t:7,e:"ui-button",a:{icon:"plus",state:[{t:2,x:{r:["data.releasePressure","data.maxReleasePressure"],s:'_0<_1?null:"disabled"'},p:[32,35,1398]}],action:"pressure",params:'{"pressure": "max"}'},f:["Max"]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],474:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[2,5,33],t:7,e:"ui-section",a:{label:"Temperature"},f:[{p:[3,9,75],t:7,e:"span",f:[{t:2,x:{r:["adata.temperature"],s:"Math.fixed(_0,2)"},p:[3,15,81]}," K"]}]}," ",{p:[5,5,151],t:7,e:"ui-section",a:{label:"Pressure"},f:[{p:[6,9,190],t:7,e:"span",f:[{t:2,x:{r:["adata.pressure"],s:"Math.fixed(_0,2)"},p:[6,15,196]}," kPa"]}]}]}," ",{p:[9,1,276],t:7,e:"ui-display",a:{title:"Controls"},f:[{p:[10,5,311],t:7,e:"ui-section",a:{label:"Power"},f:[{p:[11,9,347],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.on"],s:'_0?"power-off":"close"'},p:[11,26,364]}],style:[{t:2,x:{r:["data.on"],s:'_0?"selected":null'},p:[11,70,408]}],action:"power"},f:[{t:2,x:{r:["data.on"],s:'_0?"On":"Off"'},p:[12,28,469]}]}]}," ",{p:[14,5,531],t:7,e:"ui-section",a:{label:"Target Temperature"},f:[{p:[15,9,580],t:7,e:"ui-button",a:{icon:"fast-backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[15,48,619]}],action:"target",params:'{"adjust": -20}'}}," ",{p:[17,9,733],t:7,e:"ui-button",a:{icon:"backward",style:[{t:2,x:{r:["data.target","data.min"],s:'_0==_1?"disabled":null'},p:[17,43,767]}],action:"target",params:'{"adjust": -5}'}}," ",{p:[19,9,880],t:7,e:"ui-button",a:{icon:"pencil",action:"target",params:'{"target": "input"}'},f:[{t:2,x:{r:["adata.target"],s:"Math.fixed(_0,2)"},p:[19,79,950]}]}," ",{p:[20,9,1003],t:7,e:"ui-button",a:{icon:"forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[20,42,1036]}],action:"target",params:'{"adjust": 5}'}}," ",{p:[22,9,1148],t:7,e:"ui-button",a:{icon:"fast-forward",style:[{t:2,x:{r:["data.target","data.max"],s:'_0==_1?"disabled":null'},p:[22,47,1186]}],action:"target",params:'{"adjust": 20}'}}]}]}]},e.exports=a.extend(r.exports)},{341:341}],475:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{powerState:function(t){switch(t){case 1:return"good";default:return"bad"}}}}}(r),r.exports.template={v:3,t:[" ",{p:[13,1,173],t:7,e:"ui-notice",f:[{p:[14,2,187],t:7,e:"ui-section",a:{label:"Reconnect"},f:[{p:[15,3,221],t:7,e:"div",a:{style:"float:right"},f:[{p:[16,4,251],t:7,e:"ui-button",a:{icon:"refresh",action:"reconnect"},f:["Reconnect"]}]}]}]}," ",{p:[20,1,359],t:7,e:"ui-display",a:{title:"Turbine Controller"},f:[{p:[21,2,401],t:7,e:"ui-section",a:{label:"Status"},f:[{t:4,f:[{p:[23,4,456],t:7,e:"span",a:{"class":"bad"},f:["Broken"]}],n:50,r:"data.broken",p:[22,3,432]},{t:4,n:51,f:[{p:[25,4,504],t:7,e:"span",a:{"class":[{t:2,x:{r:["powerState","data.online"],s:"_0(_1)"},p:[25,17,517]}]},f:[{t:2,x:{r:["data.online","data.compressor_broke","data.turbine_broke"],s:'_0&&!(_1||_2)?"Online":"Offline"'},p:[25,46,546]}]}],r:"data.broken"}," ",{p:[27,3,656],t:7,e:"div",a:{style:"float:right"},f:[{p:[28,4,686],t:7,e:"ui-button",a:{icon:"power-off",action:"power-on",state:[{t:2,r:"data.broken",p:[28,57,739]}],style:[{t:2,x:{r:["data.online"],s:'_0?"selected":""'},p:[28,81,763]}]},f:["On"]}," ",{p:[29,4,817],t:7,e:"ui-button",a:{icon:"close",action:"power-off",state:[{t:2,r:"data.broken",p:[29,54,867]}],style:[{t:2,x:{r:["data.online"],s:'_0?"":"selected"'},p:[29,78,891]}]},f:["Off"]}]}," ",{t:4,f:[{p:[32,4,989],t:7,e:"br"}," [ ",{p:[33,6,1e3],t:7,e:"span",a:{"class":"bad"},f:["Compressor is inoperable"]}," ]"],n:50,r:"data.compressor_broke",p:[31,3,955]}," ",{t:4,f:[{p:[36,4,1097],t:7,e:"br"}," [ ",{p:[37,6,1108],t:7,e:"span",a:{"class":"bad"},f:["Turbine is inoperable"]}," ]"],n:50,r:"data.turbine_broke",p:[35,3,1066]}]}]}," ",{p:[41,1,1200],t:7,e:"ui-display",a:{title:"Status"},f:[{p:[42,2,1230],t:7,e:"ui-section",a:{label:"Turbine Speed"},f:[{p:[43,3,1268],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.rpm"],s:'_0?"--":_1'},p:[43,9,1274]}," RPM"]}]}," ",{p:[45,2,1337],t:7,e:"ui-section",a:{label:"Internal Temp"},f:[{p:[46,3,1375],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.temp"],s:'_0?"--":_1'},p:[46,9,1381]}," K"]}]}," ",{p:[48,2,1443],t:7,e:"ui-section",a:{label:"Generated Power"},f:[{p:[49,3,1483],t:7,e:"span",f:[{t:2,x:{r:["data.broken","data.power"],s:'_0?"--":_1'},p:[49,9,1489]}]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],476:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{},oninit:function(){this.on({hover:function(t){var e=this.get("data.telecrystals");e>=t.context.params.cost&&this.set("hovered",t.context.params)},unhover:function(t){this.set("hovered")}})}}}(r),r.exports.template={v:3,t:[" ",{p:{button:[{t:4,f:[{p:[23,7,482],t:7,e:"ui-button",a:{icon:"lock",action:"lock"},f:["Lock"]}],n:50,r:"data.lockable",p:[22,5,453]}]},t:7,e:"ui-display",a:{title:"Uplink",button:0},f:[" ",{p:[26,3,568],t:7,e:"ui-section",a:{label:"Telecrystals",right:0},f:[{p:[27,5,613],t:7,e:"span",a:{"class":[{t:2,x:{r:["data.telecrystals"],s:'_0>0?"good":"bad"'},p:[27,18,626]}]},f:[{t:2,r:"data.telecrystals",p:[27,62,670]}," TC"]}]}]}," ",{t:4,f:[{p:[31,3,764],t:7,e:"ui-display",f:[{p:[32,2,779],t:7,e:"ui-button",a:{action:"select",params:['{"category": "',{t:2,r:"name",p:[32,51,828]},'"}']},f:[{t:2,r:"name",p:[32,63,840]}]}," ",{t:4,f:[{p:[34,4,883],t:7,e:"ui-section",a:{label:[{t:2,r:"name",p:[34,23,902]}],candystripe:0,right:0},f:[{p:[35,3,934],t:7,e:"ui-button",a:{tooltip:[{t:2,r:"name",p:[35,23,954]},": ",{t:2,r:"desc",p:[35,33,964]}],"tooltip-side":"left",state:[{t:2,x:{r:["data.telecrystals","hovered.cost","cost","hovered.item","name"],s:'_0<_2||(_0-_1<_2&&_3!=_4)?"disabled":null'},p:[36,12,1006]}],action:"buy",params:['{"category": "',{t:2,r:"category",p:[37,40,1165]},'", "item": ',{t:2,r:"name",p:[37,63,1188]},', "cost": ',{t:2,r:"cost",p:[37,81,1206]},"}"]},v:{hover:"hover",unhover:"unhover"},f:[{t:2,r:"cost",p:[38,43,1260]}," TC"]}]}],n:52,r:"items",p:[33,2,863]}]}],n:52,r:"data.categories",p:[30,1,735]}]},e.exports=a.extend(r.exports)},{341:341}],477:[function(t,e,n){var a=t(341),r={exports:{}};!function(t){"use strict";t.exports={data:{healthState:function(t){var e=this.get("data.vr_avatar.maxhealth");return t>e/1.5?"good":t>e/3?"average":"bad"}}}}(r),r.exports.template={
+v:3,t:[" ",{p:[14,1,292],t:7,e:"ui-display",f:[{t:4,f:[{p:[16,3,331],t:7,e:"ui-notice",f:[{p:[17,4,347],t:7,e:"span",f:["Safety restraints disabled."]}]}],n:50,r:"data.emagged",p:[15,2,307]}," ",{t:4,f:[{p:[21,3,442],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:[{p:[22,4,482],t:7,e:"ui-section",a:{label:"Name"},f:[{t:2,r:"data.vr_avatar.name",p:[23,5,513]}]}," ",{t:4,f:[{p:[26,5,586],t:7,e:"ui-section",a:{label:"Status"},f:[{t:2,r:"data.vr_avatar.status",p:[27,6,620]}]}," ",{p:[29,5,670],t:7,e:"ui-section",a:{label:"Health"},f:[{p:[30,6,704],t:7,e:"ui-bar",a:{min:"0",max:[{t:2,r:"adata.vr_avatar.maxhealth",p:[30,27,725]}],value:[{t:2,r:"adata.vr_avatar.health",p:[30,65,763]}],state:[{t:2,x:{r:["healthState","adata.vr_avatar.health"],s:"_0(_1)"},p:[30,100,798]}]},f:[{t:2,x:{r:["adata.vr_avatar.health"],s:"Math.round(_0)"},p:[30,141,839]},"/",{t:2,r:"adata.vr_avatar.maxhealth",p:[30,180,878]}]}]}],n:50,r:"data.isliving",p:[25,4,559]}]}],n:50,r:"data.vr_avatar",p:[20,2,416]},{t:4,n:51,f:[{p:[35,3,979],t:7,e:"ui-display",a:{title:"Virtual Avatar"},f:["No Virtual Avatar detected"]}],r:"data.vr_avatar"}," ",{p:[39,2,1075],t:7,e:"ui-display",a:{title:"VR Commands"},f:[{p:[40,3,1111],t:7,e:"ui-button",a:{icon:[{t:2,x:{r:["data.toggle_open"],s:'_0?"times":"plus"'},p:[40,20,1128]}],action:"toggle_open"},f:[{t:2,x:{r:["data.toggle_open"],s:'_0?"Close":"Open"'},p:[41,4,1195]}," the VR Sleeper"]}," ",{t:4,f:[{p:[44,4,1297],t:7,e:"ui-button",a:{icon:"signal",action:"vr_connect"},f:["Connect to VR"]}],n:50,r:"data.isoccupant",p:[43,3,1269]}," ",{t:4,f:[{p:[49,4,1420],t:7,e:"ui-button",a:{icon:"ban",action:"delete_avatar"},f:["Delete Virtual Avatar"]}],n:50,r:"data.vr_avatar",p:[48,3,1393]}]}]}]},e.exports=a.extend(r.exports)},{341:341}],478:[function(t,e,n){var a=t(341),r={exports:{}};r.exports.template={v:3,t:[{p:[1,1,0],t:7,e:"ui-display",f:[{t:4,f:[{p:[3,5,42],t:7,e:"ui-section",a:{label:[{t:2,r:"color",p:[3,24,61]},{t:2,x:{r:["wire"],s:'_0?" ("+_0+")":""'},p:[3,33,70]}],labelcolor:[{t:2,r:"color",p:[3,80,117]}],candystripe:0,right:0},f:[{p:[4,7,154],t:7,e:"ui-button",a:{action:"cut",params:['{"wire":"',{t:2,r:"color",p:[4,48,195]},'"}']},f:[{t:2,x:{r:["cut"],s:'_0?"Mend":"Cut"'},p:[4,61,208]}]}," ",{p:[5,7,252],t:7,e:"ui-button",a:{action:"pulse",params:['{"wire":"',{t:2,r:"color",p:[5,50,295]},'"}']},f:["Pulse"]}," ",{p:[6,7,333],t:7,e:"ui-button",a:{action:"attach",params:['{"wire":"',{t:2,r:"color",p:[6,51,377]},'"}']},f:[{t:2,x:{r:["attached"],s:'_0?"Detach":"Attach"'},p:[6,64,390]}]}]}],n:52,r:"data.wires",p:[2,3,16]}]}," ",{t:4,f:[{p:[11,3,508],t:7,e:"ui-display",f:[{t:4,f:[{p:[13,7,555],t:7,e:"ui-section",f:[{t:2,r:".",p:[13,19,567]}]}],n:52,r:"data.status",p:[12,5,526]}]}],n:50,r:"data.status",p:[10,1,485]}]},e.exports=a.extend(r.exports)},{341:341}],479:[function(t,e,n){(function(e){"use strict";var n=t(341),a=e.interopRequireDefault(n);t(331),t(1),t(327),t(330);var r=t(480),i=e.interopRequireDefault(r),o=t(481),s=t(328),p=t(329),u=e.interopRequireDefault(p);a["default"].DEBUG=/minified/.test(function(){}),Object.assign(Math,t(485)),window.initialize=function(e){window.tgui=window.tgui||new i["default"]({el:"#container",data:function(){var n=JSON.parse(e);return{constants:t(482),text:t(486),config:n.config,data:n.data,adata:n.data}}})};var c=document.getElementById("data"),l=c.textContent,d=c.getAttribute("data-ref");"{}"!==l&&(window.initialize(l),c.remove()),(0,o.act)(d,"tgui:initialize"),(0,s.loadCSS)("font-awesome.min.css");var f=new u["default"]("FontAwesome");f.check("").then(function(){return document.body.classList.add("icons")})["catch"](function(){return document.body.classList.add("no-icons")})}).call(this,t("babel/external-helpers"))},{1:1,327:327,328:328,329:329,330:330,331:331,341:341,480:480,481:481,482:482,485:485,486:486,"babel/external-helpers":"babel/external-helpers"}],480:[function(t,e,n){var a=t(341),r={exports:{}};!function(e){"use strict";var n=t(481),a=t(483);e.exports={components:{"ui-bar":t(342),"ui-button":t(343),"ui-display":t(344),"ui-input":t(345),"ui-linegraph":t(346),"ui-notice":t(347),"ui-section":t(349),"ui-subdisplay":t(350),"ui-tabs":t(351)},events:{enter:t(339).enter,space:t(339).space},transitions:{fade:t(340)},onconfig:function(){var e=this.get("config.interface"),n={ai_airlock:t(355),airalarm:t(356),"airalarm/back":t(357),"airalarm/modes":t(358),"airalarm/scrubbers":t(359),"airalarm/status":t(360),"airalarm/thresholds":t(361),"airalarm/vents":t(362),airlock_electronics:t(363),apc:t(364),atmos_alert:t(365),atmos_control:t(366),atmos_filter:t(367),atmos_mixer:t(368),atmos_pump:t(369),borgopanel:t(370),brig_timer:t(371),bsa:t(372),canister:t(373),cargo:t(374),cargo_express:t(375),cellular_emporium:t(376),centcom_podlauncher:t(377),chem_dispenser:t(378),chem_heater:t(379),chem_master:t(380),chem_synthesizer:t(381),clockwork_slab:t(382),codex_gigas:t(383),computer_fabricator:t(384),crayon:t(385),crew:t(386),cryo:t(387),disposal_unit:t(388),dna_vault:t(389),dogborg_sleeper:t(390),eightball:t(391),emergency_shuttle_console:t(392),engraved_message:t(393),error:t(394),"exofab - Copia":t(395),exonet_node:t(396),firealarm:t(397),gps:t(398),gulag_console:t(399),gulag_item_reclaimer:t(400),holodeck:t(401),implantchair:t(402),intellicard:t(403),keycard_auth:t(404),labor_claim_console:t(405),language_menu:t(406),launchpad_remote:t(407),mech_bay_power_console:t(408),mulebot:t(409),nanite_chamber_control:t(410),nanite_cloud_control:t(411),nanite_program_hub:t(412),nanite_programmer:t(413),nanite_remote:t(414),notificationpanel:t(415),ntnet_relay:t(416),ntos_ai_restorer:t(417),ntos_card:t(418),ntos_configuration:t(419),ntos_file_manager:t(420),ntos_main:t(421),ntos_net_chat:t(422),ntos_net_dos:t(423),ntos_net_downloader:t(424),ntos_net_monitor:t(425),ntos_net_transfer:t(426),ntos_power_monitor:t(427),ntos_revelation:t(428),ntos_station_alert:t(429),ntos_supermatter_monitor:t(430),ntosheader:t(431),nuclear_bomb:t(432),operating_computer:t(433),ore_redemption_machine:t(434),pandemic:t(435),personal_crafting:t(436),portable_pump:t(437),portable_scrubber:t(438),power_monitor:t(439),radio:t(440),rdconsole:t(441),"rdconsole/circuit":t(442),"rdconsole/designview":t(443),"rdconsole/destruct":t(444),"rdconsole/diskopsdesign":t(445),"rdconsole/diskopstech":t(446),"rdconsole/nodeview":t(447),"rdconsole/protolathe":t(448),"rdconsole/rdheader":t(449),"rdconsole/settings":t(450),"rdconsole/techweb":t(451),reagentgrinder:t(452),rpd:t(453),"rpd/colorsel":t(454),"rpd/dirsel":t(455),sat_control:t(456),scrubbing_types:t(457),shuttle_manipulator:t(458),"shuttle_manipulator/modification":t(459),"shuttle_manipulator/status":t(460),"shuttle_manipulator/templates":t(461),sleeper:t(462),slime_swap_body:t(463),smartvend:t(464),smes:t(465),smoke_machine:t(466),solar_control:t(467),space_heater:t(468),spawners_menu:t(469),station_alert:t(470),suit_storage_unit:t(471),tank_dispenser:t(472),tanks:t(473),thermomachine:t(474),turbine_computer:t(475),uplink:t(476),vr_sleeper:t(477),wires:t(478)};e in n?this.components["interface"]=n[e]:this.components["interface"]=n.error},oninit:function(){this.observe("config.style",function(t,e,n){t&&document.body.classList.add(t),e&&document.body.classList.remove(e)})},oncomplete:function(){if(this.get("config.locked")){var t=(0,a.lock)(window.screenLeft,window.screenTop),e=t.x,r=t.y;(0,n.winset)(this.get("config.window"),"pos",e+","+r)}(0,n.winset)("mapwindow.map","focus",!0)}}}(r),r.exports.template={v:3,t:[" "," "," "," ",{p:[56,1,1874],t:7,e:"titlebar",f:[{t:3,r:"config.title",p:[56,11,1884]}]}," ",{p:[57,1,1915],t:7,e:"main",f:[{p:[58,3,1925],t:7,e:"warnings"}," ",{p:[59,3,1940],t:7,e:"interface"}]}," ",{t:4,f:[{p:[62,3,1990],t:7,e:"resize"}],n:50,r:"config.titlebar",p:[61,1,1963]}]},r.exports.components=r.exports.components||{};var i={warnings:t(354),titlebar:t(353),resize:t(348)};for(var o in i)i.hasOwnProperty(o)&&(r.exports.components[o]=i[o]);e.exports=a.extend(r.exports)},{339:339,340:340,341:341,342:342,343:343,344:344,345:345,346:346,347:347,348:348,349:349,350:350,351:351,353:353,354:354,355:355,356:356,357:357,358:358,359:359,360:360,361:361,362:362,363:363,364:364,365:365,366:366,367:367,368:368,369:369,370:370,371:371,372:372,373:373,374:374,375:375,376:376,377:377,378:378,379:379,380:380,381:381,382:382,383:383,384:384,385:385,386:386,387:387,388:388,389:389,390:390,391:391,392:392,393:393,394:394,395:395,396:396,397:397,398:398,399:399,400:400,401:401,402:402,403:403,404:404,405:405,406:406,407:407,408:408,409:409,410:410,411:411,412:412,413:413,414:414,415:415,416:416,417:417,418:418,419:419,420:420,421:421,422:422,423:423,424:424,425:425,426:426,427:427,428:428,429:429,430:430,431:431,432:432,433:433,434:434,435:435,436:436,437:437,438:438,439:439,440:440,441:441,442:442,443:443,444:444,445:445,446:446,447:447,448:448,449:449,450:450,451:451,452:452,453:453,454:454,455:455,456:456,457:457,458:458,459:459,460:460,461:461,462:462,463:463,464:464,465:465,466:466,467:467,468:468,469:469,470:470,471:471,472:472,473:473,474:474,475:475,476:476,477:477,478:478,481:481,483:483}],481:[function(t,e,n){"use strict";function a(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return"byond://"+e+"?"+Object.keys(t).map(function(e){return o(e)+"="+o(t[e])}).join("&")}function r(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};window.location.href=a(Object.assign({src:t,action:e},n))}function i(t,e,n){var r;window.location.href=a((r={},r[t+"."+e]=n,r),"winset")}n.__esModule=!0,n.href=a,n.act=r,n.winset=i;var o=encodeURIComponent},{}],482:[function(t,e,n){"use strict";n.__esModule=!0;n.UI_INTERACTIVE=2,n.UI_UPDATE=1,n.UI_DISABLED=0,n.UI_CLOSE=-1},{}],483:[function(t,e,n){"use strict";function a(t,e){return 0>t?t=0:t+window.innerWidth>window.screen.availWidth&&(t=window.screen.availWidth-window.innerWidth),0>e?e=0:e+window.innerHeight>window.screen.availHeight&&(e=window.screen.availHeight-window.innerHeight),{x:t,y:e}}function r(t){if(t.preventDefault(),this.get("drag")){if(this.get("x")){var e=t.screenX-this.get("x")+window.screenLeft,n=t.screenY-this.get("y")+window.screenTop;if(this.get("config.locked")){var r=a(e,n);e=r.x,n=r.y}(0,s.winset)(this.get("config.window"),"pos",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}function i(t,e){return t=Math.clamp(100,window.screen.width,t),e=Math.clamp(100,window.screen.height,e),{x:t,y:e}}function o(t){if(t.preventDefault(),this.get("resize")){if(this.get("x")){var e=t.screenX-this.get("x")+window.innerWidth,n=t.screenY-this.get("y")+window.innerHeight,a=i(e,n);e=a.x,n=a.y,(0,s.winset)(this.get("config.window"),"size",e+","+n)}this.set({x:t.screenX,y:t.screenY})}}n.__esModule=!0,n.lock=a,n.drag=r,n.sane=i,n.resize=o;var s=t(481)},{481:481}],484:[function(t,e,n){"use strict";function a(t,e){for(var n=t,a=Array.isArray(n),i=0,n=a?n:n[Symbol.iterator]();;){var o;if(a){if(i>=n.length)break;o=n[i++]}else{if(i=n.next(),i.done)break;o=i.value}var s=o;s.textContent.toLowerCase().includes(e)?(s.style.display="",r(s,e)):s.style.display="none"}}function r(t,e){for(var n=t.queryAll("section"),a=t.query("header").textContent.toLowerCase().includes(e),r=n,i=Array.isArray(r),o=0,r=i?r:r[Symbol.iterator]();;){var s;if(i){if(o>=r.length)break;s=r[o++]}else{if(o=r.next(),o.done)break;s=o.value}var p=s;a||p.textContent.toLowerCase().includes(e)?p.style.display="":p.style.display="none"}}n.__esModule=!0,n.filterMulti=a,n.filter=r},{}],485:[function(t,e,n){"use strict";function a(t,e,n){return Math.max(t,Math.min(n,e))}function r(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:1;return+(Math.round(t+"e"+e)+"e-"+e)}n.__esModule=!0,n.clamp=a,n.fixed=r},{}],486:[function(t,e,n){"use strict";function a(t){return t[0].toUpperCase()+t.slice(1).toLowerCase()}function r(t){return t.replace(/\w\S*/g,a)}function i(t,e){for(t=""+t;t.length1){for(var p=Array(o),u=0;o>u;u++)p[u]=arguments[u+3];n.children=p}return{$$typeof:t,type:e,key:void 0===a?null:""+a,ref:null,props:n,_owner:null}}}(),e.asyncIterator=function(t){if("function"==typeof Symbol){if(Symbol.asyncIterator){var e=t[Symbol.asyncIterator];if(null!=e)return e.call(t)}if(Symbol.iterator)return t[Symbol.iterator]()}throw new TypeError("Object is not async iterable")},e.asyncGenerator=function(){function t(t){this.value=t}function e(e){function n(t,e){return new Promise(function(n,r){var s={key:t,arg:e,resolve:n,reject:r,next:null};o?o=o.next=s:(i=o=s,a(t,e))})}function a(n,i){try{var o=e[n](i),s=o.value;s instanceof t?Promise.resolve(s.value).then(function(t){a("next",t)},function(t){a("throw",t)}):r(o.done?"return":"normal",o.value)}catch(p){r("throw",p)}}function r(t,e){switch(t){case"return":i.resolve({value:e,done:!0});break;case"throw":i.reject(e);break;default:i.resolve({value:e,done:!1})}i=i.next,i?a(i.key,i.arg):o=null}var i,o;this._invoke=n,"function"!=typeof e["return"]&&(this["return"]=void 0)}return"function"==typeof Symbol&&Symbol.asyncIterator&&(e.prototype[Symbol.asyncIterator]=function(){return this}),e.prototype.next=function(t){return this._invoke("next",t)},e.prototype["throw"]=function(t){return this._invoke("throw",t)},e.prototype["return"]=function(t){return this._invoke("return",t)},{wrap:function(t){return function(){return new e(t.apply(this,arguments))}},await:function(e){return new t(e)}}}(),e.asyncGeneratorDelegate=function(t,e){function n(n,a){return r=!0,a=new Promise(function(e){e(t[n](a))}),{done:!1,value:e(a)}}var a={},r=!1;return"function"==typeof Symbol&&Symbol.iterator&&(a[Symbol.iterator]=function(){return this}),a.next=function(t){return r?(r=!1,t):n("next",t)},"function"==typeof t["throw"]&&(a["throw"]=function(t){if(r)throw r=!1,t;return n("throw",t)}),"function"==typeof t["return"]&&(a["return"]=function(t){return n("return",t)}),a},e.asyncToGenerator=function(t){return function(){var e=t.apply(this,arguments);return new Promise(function(t,n){function a(r,i){try{var o=e[r](i),s=o.value}catch(p){return void n(p)}return o.done?void t(s):Promise.resolve(s).then(function(t){a("next",t)},function(t){a("throw",t)})}return a("next")})}},e.classCallCheck=function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")},e.createClass=function(){function t(t,e){for(var n=0;n=0||Object.prototype.hasOwnProperty.call(t,a)&&(n[a]=t[a]);return n},e.possibleConstructorReturn=function(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e},e.selfGlobal=void 0===t?self:t,e.set=function a(t,e,n,r){var i=Object.getOwnPropertyDescriptor(t,e);if(void 0===i){var o=Object.getPrototypeOf(t);null!==o&&a(o,e,n,r)}else if("value"in i&&i.writable)i.value=n;else{var s=i.set;void 0!==s&&s.call(r,n)}return n},e.slicedToArray=function(){function t(t,e){var n=[],a=!0,r=!1,i=void 0;try{for(var o,s=t[Symbol.iterator]();!(a=(o=s.next()).done)&&(n.push(o.value),!e||n.length!==e);a=!0);}catch(p){r=!0,i=p}finally{try{!a&&s["return"]&&s["return"]()}finally{if(r)throw i}}return n}return function(e,n){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,n);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),e.slicedToArrayLoose=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t)){for(var n,a=[],r=t[Symbol.iterator]();!(n=r.next()).done&&(a.push(n.value),!e||a.length!==e););return a}throw new TypeError("Invalid attempt to destructure non-iterable instance")},e.taggedTemplateLiteral=function(t,e){return Object.freeze(Object.defineProperties(t,{raw:{value:Object.freeze(e)}}))},e.taggedTemplateLiteralLoose=function(t,e){return t.raw=e,t},e.temporalRef=function(t,e,n){if(t===n)throw new ReferenceError(e+" is not defined - temporal dead zone");return t},e.temporalUndefined={},e.toArray=function(t){return Array.isArray(t)?t:Array.from(t)},e.toConsumableArray=function(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e
Dispense Buffer to Hypo vials
+
+ Create SmartDart (max 20µ)
+
+ Create Multiple SmartDarts
+
diff --git a/tgui/src/interfaces/vr_sleeper.ract b/tgui/src/interfaces/vr_sleeper.ract
index 32f3ab33b3..91074a9425 100644
--- a/tgui/src/interfaces/vr_sleeper.ract
+++ b/tgui/src/interfaces/vr_sleeper.ract
@@ -22,12 +22,14 @@
{{data.vr_avatar.name}}
-
- {{data.vr_avatar.status}}
-
-
- {{Math.round(adata.vr_avatar.health)}}/{{adata.vr_avatar.maxhealth}}
-
+ {{#if data.isliving}}
+
+ {{data.vr_avatar.status}}
+
+
+ {{Math.round(adata.vr_avatar.health)}}/{{adata.vr_avatar.maxhealth}}
+
+ {{/if}}
{{else}}
diff --git a/tools/mapmerge2/dmi.py b/tools/mapmerge2/dmi.py
index f0a8182c9f..c12964cead 100644
--- a/tools/mapmerge2/dmi.py
+++ b/tools/mapmerge2/dmi.py
@@ -45,6 +45,8 @@ class Dmi:
@classmethod
def from_file(cls, fname):
image = Image.open(fname)
+ if image.mode != 'RGBA':
+ image = image.convert('RGBA')
# no metadata = regular image file
if 'Description' not in image.info:
@@ -250,4 +252,4 @@ if __name__ == '__main__':
Dmi.from_file(os.path.join(dirpath, filename))
count += 1
- print(f"Successfully parsed {count} dmi files")
+ print(f"Successfully parsed {count} dmi files")
\ No newline at end of file
diff --git a/tools/mapmerge2/dmm.py b/tools/mapmerge2/dmm.py
index 8bb1dca353..15aa04c07f 100644
--- a/tools/mapmerge2/dmm.py
+++ b/tools/mapmerge2/dmm.py
@@ -343,7 +343,7 @@ def _parse(map_raw_text):
in_map_block = False
in_coord_block = False
in_map_string = False
- iter_x = 0
+ base_x = 0
adjust_y = True
curr_num = ""
@@ -487,7 +487,7 @@ def _parse(map_raw_text):
curr_x = int(curr_num)
if curr_x > maxx:
maxx = curr_x
- iter_x = 0
+ base_x = curr_x
curr_num = ""
reading_coord = "y"
elif reading_coord == "y":
@@ -521,21 +521,15 @@ def _parse(map_raw_text):
adjust_y = False
else:
curr_y += 1
- if curr_x > maxx:
- maxx = curr_x
- if iter_x > 1:
- curr_x = 1
- iter_x = 0
-
+ curr_x = base_x
else:
curr_key = BASE * curr_key + base52_r[char]
curr_key_len += 1
if curr_key_len == key_length:
- iter_x += 1
- if iter_x > 1:
- curr_x += 1
-
grid[curr_x, curr_y, curr_z] = duplicate_keys.get(curr_key, curr_key)
+ if curr_x > maxx:
+ maxx = curr_x
+ curr_x += 1
curr_key = 0
curr_key_len = 0
@@ -551,4 +545,4 @@ def _parse(map_raw_text):
data = DMM(key_length, Coordinate(maxx, maxy, maxz))
data.dictionary = dictionary
data.grid = grid
- return data
+ return data
\ No newline at end of file
diff --git a/tools/mapmerge2/requirements.txt b/tools/mapmerge2/requirements.txt
index adb42438e7..d24cb40dcc 100644
--- a/tools/mapmerge2/requirements.txt
+++ b/tools/mapmerge2/requirements.txt
@@ -1,3 +1,3 @@
pygit2==0.27.2
bidict==0.13.1
-Pillow==5.1.0
+Pillow==6.2.0
diff --git a/tools/mapmerge2/update_paths.py b/tools/mapmerge2/update_paths.py
index 2c316e941d..deab468ecd 100644
--- a/tools/mapmerge2/update_paths.py
+++ b/tools/mapmerge2/update_paths.py
@@ -173,4 +173,4 @@ if __name__ == "__main__":
parser.add_argument("--directory", "-d", help="path to maps directory, defaults to _maps/")
parser.add_argument("--inline", "-i", help="treat update source as update string instead of path", action="store_true")
parser.add_argument("--verbose", "-v", help="toggle detailed update information", action="store_true")
- main(parser.parse_args())
+ main(parser.parse_args())
\ No newline at end of file