diff --git a/.travis.yml b/.travis.yml
index 0d40ecda0a..8dd7fe20e1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,9 +3,9 @@ language: c
sudo: false
env:
- BYOND_MAJOR="509"
- BYOND_MINOR="1318"
- MACRO_COUNT=986
+ BYOND_MAJOR="510"
+ BYOND_MINOR="1346"
+ MACRO_COUNT=987
cache:
directories:
diff --git a/code/__defines/math_physics.dm b/code/__defines/math_physics.dm
index 987cb1ba9d..198f87eccc 100644
--- a/code/__defines/math_physics.dm
+++ b/code/__defines/math_physics.dm
@@ -15,9 +15,10 @@
#define RADIATOR_EXPOSED_SURFACE_AREA_RATIO 0.04 // (3 cm + 100 cm * sin(3deg))/(2*(3+100 cm)). Unitless ratio.
#define HUMAN_EXPOSED_SURFACE_AREA 5.2 //m^2, surface area of 1.7m (H) x 0.46m (D) cylinder
-#define T0C 273.15 // 0.0 degrees celcius
-#define T20C 293.15 // 20.0 degrees celcius
-#define TCMB 2.7 // -270.3 degrees celcius
+#define T0C 273.15 // 0.0 degrees celcius
+#define T20C 293.15 // 20.0 degrees celcius
+#define TCMB 2.7 // -270.3 degrees celcius
+#define TN60C 213.15 // -60 degrees celcius
#define CLAMP01(x) max(0, min(1, x))
#define QUANTIZE(variable) (round(variable,0.0001))
diff --git a/code/__defines/misc.dm b/code/__defines/misc.dm
index 0a06743993..68954b0dc5 100644
--- a/code/__defines/misc.dm
+++ b/code/__defines/misc.dm
@@ -92,7 +92,8 @@
// Setting this much higher than 1024 could allow spammers to DOS the server easily.
#define MAX_MESSAGE_LEN 1024
#define MAX_PAPER_MESSAGE_LEN 6144
-#define MAX_BOOK_MESSAGE_LEN 12288
+#define MAX_BOOK_MESSAGE_LEN 24576
+#define MAX_RECORD_LENGTH 24576
#define MAX_LNAME_LEN 64
#define MAX_NAME_LEN 52
@@ -161,3 +162,8 @@
#define CAT_NORMAL 1
#define CAT_HIDDEN 2
#define CAT_COIN 4
+
+//Antag Faction Visbility
+#define ANTAG_HIDDEN "Hidden"
+#define ANTAG_SHARED "Shared"
+#define ANTAG_KNOWN "Known"
diff --git a/code/_onclick/_defines.dm b/code/_onclick/_defines.dm
new file mode 100644
index 0000000000..3c76c35e80
--- /dev/null
+++ b/code/_onclick/_defines.dm
@@ -0,0 +1 @@
+#define CLICKCATCHER_PLANE -99
\ No newline at end of file
diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm
index d131ddd6d3..52c56ccb17 100644
--- a/code/_onclick/click.dm
+++ b/code/_onclick/click.dm
@@ -321,11 +321,19 @@
facedir(direction)
/obj/screen/click_catcher
- icon = 'icons/mob/screen1_full.dmi'
- icon_state = "passage0"
- layer = 0
+ icon = 'icons/mob/screen_gen.dmi'
+ icon_state = "click_catcher"
+ plane = CLICKCATCHER_PLANE
mouse_opacity = 2
- screen_loc = "1,1"
+ screen_loc = "CENTER-7,CENTER-7"
+
+/obj/screen/click_catcher/proc/MakeGreed()
+ . = list()
+ for(var/i = 0, i<15, i++)
+ for(var/j = 0, j<15, j++)
+ var/obj/screen/click_catcher/CC = new()
+ CC.screen_loc = "NORTH-[i],EAST-[j]"
+ . += CC
/obj/screen/click_catcher/Click(location, control, params)
var/list/modifiers = params2list(params)
@@ -333,6 +341,6 @@
var/mob/living/carbon/C = usr
C.swap_hand()
else
- var/turf/T = screen_loc2turf(modifiers["screen-loc"], get_turf(usr))
+ var/turf/T = screen_loc2turf("screen-loc", get_turf(usr))
T.Click(location, control, params)
- return 1
+ . = 1
diff --git a/code/_onclick/hud/alien_larva.dm b/code/_onclick/hud/alien_larva.dm
index 4fa0e4110a..1f0df80141 100644
--- a/code/_onclick/hud/alien_larva.dm
+++ b/code/_onclick/hud/alien_larva.dm
@@ -21,20 +21,6 @@
mymob.healths.name = "health"
mymob.healths.screen_loc = ui_alien_health
- mymob.blind = new /obj/screen()
- mymob.blind.icon = 'icons/mob/screen1_full.dmi'
- mymob.blind.icon_state = "blackimageoverlay"
- mymob.blind.name = " "
- mymob.blind.screen_loc = "1,1"
- mymob.blind.layer = 0
-
- mymob.flash = new /obj/screen()
- mymob.flash.icon = 'icons/mob/screen1_alien.dmi'
- mymob.flash.icon_state = "blank"
- mymob.flash.name = "flash"
- mymob.flash.screen_loc = ui_entire_screen
- mymob.flash.layer = 17
-
mymob.fire = new /obj/screen()
mymob.fire.icon = 'icons/mob/screen1_alien.dmi'
mymob.fire.icon_state = "fire0"
@@ -42,6 +28,6 @@
mymob.fire.screen_loc = ui_fire
mymob.client.screen = list()
- mymob.client.screen += list( mymob.healths, mymob.blind, mymob.flash, mymob.fire) //, mymob.rest, mymob.sleep, mymob.mach )
+ mymob.client.screen += list( mymob.healths, mymob.fire) //, mymob.rest, mymob.sleep, mymob.mach )
mymob.client.screen += src.adding + src.other
mymob.client.screen += mymob.client.void
\ No newline at end of file
diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm
new file mode 100644
index 0000000000..fd226eb70c
--- /dev/null
+++ b/code/_onclick/hud/fullscreen.dm
@@ -0,0 +1,118 @@
+#define FULLSCREEN_LAYER 18
+#define DAMAGE_LAYER FULLSCREEN_LAYER + 0.1
+#define BLIND_LAYER DAMAGE_LAYER + 0.1
+#define CRIT_LAYER BLIND_LAYER + 0.1
+
+/mob
+ var/list/screens = list()
+
+/mob/proc/set_fullscreen(condition, screen_name, screen_type, arg)
+ condition ? overlay_fullscreen(screen_name, screen_type, arg) : clear_fullscreen(screen_name)
+
+/mob/proc/overlay_fullscreen(category, type, severity)
+ var/obj/screen/fullscreen/screen = screens[category]
+
+ if(screen)
+ if(screen.type != type)
+ clear_fullscreen(category, FALSE)
+ screen = null
+ else if(!severity || severity == screen.severity)
+ return null
+
+ if(!screen)
+ screen = PoolOrNew(type)
+
+ screen.icon_state = "[initial(screen.icon_state)][severity]"
+ screen.severity = severity
+
+ screens[category] = screen
+ if(client && stat != DEAD)
+ client.screen += screen
+ return screen
+
+/mob/proc/clear_fullscreen(category, animated = 10)
+ var/obj/screen/fullscreen/screen = screens[category]
+ if(!screen)
+ return
+
+ screens -= category
+
+ if(animated)
+ spawn(0)
+ animate(screen, alpha = 0, time = animated)
+ sleep(animated)
+ if(client)
+ client.screen -= screen
+ qdel(screen)
+ else
+ if(client)
+ client.screen -= screen
+ qdel(screen)
+
+/mob/proc/clear_fullscreens()
+ for(var/category in screens)
+ clear_fullscreen(category)
+
+/mob/proc/hide_fullscreens()
+ if(client)
+ for(var/category in screens)
+ client.screen -= screens[category]
+
+/mob/proc/reload_fullscreen()
+ if(client && stat != DEAD) //dead mob do not see any of the fullscreen overlays that he has.
+ for(var/category in screens)
+ client.screen |= screens[category]
+
+/obj/screen/fullscreen
+ icon = 'icons/mob/screen_full.dmi'
+ icon_state = "default"
+ screen_loc = "CENTER-7,CENTER-7"
+ layer = FULLSCREEN_LAYER
+ mouse_opacity = 0
+ var/severity = 0
+
+/obj/screen/fullscreen/Destroy()
+ severity = 0
+ return ..()
+
+/obj/screen/fullscreen/brute
+ icon_state = "brutedamageoverlay"
+ layer = DAMAGE_LAYER
+
+/obj/screen/fullscreen/oxy
+ icon_state = "oxydamageoverlay"
+ layer = DAMAGE_LAYER
+
+/obj/screen/fullscreen/crit
+ icon_state = "passage"
+ layer = CRIT_LAYER
+
+/obj/screen/fullscreen/blind
+ icon_state = "blackimageoverlay"
+ layer = BLIND_LAYER
+
+/obj/screen/fullscreen/impaired
+ icon_state = "impairedoverlay"
+
+/obj/screen/fullscreen/blurry
+ icon = 'icons/mob/screen1.dmi'
+ screen_loc = "WEST,SOUTH to EAST,NORTH"
+ icon_state = "blurry"
+
+/obj/screen/fullscreen/flash
+ icon = 'icons/mob/screen1.dmi'
+ screen_loc = "WEST,SOUTH to EAST,NORTH"
+ icon_state = "flash"
+
+/obj/screen/fullscreen/flash/noise
+ icon_state = "noise"
+
+/obj/screen/fullscreen/high
+ icon = 'icons/mob/screen1.dmi'
+ screen_loc = "WEST,SOUTH to EAST,NORTH"
+ icon_state = "druggy"
+
+#undef FULLSCREEN_LAYER
+#undef BLIND_LAYER
+#undef DAMAGE_LAYER
+#undef CRIT_LAYER
\ No newline at end of file
diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm
index 7b9cf82cc5..16c601ecb7 100644
--- a/code/_onclick/hud/hud.dm
+++ b/code/_onclick/hud/hud.dm
@@ -269,7 +269,7 @@ datum/hud/New(mob/owner)
else if(isrobot(mymob))
robot_hud(ui_style, ui_color, ui_alpha, mymob)
else if(isbrain(mymob))
- brain_hud(ui_style)
+ mymob.instantiate_hud(src)
else if(isalien(mymob))
larva_hud()
else if(isslime(mymob))
@@ -382,3 +382,9 @@ datum/hud/New(mob/owner)
hud_used.hidden_inventory_update()
hud_used.persistant_inventory_update()
update_action_buttons()
+
+/mob/proc/add_click_catcher()
+ client.screen += client.void
+
+/mob/new_player/add_click_catcher()
+ return
\ No newline at end of file
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index 3f872f53e6..d38b3acc5f 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -303,32 +303,6 @@
mymob.ling_chem_display.icon_state = "ling_chems"
hud_elements |= mymob.ling_chem_display
- mymob.blind = new /obj/screen()
- mymob.blind.icon = 'icons/mob/screen1_full.dmi'
- mymob.blind.icon_state = "blackimageoverlay"
- mymob.blind.name = " "
- mymob.blind.screen_loc = "1,1"
- mymob.blind.mouse_opacity = 0
- mymob.blind.layer = 0
- hud_elements |= mymob.blind
-
- mymob.damageoverlay = new /obj/screen()
- mymob.damageoverlay.icon = 'icons/mob/screen1_full.dmi'
- mymob.damageoverlay.icon_state = "oxydamageoverlay0"
- mymob.damageoverlay.name = "dmg"
- mymob.damageoverlay.screen_loc = "1,1"
- mymob.damageoverlay.mouse_opacity = 0
- mymob.damageoverlay.layer = 18.1 //The black screen overlay sets layer to 18 to display it, this one has to be just on top.
- hud_elements |= mymob.damageoverlay
-
- mymob.flash = new /obj/screen()
- mymob.flash.icon = ui_style
- mymob.flash.icon_state = "blank"
- mymob.flash.name = "flash"
- mymob.flash.screen_loc = ui_entire_screen
- mymob.flash.layer = 17
- hud_elements |= mymob.flash
-
mymob.pain = new /obj/screen( null )
mymob.zone_sel = new /obj/screen/zone_sel( null )
@@ -366,7 +340,7 @@
mymob.client.screen += hud_elements
mymob.client.screen += src.adding + src.hotkeybuttons
mymob.client.screen += mymob.client.void
- inventory_shown = 0;
+ inventory_shown = 0
return
diff --git a/code/_onclick/hud/other_mobs.dm b/code/_onclick/hud/other_mobs.dm
index 76922e398c..cab3e3bfca 100644
--- a/code/_onclick/hud/other_mobs.dm
+++ b/code/_onclick/hud/other_mobs.dm
@@ -5,14 +5,6 @@
/datum/hud/proc/ghost_hud()
return
-/datum/hud/proc/brain_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
- mymob.blind = new /obj/screen()
- mymob.blind.icon = 'icons/mob/screen1_full.dmi'
- mymob.blind.icon_state = "blackimageoverlay"
- mymob.blind.name = " "
- mymob.blind.screen_loc = "1,1"
- mymob.blind.layer = 0
-
/datum/hud/proc/blob_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
blobpwrdisplay = new /obj/screen()
@@ -116,13 +108,6 @@
else if(istype(mymob,/mob/living/simple_animal/construct/harvester))
constructtype = "harvester"
- mymob.flash = new /obj/screen()
- mymob.flash.icon = 'icons/mob/screen1.dmi'
- mymob.flash.icon_state = "blank"
- mymob.flash.name = "flash"
- mymob.flash.screen_loc = ui_entire_screen
- mymob.flash.layer = 17
-
if(constructtype)
mymob.fire = new /obj/screen()
mymob.fire.icon = 'icons/mob/screen1_construct.dmi'
@@ -155,5 +140,5 @@
mymob.client.screen = list()
- mymob.client.screen += list(mymob.fire, mymob.healths, mymob.pullin, mymob.zone_sel, mymob.purged, mymob.flash)
+ mymob.client.screen += list(mymob.fire, mymob.healths, mymob.pullin, mymob.zone_sel, mymob.purged)
mymob.client.screen += mymob.client.void
diff --git a/code/_onclick/hud/robot.dm b/code/_onclick/hud/robot.dm
index c6783e7bf7..ff0d8cdd5b 100644
--- a/code/_onclick/hud/robot.dm
+++ b/code/_onclick/hud/robot.dm
@@ -173,21 +173,6 @@ var/obj/screen/robot_inventory
mymob.pullin.screen_loc = ui_borg_pull
src.other += mymob.pullin
- mymob.blind = new /obj/screen()
- mymob.blind.icon = 'icons/mob/screen1_full.dmi'
- mymob.blind.icon_state = "blackimageoverlay"
- mymob.blind.name = " "
- mymob.blind.screen_loc = "1,1"
- mymob.blind.layer = 0
-
- mymob.flash = new /obj/screen()
- mymob.flash.icon = ui_style
- mymob.flash.icon_state = "blank"
- mymob.flash.name = "flash"
- mymob.flash.screen_loc = ui_entire_screen
- mymob.flash.layer = 17
- src.other += mymob.flash
-
mymob.zone_sel = new /obj/screen/zone_sel()
mymob.zone_sel.icon = ui_style
mymob.zone_sel.alpha = ui_alpha
@@ -210,7 +195,7 @@ var/obj/screen/robot_inventory
mymob.client.screen = list()
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, mymob.blind, mymob.flash, robot_inventory, mymob.gun_setting_icon)
+ mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.fire, mymob.hands, mymob.healths, mymob:cells, mymob.pullin, robot_inventory, mymob.gun_setting_icon)
mymob.client.screen += src.adding + src.other
mymob.client.screen += mymob.client.void
diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm
index e0c6c7a159..2413cb57ae 100644
--- a/code/_onclick/item_attack.dm
+++ b/code/_onclick/item_attack.dm
@@ -39,7 +39,7 @@ avoid code duplication. This includes items that may sometimes act as a standard
/mob/living/attackby(obj/item/I, mob/user)
if(!ismob(user))
return 0
- if(can_operate(src) && do_surgery(src,user,I)) //Surgery
+ if(can_operate(src) && I.do_surgery(src,user)) //Surgery
return 1
if(attempt_vr(src,"vore_attackby",args)) return //VOREStation Code
return I.attack(src, user, user.zone_sel.selecting)
@@ -77,6 +77,7 @@ avoid code duplication. This includes items that may sometimes act as a standard
//Called when a weapon is used to make a successful melee attack on a mob. Returns the blocked result
/obj/item/proc/apply_hit_effect(mob/living/target, mob/living/user, var/hit_zone)
+ user.break_cloak()
if(hitsound)
playsound(loc, hitsound, 50, 1, -1)
diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm
index b249db9a47..ae0d5a2544 100644
--- a/code/controllers/configuration.dm
+++ b/code/controllers/configuration.dm
@@ -65,6 +65,7 @@ var/list/gamemode_cache = list()
var/usewhitelist = 0
var/kick_inactive = 0 //force disconnect for inactive players after this many minutes, if non-0
var/show_mods = 0
+ var/show_devs = 0
var/show_mentors = 0
var/mods_can_tempban = 0
var/mods_can_job_tempban = 0
@@ -505,6 +506,9 @@ var/list/gamemode_cache = list()
if("show_mods")
config.show_mods = 1
+ if("show_devs")
+ config.show_devs = 1
+
if("show_mentors")
config.show_mentors = 1
diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm
index cc603aa2df..2043febdb6 100644
--- a/code/datums/datacore.dm
+++ b/code/datums/datacore.dm
@@ -228,6 +228,8 @@
L.fields["faction"] = H.personal_faction
L.fields["religion"] = H.religion
L.fields["image"] = getFlatIcon(H) //This is god-awful
+ L.fields["antagfac"] = H.antag_faction
+ L.fields["antagvis"] = H.antag_vis
if(H.exploit_record && !jobban_isbanned(H, "Records"))
L.fields["exploit_record"] = H.exploit_record
else
diff --git a/code/datums/supplypacks/atmospherics.dm b/code/datums/supplypacks/atmospherics.dm
index 91c85f8ac2..0c8d3748d1 100644
--- a/code/datums/supplypacks/atmospherics.dm
+++ b/code/datums/supplypacks/atmospherics.dm
@@ -52,7 +52,7 @@
/datum/supply_packs/atmos/canister_sleeping_agent
name = "N2O gas canister"
- cost = 40
+ cost = 15
containername = "N2O gas canister crate"
containertype = /obj/structure/closet/crate/secure/large
access = access_atmospherics
@@ -60,7 +60,7 @@
/datum/supply_packs/atmos/canister_carbon_dioxide
name = "Carbon dioxide gas canister"
- cost = 40
+ cost = 15
containername = "CO2 canister crate"
containertype = /obj/structure/closet/crate/secure/large
access = access_atmospherics
@@ -69,7 +69,7 @@
/datum/supply_packs/atmos/air_dispenser
contains = list(/obj/machinery/pipedispenser/orderable)
name = "Pipe Dispenser"
- cost = 35
+ cost = 25
containertype = /obj/structure/closet/crate/secure/large
containername = "Pipe Dispenser Crate"
access = access_atmospherics
@@ -77,7 +77,7 @@
/datum/supply_packs/atmos/disposals_dispenser
contains = list(/obj/machinery/pipedispenser/disposal/orderable)
name = "Disposals Pipe Dispenser"
- cost = 35
+ cost = 25
containertype = /obj/structure/closet/crate/secure/large
containername = "Disposal Dispenser Crate"
access = access_atmospherics
\ No newline at end of file
diff --git a/code/datums/supplypacks/contraband.dm b/code/datums/supplypacks/contraband.dm
index fa8c237fe8..14761d6cd9 100644
--- a/code/datums/supplypacks/contraband.dm
+++ b/code/datums/supplypacks/contraband.dm
@@ -14,7 +14,7 @@
)
name = "Contraband crate"
- cost = 30
+ cost = 25
containertype = /obj/structure/closet/crate
containername = "Unlabeled crate"
contraband = 1
@@ -28,7 +28,7 @@
/obj/item/weapon/pen/reagent/paralysis,
/obj/item/weapon/grenade/chem_grenade/incendiary
)
- cost = 20
+ cost = 25
containertype = /obj/structure/closet/crate
containername = "Special Ops crate"
hidden = 1
diff --git a/code/datums/supplypacks/costumes.dm b/code/datums/supplypacks/costumes.dm
index c0b11b16bc..cb5a950bfe 100644
--- a/code/datums/supplypacks/costumes.dm
+++ b/code/datums/supplypacks/costumes.dm
@@ -5,10 +5,10 @@
/datum/supply_packs/costumes
- group = "Costumes & Clothes"
+ group = "Costumes"
/datum/supply_packs/randomised/costumes
- group = "Costumes & Clothes"
+ group = "Costumes"
/datum/supply_packs/costumes/wizard
name = "Wizard costume"
@@ -109,7 +109,7 @@
containertype = /obj/structure/closet
containername = "Formalwear for the best occasions."
-datum/supply_packs/misc/witch
+datum/supply_packs/costumes/witch
name = "Witch costume"
containername = "Witch costume"
containertype = /obj/structure/closet
@@ -124,7 +124,7 @@ datum/supply_packs/misc/witch
/datum/supply_packs/randomised/costumes/costume_hats
name = "Costume hats"
containername = "Actor hats crate"
- containertype = /obj/structure/closet
+ containertype = /obj/structure/closet/crate
cost = 10
num_contained = 3
contains = list(
diff --git a/code/datums/supplypacks/engineering.dm b/code/datums/supplypacks/engineering.dm
index 900419d0d3..fd3c130b61 100644
--- a/code/datums/supplypacks/engineering.dm
+++ b/code/datums/supplypacks/engineering.dm
@@ -29,7 +29,7 @@
/obj/item/weapon/cell = 2,
/obj/item/weapon/cell/high = 2
)
- cost = 15
+ cost = 10
containertype = /obj/structure/closet/crate
containername = "Electrical maintenance crate"
@@ -48,7 +48,7 @@
/datum/supply_packs/eng/fueltank
name = "Fuel tank crate"
contains = list(/obj/structure/reagent_dispensers/fueltank)
- cost = 8
+ cost = 10
containertype = /obj/structure/largecrate
containername = "fuel tank crate"
@@ -110,7 +110,7 @@
/datum/supply_packs/eng/shield_gen
contains = list(/obj/item/weapon/circuitboard/shield_gen)
name = "Bubble shield generator circuitry"
- cost = 50
+ cost = 30
containertype = /obj/structure/closet/crate/secure
containername = "bubble shield generator circuitry crate"
access = access_ce
@@ -118,7 +118,7 @@
/datum/supply_packs/eng/shield_gen_ex
contains = list(/obj/item/weapon/circuitboard/shield_gen_ex)
name = "Hull shield generator circuitry"
- cost = 50
+ cost = 30
containertype = /obj/structure/closet/crate/secure
containername = "hull shield generator circuitry crate"
access = access_ce
@@ -126,7 +126,7 @@
/datum/supply_packs/eng/shield_cap
contains = list(/obj/item/weapon/circuitboard/shield_cap)
name = "Bubble shield capacitor circuitry"
- cost = 50
+ cost = 30
containertype = /obj/structure/closet/crate/secure
containername = "shield capacitor circuitry crate"
access = access_ce
@@ -142,7 +142,7 @@
/datum/supply_packs/eng/teg
contains = list(/obj/machinery/power/generator)
name = "Mark I Thermoelectric Generator"
- cost = 75
+ cost = 50
containertype = /obj/structure/closet/crate/secure/large
containername = "Mk1 TEG crate"
access = access_engine
@@ -150,7 +150,7 @@
/datum/supply_packs/eng/circulator
contains = list(/obj/machinery/atmospherics/binary/circulator)
name = "Binary atmospheric circulator"
- cost = 60
+ cost = 50
containertype = /obj/structure/closet/crate/secure/large
containername = "Atmospheric circulator crate"
access = access_engine
@@ -167,7 +167,7 @@
/datum/supply_packs/eng/pacman_parts
name = "P.A.C.M.A.N. portable generator parts"
- cost = 45
+ cost = 25
containername = "P.A.C.M.A.N. Portable Generator Construction Kit"
containertype = /obj/structure/closet/crate/secure
access = access_tech_storage
@@ -180,7 +180,7 @@
/datum/supply_packs/eng/super_pacman_parts
name = "Super P.A.C.M.A.N. portable generator parts"
- cost = 55
+ cost = 35
containername = "Super P.A.C.M.A.N. portable generator construction kit"
containertype = /obj/structure/closet/crate/secure
access = access_tech_storage
diff --git a/code/datums/supplypacks/hospitality.dm b/code/datums/supplypacks/hospitality.dm
index 6dd421b243..0e245f1921 100644
--- a/code/datums/supplypacks/hospitality.dm
+++ b/code/datums/supplypacks/hospitality.dm
@@ -22,7 +22,7 @@
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/ale = 2,
/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer = 4,
)
- cost = 20
+ cost = 10
containertype = /obj/structure/closet/crate
containername = "Party equipment"
diff --git a/code/datums/supplypacks/hydroponics.dm b/code/datums/supplypacks/hydroponics.dm
index a9a26fd561..25f06143d0 100644
--- a/code/datums/supplypacks/hydroponics.dm
+++ b/code/datums/supplypacks/hydroponics.dm
@@ -17,21 +17,21 @@
/datum/supply_packs/hydro/farwa
name = "Farwa crate"
contains = list (/obj/item/weapon/storage/box/monkeycubes/farwacubes)
- cost = 30
+ cost = 20
containertype = /obj/structure/closet/crate/freezer
containername = "Farwa crate"
/datum/supply_packs/hydro/neara
name = "Neaera crate"
contains = list (/obj/item/weapon/storage/box/monkeycubes/neaeracubes)
- cost = 30
+ cost = 20
containertype = /obj/structure/closet/crate/freezer
containername = "Neaera crate"
/datum/supply_packs/hydro/stok
name = "Stok crate"
contains = list (/obj/item/weapon/storage/box/monkeycubes/stokcubes)
- cost = 30
+ cost = 20
containertype = /obj/structure/closet/crate/freezer
containername = "Stok crate"
@@ -55,14 +55,14 @@
/obj/item/weapon/material/minihoe,
/obj/item/weapon/storage/box/botanydisk
)
- cost = 15
+ cost = 20
containertype = /obj/structure/closet/crate/hydroponics
containername = "Hydroponics crate"
access = access_hydroponics
/datum/supply_packs/hydro/cow
name = "Cow crate"
- cost = 30
+ cost = 25
containertype = /obj/structure/largecrate/animal/cow
containername = "Cow crate"
access = access_hydroponics
@@ -76,7 +76,7 @@
/datum/supply_packs/hydro/chicken
name = "Chicken crate"
- cost = 20
+ cost = 25
containertype = /obj/structure/largecrate/animal/chick
containername = "Chicken crate"
access = access_hydroponics
@@ -123,7 +123,7 @@
/datum/supply_packs/hydro/watertank
name = "Water tank crate"
contains = list(/obj/structure/reagent_dispensers/watertank)
- cost = 8
+ cost = 10
containertype = /obj/structure/largecrate
containername = "water tank crate"
@@ -142,7 +142,7 @@
/datum/supply_packs/hydro/tray
name = "Empty hydroponics tray"
- cost = 30
+ cost = 20
containertype = /obj/structure/closet/crate/hydroponics
containername = "Hydroponics tray crate"
contains = list(/obj/machinery/portable_atmospherics/hydroponics{anchored = 0})
diff --git a/code/datums/supplypacks/medical.dm b/code/datums/supplypacks/medical.dm
index c7cc7dc575..3972114440 100644
--- a/code/datums/supplypacks/medical.dm
+++ b/code/datums/supplypacks/medical.dm
@@ -42,7 +42,7 @@
/datum/supply_packs/med/cryobag
name = "Stasis bag crate"
contains = list(/obj/item/bodybag/cryobag = 3)
- cost = 50
+ cost = 40
containertype = /obj/structure/closet/crate/medical
containername = "Stasis bag crate"
@@ -75,7 +75,7 @@
/obj/item/weapon/storage/box/gloves,
/obj/item/weapon/storage/belt/medical = 3
)
- cost = 15
+ cost = 10
containertype = "/obj/structure/closet/crate"
containername = "Sterile equipment crate"
@@ -87,7 +87,7 @@
/obj/item/device/radio/headset/headset_med/alt = 3,
/obj/item/clothing/suit/storage/hooded/wintercoat/medical = 3
)
- cost = 15
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Medical surplus equipment"
access = access_medical
@@ -111,7 +111,7 @@
/obj/item/device/flashlight/pen,
/obj/item/weapon/reagent_containers/syringe
)
- cost = 60
+ cost = 50
containertype = "/obj/structure/closet/crate/secure"
containername = "Chief medical officer equipment"
access = access_cmo
@@ -157,7 +157,7 @@
/obj/item/weapon/storage/box/pillbottles,
/obj/item/weapon/reagent_containers/syringe
)
- cost = 15
+ cost = 20
containertype = "/obj/structure/closet/crate/secure"
containername = "Chemist equipment"
access = access_chemistry
@@ -204,7 +204,7 @@
/obj/item/weapon/pen,
/obj/item/weapon/cartridge/medical
)
- cost = 15
+ cost = 20
containertype = "/obj/structure/closet/crate/secure"
containername = "Psychiatrist equipment"
access = access_psychiatrist
@@ -225,7 +225,7 @@
/obj/item/weapon/storage/box/masks,
/obj/item/weapon/storage/box/gloves
)
- cost = 15
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Medical scrubs crate"
access = access_medical_equip
@@ -269,7 +269,7 @@
/obj/item/weapon/storage/box/masks,
/obj/item/weapon/storage/box/gloves
)
- cost = 15
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Medical uniform crate"
access = access_medical_equip
diff --git a/code/datums/supplypacks/misc.dm b/code/datums/supplypacks/misc.dm
index 80c25b48a3..21b8481854 100644
--- a/code/datums/supplypacks/misc.dm
+++ b/code/datums/supplypacks/misc.dm
@@ -67,7 +67,7 @@
/obj/item/clothing/accessory/storage/white_drop_pouches,
/obj/item/clothing/accessory/storage/webbing
)
- cost = 15
+ cost = 10
containertype = "/obj/structure/closet/crate"
containername = "Webbing crate"
@@ -92,6 +92,6 @@
/obj/item/clothing/head/helmet/space/emergency = 4,
/obj/item/clothing/mask/gas = 4
)
- cost = 45
+ cost = 35
containertype = /obj/structure/closet/crate/internals
containername = "Emergency crate"
\ No newline at end of file
diff --git a/code/datums/supplypacks/munitions.dm b/code/datums/supplypacks/munitions.dm
index a33c9accac..8edee72239 100644
--- a/code/datums/supplypacks/munitions.dm
+++ b/code/datums/supplypacks/munitions.dm
@@ -40,7 +40,7 @@
contains = list(
/obj/item/weapon/gun/energy/xray = 2,
/obj/item/weapon/shield/energy = 2)
- cost = 125
+ cost = 100
containertype = /obj/structure/closet/crate/secure/weapon
containername = "Experimental weapons crate"
access = access_armory
@@ -60,7 +60,7 @@
/obj/item/weapon/storage/box/shotgunshells,
/obj/item/weapon/gun/projectile/shotgun/pump/combat = 2
)
- cost = 65
+ cost = 50
containertype = /obj/structure/closet/crate/secure
containername = "Shotgun crate"
access = access_armory
@@ -68,7 +68,7 @@
/datum/supply_packs/munitions/erifle
name = "Energy marksman crate"
contains = list(/obj/item/weapon/gun/energy/sniperrifle = 2)
- cost = 90
+ cost = 100
containertype = /obj/structure/closet/crate/secure
containername = "Energy marksman crate"
access = access_armory
@@ -91,7 +91,7 @@
/obj/item/weapon/gun/projectile/automatic/wt550,
/obj/item/weapon/gun/projectile/automatic/z8
)
- cost = 90
+ cost = 100
containertype = /obj/structure/closet/crate/secure
containername = "Automatic weapon crate"
access = access_armory
@@ -119,12 +119,12 @@
containername = "Weapons crate"
/datum/supply_packs/munitions/shotgunammo
- name = "Ballistic ammunition crate"
+ name = "Shotgun ammunition crate"
contains = list(
/obj/item/weapon/storage/box/shotgunammo = 2,
/obj/item/weapon/storage/box/shotgunshells = 2
)
- cost = 60
+ cost = 25
containertype = /obj/structure/closet/crate/secure
containername = "ballistic ammunition crate"
access = access_armory
@@ -137,7 +137,7 @@
/obj/item/ammo_magazine/mc9mmt/rubber,
/obj/item/ammo_magazine/a556
)
- cost = 20
+ cost = 25
containertype = /obj/structure/closet/crate/secure
containername = "Automatic weapon ammunition crate"
access = access_armory
@@ -145,7 +145,7 @@
/datum/supply_packs/munitions/beanbagammo
name = "Beanbag shells"
contains = list(/obj/item/weapon/storage/box/beanbags = 3)
- cost = 30
+ cost = 25
containertype = /obj/structure/closet/crate
containername = "Beanbag shells"
access = null
diff --git a/code/datums/supplypacks/recreation.dm b/code/datums/supplypacks/recreation.dm
index 18895b48f4..7bfdaaeeb6 100644
--- a/code/datums/supplypacks/recreation.dm
+++ b/code/datums/supplypacks/recreation.dm
@@ -19,7 +19,7 @@
/obj/item/weapon/material/twohanded/spear/foam = 2,
/obj/item/weapon/material/twohanded/fireaxe/foam = 2
)
- cost = 80
+ cost = 50
containertype = /obj/structure/closet/crate
containername = "foam weapon crate"
@@ -33,7 +33,7 @@
)
containertype = /obj/structure/closet
containername = "Lasertag Closet"
- cost = 20
+ cost = 10
/datum/supply_packs/recreation/artscrafts
name = "Arts and Crafts supplies"
diff --git a/code/datums/supplypacks/robotics.dm b/code/datums/supplypacks/robotics.dm
index 090f3d2078..f2ab73b824 100644
--- a/code/datums/supplypacks/robotics.dm
+++ b/code/datums/supplypacks/robotics.dm
@@ -58,7 +58,7 @@
/obj/item/weapon/circuitboard/mecha/ripley/main,
/obj/item/weapon/circuitboard/mecha/ripley/peripherals
)
- cost = 30
+ cost = 25
containertype = /obj/structure/closet/crate/secure
containername = "APLU \"Ripley\" Circuit Crate"
access = access_robotics
diff --git a/code/datums/supplypacks/science.dm b/code/datums/supplypacks/science.dm
index 36b51dbd42..135af8de24 100644
--- a/code/datums/supplypacks/science.dm
+++ b/code/datums/supplypacks/science.dm
@@ -16,7 +16,7 @@
/datum/supply_packs/sci/coolanttank
name = "Coolant tank crate"
contains = list(/obj/structure/reagent_dispensers/coolanttank)
- cost = 16
+ cost = 15
containertype = /obj/structure/largecrate
containername = "coolant tank crate"
diff --git a/code/datums/supplypacks/security.dm b/code/datums/supplypacks/security.dm
index 483d8e0c12..6c45e5c036 100644
--- a/code/datums/supplypacks/security.dm
+++ b/code/datums/supplypacks/security.dm
@@ -82,7 +82,7 @@
/obj/item/clothing/gloves/arm_guard/bulletproof,
/obj/item/clothing/shoes/leg_guard/bulletproof
)
- cost = 35
+ cost = 40
containertype = /obj/structure/closet/crate/secure
containername = "bullet resistant armor set crate"
access = access_armory
@@ -104,7 +104,7 @@
name = "Tactical suits"
containertype = /obj/structure/closet/crate/secure
containername = "Tactical Suit Locker"
- cost = 60
+ cost = 40
access = access_armory
contains = list(
/obj/item/clothing/under/tactical,
@@ -162,7 +162,7 @@
/obj/item/device/radio/headset/headset_sec/alt = 3,
/obj/item/clothing/suit/storage/hooded/wintercoat/security = 3
)
- cost = 25
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Security surplus equipment"
access = null
@@ -189,7 +189,7 @@
/obj/item/device/flashlight/maglight,
/obj/item/weapon/storage/briefcase/crimekit
)
- cost = 40
+ cost = 20
containertype = "/obj/structure/closet/crate/secure"
containername = "Forensic equipment"
access = access_forensics_lockers
@@ -210,7 +210,7 @@
/obj/item/clothing/accessory/badge/holo/detective = 2,
/obj/item/clothing/gloves/black = 2
)
- cost = 20
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Investigation clothing"
access = access_forensics_lockers
@@ -240,7 +240,7 @@
/obj/item/weapon/gun/energy/taser,
/obj/item/device/flashlight/maglight
)
- cost = 30
+ cost = 20
containertype = "/obj/structure/closet/crate/secure"
containername = "Officer equipment"
access = access_brig
@@ -268,7 +268,7 @@
/obj/item/clothing/head/beret/sec/corporate/warden,
/obj/item/device/flashlight/maglight
)
- cost = 45
+ cost = 20
containertype = "/obj/structure/closet/crate/secure"
containername = "Warden equipment"
access = access_armory
@@ -294,7 +294,7 @@
/obj/item/clothing/head/beret/sec/corporate/hos,
/obj/item/device/flashlight/maglight
)
- cost = 65
+ cost = 50
containertype = "/obj/structure/closet/crate/secure"
containername = "Head of security equipment"
access = access_hos
@@ -314,7 +314,7 @@
/obj/item/clothing/gloves/black = 4,
/obj/item/weapon/storage/box/holobadge
)
- cost = 20
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Security uniform crate"
@@ -335,7 +335,7 @@
/obj/item/clothing/gloves/black = 4,
/obj/item/weapon/storage/box/holobadge
)
- cost = 20
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Navy blue security uniform crate"
@@ -355,21 +355,22 @@
/obj/item/clothing/gloves/black = 4,
/obj/item/weapon/storage/box/holobadge
)
- cost = 20
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Corporate security uniform crate"
/datum/supply_packs/security/biosuit
name = "Security biohazard gear"
contains = list(
- /obj/item/clothing/head/bio_hood/security,
- /obj/item/clothing/under/rank/security,
- /obj/item/clothing/suit/bio_suit/security,
- /obj/item/clothing/shoes/white,
- /obj/item/clothing/mask/gas,
- /obj/item/weapon/tank/oxygen,
- /obj/item/clothing/gloves/latex
+ /obj/item/clothing/head/bio_hood/security = 3,
+ /obj/item/clothing/under/rank/security = 3,
+ /obj/item/clothing/suit/bio_suit/security = 3,
+ /obj/item/clothing/shoes/white = 3,
+ /obj/item/clothing/mask/gas = 3,
+ /obj/item/weapon/tank/oxygen = 3,
+ /obj/item/clothing/gloves/latex,
+ /obj/item/weapon/storage/box/gloves
)
- cost = 35
+ cost = 50
containertype = "/obj/structure/closet/crate/secure"
containername = "Security biohazard gear"
diff --git a/code/datums/supplypacks/supply.dm b/code/datums/supplypacks/supply.dm
index e9832b3657..3f143c88d6 100644
--- a/code/datums/supplypacks/supply.dm
+++ b/code/datums/supplypacks/supply.dm
@@ -103,7 +103,7 @@
/obj/item/clothing/glasses/material,
/obj/item/clothing/glasses/meson
)
- cost = 15
+ cost = 10
containertype = "/obj/structure/closet/crate/secure"
containername = "Shaft miner equipment"
access = access_mining
@@ -118,7 +118,7 @@
/datum/supply_packs/supply/cargotrain
name = "Cargo Train Tug"
contains = list(/obj/vehicle/train/cargo/engine)
- cost = 45
+ cost = 35
containertype = /obj/structure/largecrate
containername = "Cargo Train Tug Crate"
diff --git a/code/datums/supplypacks/supplypacks.dm b/code/datums/supplypacks/supplypacks.dm
index 7bb66875ac..c62231285c 100644
--- a/code/datums/supplypacks/supplypacks.dm
+++ b/code/datums/supplypacks/supplypacks.dm
@@ -7,12 +7,14 @@
//var/list/all_supply_groups = list("Operations","Security","Hospitality","Engineering","Atmospherics","Medical","Reagents","Reagent Cartridges","Science","Hydroponics", "Supply", "Miscellaneous")
var/list/all_supply_groups = list("Atmospherics",
- "Costumes & Clothes",
+ "Costumes",
"Engineering",
"Hospitality",
+ "Hydroponics",
"Materials",
"Medical",
"Miscellaneous",
+ "Munitions",
"Reagents",
"Reagent Cartridges",
"Recreation",
diff --git a/code/datums/supplypacks/voidsuits.dm b/code/datums/supplypacks/voidsuits.dm
index 3d37bd171a..6bf5c0f5b3 100644
--- a/code/datums/supplypacks/voidsuits.dm
+++ b/code/datums/supplypacks/voidsuits.dm
@@ -16,7 +16,7 @@
/obj/item/clothing/shoes/magboots = 2,
/obj/item/weapon/tank/oxygen = 2,
)
- cost = 45
+ cost = 40
containertype = "/obj/structure/closet/crate/secure"
containername = "Atmospheric voidsuit crate"
access = access_atmospherics
@@ -58,7 +58,7 @@
/obj/item/clothing/shoes/magboots = 2,
/obj/item/weapon/tank/oxygen = 2
)
- cost = 55
+ cost = 40
containertype = "/obj/structure/closet/crate/secure"
containername = "Security voidsuit crate"
@@ -70,7 +70,7 @@
/obj/item/clothing/mask/breath = 2,
/obj/item/weapon/tank/oxygen = 2
)
- cost = 35
+ cost = 40
containertype = "/obj/structure/closet/crate/secure"
containername = "Mining voidsuit crate"
access = access_mining
\ No newline at end of file
diff --git a/code/game/antagonist/antagonist.dm b/code/game/antagonist/antagonist.dm
index d91242ea8b..9c3a9476ac 100644
--- a/code/game/antagonist/antagonist.dm
+++ b/code/game/antagonist/antagonist.dm
@@ -99,19 +99,23 @@
// Prune restricted status. Broke it up for readability.
// Note that this is done before jobs are handed out.
- for(var/datum/mind/player in ticker.mode.get_players_for_role(role_type, id))
+ candidates = ticker.mode.get_players_for_role(role_type, id, ghosts_only)
+ for(var/datum/mind/player in candidates)
if(ghosts_only && !istype(player.current, /mob/observer/dead))
- log_debug("[key_name(player)] is not eligible to become a [role_text]: Only ghosts may join as this role!")
+ candidates -= player
+ log_debug("[key_name(player)] is not eligible to become a [role_text]: Only ghosts may join as this role! They have been removed from the draft.")
else if(player.special_role)
- log_debug("[key_name(player)] is not eligible to become a [role_text]: They already have a special role ([player.special_role])!")
+ candidates -= player
+ log_debug("[key_name(player)] is not eligible to become a [role_text]: They already have a special role ([player.special_role])! They have been removed from the draft.")
else if (player in pending_antagonists)
- log_debug("[key_name(player)] is not eligible to become a [role_text]: They have already been selected for this role!")
+ candidates -= player
+ log_debug("[key_name(player)] is not eligible to become a [role_text]: They have already been selected for this role! They have been removed from the draft.")
else if(!can_become_antag(player))
- log_debug("[key_name(player)] is not eligible to become a [role_text]: They are blacklisted for this role!")
+ candidates -= player
+ log_debug("[key_name(player)] is not eligible to become a [role_text]: They are blacklisted for this role! They have been removed from the draft.")
else if(player_is_antag(player))
- log_debug("[key_name(player)] is not eligible to become a [role_text]: They are already an antagonist!")
- else
- candidates += player
+ candidates -= player
+ log_debug("[key_name(player)] is not eligible to become a [role_text]: They are already an antagonist! They have been removed from the draft.")
return candidates
diff --git a/code/game/gamemodes/cult/cult_items.dm b/code/game/gamemodes/cult/cult_items.dm
index 1a0aa9e1c5..3cd2a496cb 100644
--- a/code/game/gamemodes/cult/cult_items.dm
+++ b/code/game/gamemodes/cult/cult_items.dm
@@ -8,6 +8,8 @@
throwforce = 10
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
+ edge = 1
+ sharp = 1
/obj/item/weapon/melee/cultblade/cultify()
return
diff --git a/code/game/gamemodes/cult/cultify/obj.dm b/code/game/gamemodes/cult/cultify/obj.dm
index 83dfc857be..d7c0cff5ec 100644
--- a/code/game/gamemodes/cult/cultify/obj.dm
+++ b/code/game/gamemodes/cult/cultify/obj.dm
@@ -50,7 +50,7 @@
src.invisibility = INVISIBILITY_MAXIMUM
density = 0
-/obj/machinery/cooking/cultify()
+/obj/machinery/cooker/cultify()
new /obj/structure/cult/talisman(loc)
qdel(src)
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 3cb41cc872..91d802c8bf 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -465,7 +465,6 @@ var/list/sacrificed = list()
break
D.universal_speak = 1
D.status_flags &= ~GODMODE
- D.s_tone = 35
D.b_eyes = 200
D.r_eyes = 200
D.g_eyes = 200
@@ -1052,7 +1051,7 @@ var/list/sacrificed = list()
for(var/mob/living/L in viewers(src))
if(iscarbon(L))
var/mob/living/carbon/C = L
- flick("e_flash", C.flash)
+ C.flash_eyes()
if(C.stuttering < 1 && (!(HULK in C.mutations)))
C.stuttering = 1
C.Weaken(1)
@@ -1081,7 +1080,7 @@ var/list/sacrificed = list()
admin_attack_log(usr, T, "Used a stun rune.", "Was victim of a stun rune.", "used a stun rune on")
else if(iscarbon(T))
var/mob/living/carbon/C = T
- flick("e_flash", C.flash)
+ C.flash_eyes()
if (!(HULK in C.mutations))
C.silent += 15
C.Weaken(25)
diff --git a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
index 3374f8f9be..d42d684d56 100644
--- a/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
+++ b/code/game/gamemodes/endgame/supermatter_cascade/universe.dm
@@ -43,7 +43,7 @@ var/global/universe_has_ended = 0
world << sound('sound/effects/cascade.ogg')
for(var/mob/M in player_list)
- flick("e_flash", M.flash)
+ M.flash_eyes()
if(emergency_shuttle.can_recall())
priority_announcement.Announce("The emergency shuttle has returned due to bluespace distortion.")
@@ -122,6 +122,6 @@ The access requirements on the Asteroid Shuttles' consoles have now been revoked
continue
if(M.current.stat!=2)
M.current.Weaken(10)
- flick("e_flash", M.current.flash)
+ M.current.flash_eyes()
clear_antag_roles(M)
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 2aa1d2b024..60d968bba0 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -372,7 +372,7 @@ var/global/list/additional_antag_types = list()
/datum/game_mode/proc/check_win() //universal trigger to be called at mob death, nuke explosion, etc. To be called from everywhere.
return 0
-/datum/game_mode/proc/get_players_for_role(var/role, var/antag_id)
+/datum/game_mode/proc/get_players_for_role(var/role, var/antag_id, var/ghosts_only)
var/list/players = list()
var/list/candidates = list()
@@ -387,6 +387,8 @@ var/global/list/additional_antag_types = list()
continue
if(istype(player, /mob/new_player))
continue
+ if(istype(player, /mob/observer/dead) && !ghosts_only)
+ continue
if(!role || (player.client.prefs.be_special & role))
log_debug("[player.key] had [antag_id] enabled, so we are drafting them.")
candidates |= player.mind
diff --git a/code/game/jobs/job/captain.dm b/code/game/jobs/job/captain.dm
index 69f837d8f9..514d3cf047 100644
--- a/code/game/jobs/job/captain.dm
+++ b/code/game/jobs/job/captain.dm
@@ -30,13 +30,13 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/captain(H), slot_back)
if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel/cap(H), slot_back)
if(4) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel(H), slot_back)
- H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/captain(H), slot_w_uniform)
+ H.equip_to_slot_or_del(new /obj/item/clothing/under/rank/captain(H), slot_w_uniform)
if(H.age>49)
- // Since we can have something other than the default uniform at this
+ // Since we can have something other than the default uniform at this
// point, check if we can actually attach the medal
var/obj/item/clothing/uniform = H.w_uniform
var/obj/item/clothing/accessory/medal/gold/captain/medal = new()
-
+
if(uniform && uniform.can_attach_accessory(medal))
uniform.attach_accessory(null, medal)
else
@@ -72,6 +72,7 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
supervisors = "the captain"
selection_color = "#2F2F7F"
idtype = /obj/item/weapon/card/id/silver
+ alt_titles = list("Crew Resources Officer")
req_admin_notify = 1
minimal_player_age = 10
economic_modifier = 10
@@ -107,4 +108,5 @@ var/datum/announcement/minor/captain_announcement = new(do_newscast = 1)
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/ids(H), slot_l_hand)
else
H.equip_to_slot_or_del(new /obj/item/weapon/storage/box/ids(H.back), slot_in_backpack)
- return 1
+ H.implant_loyalty()
+ return 1
\ No newline at end of file
diff --git a/code/game/machinery/adv_med.dm b/code/game/machinery/adv_med.dm
index eab6da38ca..6f08a35601 100644
--- a/code/game/machinery/adv_med.dm
+++ b/code/game/machinery/adv_med.dm
@@ -9,13 +9,23 @@
icon_state = "body_scanner_0"
density = 1
anchored = 1
+
circuit = /obj/item/weapon/circuitboard/body_scanner
use_power = 1
idle_power_usage = 60
active_power_usage = 10000 //10 kW. It's a big all-body scanner.
+ light_color = "#00FF00"
+
/obj/machinery/bodyscanner/New()
+ ..()
+ spawn( 5 )
+ var/obj/machinery/body_scanconsole/C = locate(/obj/machinery/body_scanconsole) in range(2,src)
+ if(C)
+ C.connected = src
+
+/obj/machinery/bodyscanner/map/New()
..()
circuit = new circuit(src)
component_parts = list()
@@ -23,81 +33,14 @@
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/stack/material/glass/reinforced(src, 2)
-
- spawn( 5 )
- var/obj/machinery/body_scanconsole/C = locate(/obj/machinery/body_scanconsole) in range(2,src)
- if(C)
- C.connected = src
- return
-
RefreshParts()
-/obj/machinery/bodyscanner/relaymove(mob/user as mob)
- if (user.stat)
- return
- src.go_out()
- return
-
-/obj/machinery/bodyscanner/verb/eject()
- set src in oview(1)
- set category = "Object"
- set name = "Eject Body Scanner"
-
- if (usr.stat != 0)
- return
- src.go_out()
- add_fingerprint(usr)
- return
-
-/obj/machinery/bodyscanner/verb/move_inside()
- set src in oview(1)
- set category = "Object"
- set name = "Enter Body Scanner"
-
- if (usr.stat != 0)
- return
- if (src.occupant)
- usr << "The scanner is already occupied!"
- return
- if (usr.abiotic())
- usr << "The subject cannot have abiotic items on."
- return
- usr.pulling = null
- usr.client.perspective = EYE_PERSPECTIVE
- usr.client.eye = src
- usr.loc = src
- src.occupant = usr
- update_use_power(2)
- src.icon_state = "body_scanner_1"
- for(var/obj/O in src)
- //O = null
- if(O in component_parts)
- continue
- if(O == circuit)
- continue
- qdel(O)
- //Foreach goto(124)
- src.add_fingerprint(usr)
- return
-
-/obj/machinery/bodyscanner/proc/go_out()
- if ((!( src.occupant ) || src.locked))
- return
- for(var/obj/O in src)
- if(O in component_parts)
- continue
- if(O == circuit)
- continue
- O.loc = src.loc
- //Foreach goto(30)
- if (src.occupant.client)
- src.occupant.client.eye = src.occupant.client.mob
- src.occupant.client.perspective = MOB_PERSPECTIVE
- src.occupant.loc = src.loc
- src.occupant = null
- update_use_power(1)
- src.icon_state = "body_scanner_0"
- return
+/obj/machinery/bodyscanner/power_change()
+ ..()
+ if(!(stat & (BROKEN|NOPOWER)))
+ set_light(2)
+ else
+ set_light(0)
/obj/machinery/bodyscanner/attackby(var/obj/item/G, user as mob)
if(default_deconstruction_screwdriver(user, G))
@@ -107,42 +50,96 @@
if(istype(G, /obj/item/weapon/grab))
var/obj/item/weapon/grab/H = G
- if(!(ismob(H.affecting)))
+ if(panel_open)
+ user << "Close the maintenance panel first."
return
- if (src.occupant)
- user << "The scanner is already occupied!"
+ if(!ismob(H.affecting))
return
- if (H.affecting.abiotic())
- user << "Subject cannot have abiotic items on."
+ if(occupant)
+ user << "The scanner is already occupied!"
return
+ for(var/mob/living/carbon/slime/M in range(1, H.affecting))
+ if(M.Victim == H.affecting)
+ user << "[H.affecting.name] has a fucking slime attached to them, deal with that first."
+ return
var/mob/M = H.affecting
- if (M.client)
- M.client.perspective = EYE_PERSPECTIVE
- M.client.eye = src
- M.loc = src
- src.occupant = M
- update_use_power(2)
- src.icon_state = "body_scanner_1"
- for(var/obj/O in src)
- if(O in component_parts)
- continue
- if(O == circuit)
- continue
- O.loc = src.loc
- //Foreach goto(154)
- src.add_fingerprint(user)
- //G = null
+ if(M.abiotic())
+ user << "Subject cannot have abiotic items on."
+ return
+ M.forceMove(src)
+ occupant = M
+ icon_state = "body_scanner_1"
+ add_fingerprint(user)
qdel(G)
+
+/obj/machinery/bodyscanner/MouseDrop_T(mob/living/carbon/O, mob/user as mob)
+ if(!istype(O))
+ return 0 //not a mob
+ if(user.incapacitated())
+ return 0 //user shouldn't be doing things
+ if(O.anchored)
+ return 0 //mob is anchored???
+ if(get_dist(user, src) > 1 || get_dist(user, O) > 1)
+ return 0 //doesn't use adjacent() to allow for non-cardinal (fuck my life)
+ if(!ishuman(user) && !isrobot(user))
+ return 0 //not a borg or human
+ if(panel_open)
+ user << "Close the maintenance panel first."
+ return 0 //panel open
+ if(occupant)
+ user << "\The [src] is already occupied."
+ return 0 //occupied
+
+ if(O.buckled)
+ return 0
+ if(O.abiotic())
+ user << "Subject cannot have abiotic items on."
+ return 0
+ for(var/mob/living/carbon/slime/M in range(1, O))
+ if(M.Victim == O)
+ user << "[O] has a fucking slime attached to them, deal with that first."
+ return 0
+
+ if(O == user)
+ visible_message("[user] climbs into \the [src].")
+ else
+ visible_message("[user] puts [O] into the body scanner.")
+
+ O.forceMove(src)
+ occupant = O
+ icon_state = "body_scanner_1"
+ add_fingerprint(user)
+
+/obj/machinery/bodyscanner/relaymove(mob/user as mob)
+ if(user.incapacitated())
+ return 0 //maybe they should be able to get out with cuffs, but whatever
+ go_out()
+
+/obj/machinery/bodyscanner/verb/eject()
+ set src in oview(1)
+ set category = "Object"
+ set name = "Eject Body Scanner"
+
+ if(usr.incapacitated())
+ return
+ go_out()
+ add_fingerprint(usr)
+
+/obj/machinery/bodyscanner/proc/go_out()
+ if ((!( src.occupant ) || src.locked))
+ return
+ if (src.occupant.client)
+ src.occupant.client.eye = src.occupant.client.mob
+ src.occupant.client.perspective = MOB_PERSPECTIVE
+ src.occupant.loc = src.loc
+ src.occupant = null
+ src.icon_state = "body_scanner_0"
return
/obj/machinery/bodyscanner/ex_act(severity)
switch(severity)
if(1.0)
for(var/atom/movable/A as mob|obj in src)
- if(A in component_parts)
- continue
- if(A == circuit)
- continue
A.loc = src.loc
ex_act(severity)
//Foreach goto(35)
@@ -152,10 +149,6 @@
if(2.0)
if (prob(50))
for(var/atom/movable/A as mob|obj in src)
- if(A in component_parts)
- continue
- if(A == circuit)
- continue
A.loc = src.loc
ex_act(severity)
//Foreach goto(108)
@@ -165,10 +158,6 @@
if(3.0)
if (prob(25))
for(var/atom/movable/A as mob|obj in src)
- if(A in component_parts)
- continue
- if(A == circuit)
- continue
A.loc = src.loc
ex_act(severity)
//Foreach goto(181)
@@ -178,32 +167,7 @@
else
return
-/obj/machinery/body_scanconsole/ex_act(severity)
-
- switch(severity)
- if(1.0)
- //SN src = null
- qdel(src)
- return
- if(2.0)
- if (prob(50))
- //SN src = null
- qdel(src)
- return
- else
- return
-
-/obj/machinery/body_scanconsole/power_change()
- ..()
- if(stat & BROKEN)
- icon_state = "body_scannerconsole-p"
- else
- if (stat & NOPOWER)
- spawn(rand(0, 15))
- src.icon_state = "body_scannerconsole-p"
- else
- icon_state = initial(icon_state)
-
+//Body Scan Console
/obj/machinery/body_scanconsole
var/obj/machinery/bodyscanner/connected
var/known_implants = list(/obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking)
@@ -216,67 +180,12 @@
density = 0
anchored = 1
circuit = /obj/item/weapon/circuitboard/scanner_console
+ var/printing = null
+ var/printing_text = null
/obj/machinery/body_scanconsole/New()
..()
- spawn( 5 )
- src.connected = locate(/obj/machinery/bodyscanner) in range(2,src)
- return
- return
-
-/*
-
-/obj/machinery/body_scanconsole/process() //not really used right now
- if(stat & (NOPOWER|BROKEN))
- return
- //use_power(250) // power stuff
-
-// var/mob/M //occupant
-// if (!( src.status )) //remove this
-// return
-// if ((src.connected && src.connected.occupant)) //connected & occupant ok
-// M = src.connected.occupant
-// else
-// if (istype(M, /mob))
-// //do stuff
-// else
-/// src.temphtml = "Process terminated due to lack of occupant in scanning chamber."
-// src.status = null
-// src.updateDialog()
-// return
-
-*/
-
-/obj/machinery/body_scanconsole/attack_ai(user as mob)
- return src.attack_hand(user)
-
-/obj/machinery/body_scanconsole/attack_hand(user as mob)
- if(..())
- return
- if(stat & (NOPOWER|BROKEN))
- return
- if(!connected || (connected.stat & (NOPOWER|BROKEN)))
- user << "This console is not connected to a functioning body scanner."
- return
- if(!ishuman(connected.occupant))
- user << "This device can only scan compatible lifeforms."
- return
-
- var/dat
- if (src.delete && src.temphtml) //Window in buffer but its just simple message, so nothing
- src.delete = src.delete
- else if (!src.delete && src.temphtml) //Window in buffer - its a menu, dont add clear message
- dat = text("[]
Main Menu", src.temphtml, src)
- else
- if (src.connected) //Is something connected?
- dat = format_occupant_data(src.connected.get_occupant_data())
- dat += "
Print
"
- else
- dat = "Error: No Body Scanner connected."
-
- dat += text("
Close", user)
- user << browse(dat, "window=scanconsole;size=430x600")
- return
+ findscanner()
/obj/machinery/body_scanconsole/attackby(var/obj/item/I, var/mob/user)
if(istype(I, /obj/item/weapon/screwdriver) && circuit)
@@ -309,207 +218,365 @@
src.attack_hand(user)
return
-/obj/machinery/body_scanconsole/Topic(href, href_list)
- if (..())
- return
+/obj/machinery/body_scanconsole/power_change()
+ if(stat & BROKEN)
+ icon_state = "body_scannerconsole-p"
+ else if(powered() && !panel_open)
+ icon_state = initial(icon_state)
+ stat &= ~NOPOWER
+ else
+ spawn(rand(0, 15))
+ src.icon_state = "body_scannerconsole-p"
+ stat |= NOPOWER
- if (href_list["print"])
- if (!src.connected)
- usr << "\icon[src]Error: No body scanner connected."
+/obj/machinery/body_scanconsole/ex_act(severity)
+ switch(severity)
+ if(1.0)
+ //SN src = null
+ qdel(src)
return
- var/mob/living/carbon/human/occupant = src.connected.occupant
- if (!src.connected.occupant)
- usr << "\icon[src]The body scanner is empty."
- return
- if (!istype(occupant,/mob/living/carbon/human))
- usr << "\icon[src]The body scanner cannot scan that lifeform."
- return
- var/obj/item/weapon/paper/R = new(src.loc)
- R.name = "Body scan report"
- R.info = format_occupant_data(src.connected.get_occupant_data())
-
-
-/obj/machinery/bodyscanner/proc/get_occupant_data()
- if (!occupant || !istype(occupant, /mob/living/carbon/human))
- return
- var/mob/living/carbon/human/H = occupant
- var/list/occupant_data = list(
- "stationtime" = worldtime2text(),
- "stat" = H.stat,
- "health" = round(H.health/H.maxHealth)*100,
- "virus_present" = H.virus2.len,
- "bruteloss" = H.getBruteLoss(),
- "fireloss" = H.getFireLoss(),
- "oxyloss" = H.getOxyLoss(),
- "toxloss" = H.getToxLoss(),
- "rads" = H.radiation,
- "cloneloss" = H.getCloneLoss(),
- "brainloss" = H.getBrainLoss(),
- "paralysis" = H.paralysis,
- "bodytemp" = H.bodytemperature,
- "borer_present" = H.has_brain_worms(),
- "inaprovaline_amount" = H.reagents.get_reagent_amount("inaprovaline"),
- "dexalin_amount" = H.reagents.get_reagent_amount("dexalin"),
- "stoxin_amount" = H.reagents.get_reagent_amount("stoxin"),
- "bicaridine_amount" = H.reagents.get_reagent_amount("bicaridine"),
- "dermaline_amount" = H.reagents.get_reagent_amount("dermaline"),
- "blood_amount" = round((H.vessel.get_reagent_amount("blood") / H.species.blood_volume)*100),
- "disabilities" = H.sdisabilities,
- "lung_ruptured" = H.is_lung_ruptured(),
- "external_organs" = H.organs.Copy(),
- "internal_organs" = H.internal_organs.Copy(),
- "species_organs" = H.species.has_organ //Just pass a reference for this, it shouldn't ever be modified outside of the datum.
- )
- occupant_data = attempt_vr(src,"get_occupant_data_vr",list(occupant_data,H))
- return occupant_data
-
-
-/obj/machinery/body_scanconsole/proc/format_occupant_data(var/list/occ)
- var/dat = "Scan performed at [occ["stationtime"]]
"
- dat += "Occupant Statistics:
"
- var/aux
- switch (occ["stat"])
- if(0)
- aux = "Conscious"
- if(1)
- aux = "Unconscious"
+ if(2.0)
+ if (prob(50))
+ //SN src = null
+ qdel(src)
+ return
else
- aux = "Dead"
- dat += text("[]\tHealth %: [] ([])
", ("Viral pathogen detected in blood stream.
"
- dat += text("[]\t-Brute Damage %: []
", (""), occ["bruteloss"])
- dat += text("[]\t-Respiratory Damage %: []
", (""), occ["oxyloss"])
- dat += text("[]\t-Toxin Content %: []
", (""), occ["toxloss"])
- dat += text("[]\t-Burn Severity %: []
", (""), occ["fireloss"])
+ return
- dat += text("[]\tRadiation Level %: []
", (""), occ["rads"])
- dat += text("[]\tGenetic Tissue Damage %: []
", (""), occ["cloneloss"])
- dat += text("[]\tApprox. Brain Damage %: []
", (""), occ["brainloss"])
- dat += text("Paralysis Summary %: [] ([] seconds left!)
", occ["paralysis"], round(occ["paralysis"] / 4))
- dat += text("Body Temperature: [occ["bodytemp"]-T0C]°C ([occ["bodytemp"]*1.8-459.67]°F)
")
- dat += attempt_vr(src,"format_occupant_data_vr",list(occ))
- if(occ["borer_present"])
- dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
"
+/obj/machinery/body_scanconsole/proc/findscanner()
+ spawn( 5 )
+ var/obj/machinery/bodyscanner/bodyscannernew = null
+ // Loop through every direction
+ for(dir in list(NORTH,EAST,SOUTH,WEST))
+ // Try to find a scanner in that direction
+ bodyscannernew = locate(/obj/machinery/bodyscanner, get_step(src, dir))
+ src.connected = bodyscannernew
+ return
- dat += text("[]\tBlood Level %: [] ([] units)
", (""), occ["blood_amount"], occ["blood_amount"])
+/obj/machinery/body_scanconsole/attack_ai(user as mob)
+ return attack_hand(user)
- dat += text("Inaprovaline: [] units
", occ["inaprovaline_amount"])
- dat += text("Soporific: [] units
", occ["stoxin_amount"])
- dat += text("[]\tDermaline: [] units
", (""), occ["dermaline_amount"])
- dat += text("[]\tBicaridine: [] units
", (""), occ["bicaridine_amount"])
- dat += text("[]\tDexalin: [] units
", (""), occ["dexalin_amount"])
+/obj/machinery/body_scanconsole/attack_ghost(user as mob)
+ return attack_hand(user)
- dat += "
"
- dat += ""
- dat += "| Organ | "
- dat += "Burn Damage | "
- dat += "Brute Damage | "
- dat += "Other Wounds | "
- dat += "
"
+/obj/machinery/body_scanconsole/attack_hand(user as mob)
+ if(stat & (NOPOWER|BROKEN))
+ return
- for(var/obj/item/organ/external/e in occ["external_organs"])
- var/AN = ""
- var/open = ""
- var/infected = ""
- var/imp = ""
- var/bled = ""
- var/robot = ""
- var/splint = ""
- var/internal_bleeding = ""
- var/lung_ruptured = ""
+ if (panel_open)
+ user << "Close the maintenance panel first."
+ return
- dat += ""
+ if(!src.connected)
+ findscanner()
- for(var/datum/wound/W in e.wounds) if(W.internal)
- internal_bleeding = "
Internal bleeding"
- break
- if(istype(e, /obj/item/organ/external/chest) && occ["lung_ruptured"])
- lung_ruptured = "Lung ruptured:"
- if(e.status & ORGAN_SPLINTED)
- splint = "Splinted:"
- if(e.status & ORGAN_BLEEDING)
- bled = "Bleeding:"
- if(e.status & ORGAN_BROKEN)
- AN = "[e.broken_description]:"
- switch(e.robotic)
- if(ORGAN_ROBOT) robot = "Prosthetic:"
- if(ORGAN_ASSISTED) robot = "Augmented:"
- if(e.open)
- open = "Open:"
+ ui_interact(user)
- switch (e.germ_level)
- if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200)
- infected = "Mild Infection:"
- if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
- infected = "Mild Infection+:"
- if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
- infected = "Mild Infection++:"
- if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
- infected = "Acute Infection:"
- if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
- infected = "Acute Infection+:"
- if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400)
- infected = "Acute Infection++:"
- if (INFECTION_LEVEL_THREE to INFINITY)
- infected = "Septic:"
- if(e.rejecting)
- infected += "(being rejected)"
- if (e.implants.len)
- var/unknown_body = 0
- for(var/I in e.implants)
- if(is_type_in_list(I,known_implants))
- imp += "[I] implanted:"
+/obj/machinery/body_scanconsole/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ var/data[0]
+
+ data["connected"] = connected ? 1 : 0
+
+ if(connected)
+ data["occupied"] = connected.occupant ? 1 : 0
+
+ var/occupantData[0]
+ if(connected.occupant && ishuman(connected.occupant))
+ var/mob/living/carbon/human/H = connected.occupant
+ occupantData["name"] = H.name
+ occupantData["stat"] = H.stat
+ occupantData["health"] = H.health
+
+ occupantData["hasVirus"] = H.virus2.len
+
+ occupantData["bruteLoss"] = H.getBruteLoss()
+ occupantData["oxyLoss"] = H.getOxyLoss()
+ occupantData["toxLoss"] = H.getToxLoss()
+ occupantData["fireLoss"] = H.getFireLoss()
+
+ occupantData["radLoss"] = H.radiation
+ occupantData["cloneLoss"] = H.getCloneLoss()
+ occupantData["brainLoss"] = H.getBrainLoss()
+ occupantData["paralysis"] = H.paralysis
+ occupantData["paralysisSeconds"] = round(H.paralysis / 4)
+ occupantData["bodyTempC"] = H.bodytemperature-T0C
+ occupantData["bodyTempF"] = (((H.bodytemperature-T0C) * 1.8) + 32)
+
+ occupantData["hasBorer"] = H.has_brain_worms()
+
+ var/bloodData[0]
+ if(H.vessel)
+ var/blood_volume = round(H.vessel.get_reagent_amount("blood"))
+ bloodData["volume"] = blood_volume
+ bloodData["percent"] = round(((blood_volume / 560)*100))
+
+ occupantData["blood"] = bloodData
+
+ var/reagentData[0]
+ if(H.reagents.reagent_list.len >= 1)
+ for(var/datum/reagent/R in H.reagents.reagent_list)
+ reagentData[++reagentData.len] = list("name" = R.name, "amount" = R.volume)
+ else
+ reagentData = null
+
+ occupantData["reagents"] = reagentData
+
+ var/extOrganData[0]
+ for(var/obj/item/organ/external/E in H.organs)
+ var/organData[0]
+ organData["name"] = E.name
+ organData["open"] = E.open
+ organData["germ_level"] = E.germ_level
+ organData["bruteLoss"] = E.brute_dam
+ organData["fireLoss"] = E.burn_dam
+
+ var/implantData[0]
+ for(var/obj/I in E.implants)
+ var/implantSubData[0]
+ implantSubData["name"] = I.name
+ if(is_type_in_list(I, known_implants))
+ implantSubData["known"] = 1
+
+ implantData.Add(list(implantSubData))
+
+ organData["implants"] = implantData
+ organData["implants_len"] = implantData.len
+
+ var/organStatus[0]
+ if(E.status & ORGAN_DESTROYED)
+ organStatus["destroyed"] = 1
+ if(E.status & ORGAN_BROKEN)
+ organStatus["broken"] = E.broken_description
+ if(E.status & ORGAN_ROBOT)
+ organStatus["robotic"] = 1
+ if(E.status & ORGAN_SPLINTED)
+ organStatus["splinted"] = 1
+ if(E.status & ORGAN_BLEEDING)
+ organStatus["bleeding"] = 1
+
+ organData["status"] = organStatus
+
+ if(istype(E, /obj/item/organ/external/chest) && H.is_lung_ruptured())
+ organData["lungRuptured"] = 1
+
+ for(var/datum/wound/W in E.wounds)
+ if(W.internal)
+ organData["internalBleeding"] = 1
+ break
+
+ extOrganData.Add(list(organData))
+
+ occupantData["extOrgan"] = extOrganData
+
+ var/intOrganData[0]
+ for(var/obj/item/organ/I in H.internal_organs)
+ var/organData[0]
+ organData["name"] = I.name
+ if(I.status & ORGAN_ASSISTED)
+ organData["desc"] = "Assisted"
+ else if(I.robotic >= ORGAN_ROBOT)
+ organData["desc"] = "Mechanical"
else
- unknown_body++
- if(unknown_body)
- imp += "Unknown body present:"
+ organData["desc"] = null
+ organData["germ_level"] = I.germ_level
+ organData["damage"] = I.damage
- if(!AN && !open && !infected & !imp)
- AN = "None:"
- if(!e.is_stump())
- dat += "[e.name] | [e.burn_dam] | [e.brute_dam] | [robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured] | "
+ intOrganData.Add(list(organData))
+
+ occupantData["intOrgan"] = intOrganData
+
+ occupantData["blind"] = (H.sdisabilities & BLIND)
+ occupantData["nearsighted"] = (H.disabilities & NEARSIGHTED)
+ occupantData = attempt_vr(src,"get_occupant_data_vr",list(occupantData,H)) //VOREStation Insert
+ data["occupant"] = occupantData
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if(!ui)
+ ui = new(user, src, ui_key, "adv_med.tmpl", "Body Scanner", 690, 800)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(1)
+
+
+/obj/machinery/body_scanconsole/Topic(href, href_list)
+ if(..())
+ return 1
+
+ if (href_list["print_p"])
+ generate_printing_text()
+
+ if (!(printing) && printing_text)
+ printing = 1
+ visible_message("\The [src] rattles and prints out a sheet of paper.")
+ var/obj/item/weapon/paper/P = new /obj/item/weapon/paper(loc)
+ P.info = "Body Scan - [href_list["name"]]
"
+ P.info += "Time of scan: [worldtime2text(world.time)]
"
+ P.info += "[printing_text]"
+ P.info += "
Notes:
"
+ P.name = "Body Scan - [href_list["name"]]"
+ printing = null
+ printing_text = null
+
+/obj/machinery/body_scanconsole/proc/generate_printing_text()
+ var/dat = ""
+
+ if(connected)
+ var/mob/living/carbon/human/occupant = connected.occupant
+ dat = "Occupant Statistics:
" //Blah obvious
+ if(istype(occupant)) //is there REALLY someone in there?
+ var/t1
+ switch(occupant.stat) // obvious, see what their status is
+ if(0)
+ t1 = "Conscious"
+ if(1)
+ t1 = "Unconscious"
+ else
+ t1 = "*dead*"
+ dat += " 50 ? "blue" : "red"]>\tHealth %: [occupant.health], ([t1])
"
+
+ if(occupant.virus2.len)
+ dat += "Viral pathogen detected in blood stream.
"
+
+ var/extra_font = null
+ extra_font = ""
+ dat += "[extra_font]\t-Brute Damage %: [occupant.getBruteLoss()]
"
+
+ extra_font = ""
+ dat += "[extra_font]\t-Respiratory Damage %: [occupant.getOxyLoss()]
"
+
+ extra_font = ""
+ dat += "[extra_font]\t-Toxin Content %: [occupant.getToxLoss()]
"
+
+ extra_font = ""
+ dat += "[extra_font]\t-Burn Severity %: [occupant.getFireLoss()]
"
+
+ extra_font = ""
+ dat += "[extra_font]\tRadiation Level %: [occupant.radiation]
"
+
+ extra_font = ""
+ dat += "[extra_font]\tGenetic Tissue Damage %: [occupant.getCloneLoss()]
"
+
+ extra_font = ""
+ dat += "[extra_font]\tApprox. Brain Damage %: [occupant.getBrainLoss()]
"
+
+ dat += "Paralysis Summary %: [occupant.paralysis] ([round(occupant.paralysis / 4)] seconds left!)
"
+ dat += "Body Temperature: [occupant.bodytemperature-T0C]°C ([occupant.bodytemperature*1.8-459.67]°F)
"
+
+ dat += "
"
+
+ if(occupant.has_brain_worms())
+ dat += "Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
"
+
+ if(occupant.vessel)
+ var/blood_volume = round(occupant.vessel.get_reagent_amount("blood"))
+ var/blood_percent = blood_volume / 560
+ blood_percent *= 100
+
+ extra_font = " 448 ? "blue" : "red"]>"
+ dat += "[extra_font]\tBlood Level %: [blood_percent] ([blood_volume] units)
"
+
+ if(occupant.reagents)
+ for(var/datum/reagent/R in occupant.reagents)
+ dat += "Reagent: [R.name], Amount: [R.volume]
"
+
+ dat += "
"
+ dat += ""
+ dat += "| Organ | "
+ dat += "Burn Damage | "
+ dat += "Brute Damage | "
+ dat += "Other Wounds | "
+ dat += "
"
+
+ for(var/obj/item/organ/external/e in occupant.organs)
+ dat += ""
+ var/AN = ""
+ var/open = ""
+ var/infected = ""
+ var/robot = ""
+ var/imp = ""
+ var/bled = ""
+ var/splint = ""
+ var/internal_bleeding = ""
+ var/lung_ruptured = ""
+ for(var/datum/wound/W in e.wounds) if(W.internal)
+ internal_bleeding = "
Internal bleeding"
+ break
+ if(istype(e, /obj/item/organ/external/chest) && occupant.is_lung_ruptured())
+ lung_ruptured = "Lung ruptured:"
+ if(e.status & ORGAN_SPLINTED)
+ splint = "Splinted:"
+ if(e.status & ORGAN_BLEEDING)
+ bled = "Bleeding:"
+ if(e.status & ORGAN_BROKEN)
+ AN = "[e.broken_description]:"
+ if(e.status & ORGAN_ROBOT)
+ robot = "Prosthetic:"
+ if(e.open)
+ open = "Open:"
+ switch (e.germ_level)
+ if (INFECTION_LEVEL_ONE to INFECTION_LEVEL_ONE + 200)
+ infected = "Mild Infection:"
+ if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
+ infected = "Mild Infection+:"
+ if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
+ infected = "Mild Infection++:"
+ if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
+ infected = "Acute Infection:"
+ if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
+ infected = "Acute Infection+:"
+ if (INFECTION_LEVEL_TWO + 300 to INFECTION_LEVEL_TWO + 400)
+ infected = "Acute Infection++:"
+ if (INFECTION_LEVEL_THREE to INFINITY)
+ infected = "Septic:"
+
+ var/unknown_body = 0
+ for(var/I in e.implants)
+ if(is_type_in_list(I,known_implants))
+ imp += "[I] implanted:"
+ else
+ unknown_body++
+
+ if(unknown_body)
+ imp += "Unknown body present:"
+ if(!AN && !open && !infected & !imp)
+ AN = "None:"
+ if(!(e.status & ORGAN_DESTROYED))
+ dat += "[e.name] | [e.burn_dam] | [e.brute_dam] | [robot][bled][AN][splint][open][infected][imp][internal_bleeding][lung_ruptured] | "
+ else
+ dat += "[e.name] | - | - | Not Found | "
+ dat += "
"
+ for(var/obj/item/organ/i in occupant.internal_organs)
+ var/mech = ""
+ if(i.status & ORGAN_ASSISTED)
+ mech = "Assisted:"
+ if(i.robotic >= ORGAN_ROBOT)
+ mech = "Mechanical:"
+ var/infection = "None"
+ switch (i.germ_level)
+ if (1 to INFECTION_LEVEL_ONE + 200)
+ infection = "Mild Infection:"
+ if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
+ infection = "Mild Infection+:"
+ if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
+ infection = "Mild Infection++:"
+ if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
+ infection = "Acute Infection:"
+ if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
+ infection = "Acute Infection+:"
+ if (INFECTION_LEVEL_TWO + 300 to INFINITY)
+ infection = "Acute Infection++:"
+
+ dat += ""
+ dat += "| [i.name] | N/A | [i.damage] | [infection]:[mech] | | "
+ dat += "
"
+ dat += "
"
+ if(occupant.sdisabilities & BLIND)
+ dat += "Cataracts detected.
"
+ if(occupant.disabilities & NEARSIGHTED)
+ dat += "Retinal misalignment detected.
"
else
- dat += "[e.name] | - | - | Not [e.is_stump() ? "Found" : "Attached Completely"] | "
- dat += "
"
+ dat += "\The [src] is empty."
+ else
+ dat = " Error: No Body Scanner connected."
- for(var/obj/item/organ/i in occ["internal_organs"])
-
- var/mech = ""
- if(i.status & ORGAN_ASSISTED)
- mech = "Assisted:"
- if(i.robotic >= ORGAN_ROBOT)
- mech = "Mechanical:"
-
- var/infection = "None"
- switch (i.germ_level)
- if (1 to INFECTION_LEVEL_ONE + 200)
- infection = "Mild Infection:"
- if (INFECTION_LEVEL_ONE + 200 to INFECTION_LEVEL_ONE + 300)
- infection = "Mild Infection+:"
- if (INFECTION_LEVEL_ONE + 300 to INFECTION_LEVEL_ONE + 400)
- infection = "Mild Infection++:"
- if (INFECTION_LEVEL_TWO to INFECTION_LEVEL_TWO + 200)
- infection = "Acute Infection:"
- if (INFECTION_LEVEL_TWO + 200 to INFECTION_LEVEL_TWO + 300)
- infection = "Acute Infection+:"
- if (INFECTION_LEVEL_TWO + 300 to INFINITY)
- infection = "Acute Infection++:"
- if(i.rejecting)
- infection += "(being rejected)"
-
- dat += ""
- dat += "| [i.name] | N/A | [i.damage] | [infection]:[mech] | | "
- dat += "
"
- dat += "
"
-
- var/list/species_organs = occ["species_organs"]
- for(var/organ_name in species_organs)
- if(!locate(species_organs[organ_name]) in occ["internal_organs"])
- dat += text("No [organ_name] detected.
")
-
- if(occ["sdisabilities"] & BLIND)
- dat += text("Cataracts detected.
")
- if(occ["sdisabilities"] & NEARSIGHTED)
- dat += text("Retinal misalignment detected.
")
- return dat
+ printing_text = dat
\ No newline at end of file
diff --git a/code/game/machinery/atmo_control.dm b/code/game/machinery/atmo_control.dm
index c7b5f3c73a..19d1ee1253 100644
--- a/code/game/machinery/atmo_control.dm
+++ b/code/game/machinery/atmo_control.dm
@@ -94,13 +94,8 @@ obj/machinery/computer/general_air_control/Destroy()
/obj/machinery/computer/general_air_control/attack_hand(mob/user)
if(..(user))
return
- user << browse(return_text(),"window=computer")
- user.set_machine(src)
- onclose(user, "computer")
-/obj/machinery/computer/general_air_control/process()
- ..()
- src.updateUsrDialog()
+ ui_interact(user)
/obj/machinery/computer/general_air_control/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
@@ -110,43 +105,27 @@ obj/machinery/computer/general_air_control/Destroy()
sensor_information[id_tag] = signal.data
-/obj/machinery/computer/general_air_control/proc/return_text()
- var/sensor_data
+/obj/machinery/computer/general_air_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
+
+ var/list/data = list()
+ var/sensors_ui[0]
if(sensors.len)
for(var/id_tag in sensors)
var/long_name = sensors[id_tag]
- var/list/data = sensor_information[id_tag]
- var/sensor_part = "[long_name]:
"
-
- if(data)
- if(data["pressure"])
- sensor_part += " Pressure: [data["pressure"]] kPa
"
- if(data["temperature"])
- sensor_part += " Temperature: [data["temperature"]] K
"
- if(data["oxygen"]||data["phoron"]||data["nitrogen"]||data["carbon_dioxide"])
- sensor_part += " Gas Composition :"
- if(data["oxygen"])
- sensor_part += "[data["oxygen"]]% O2; "
- if(data["nitrogen"])
- sensor_part += "[data["nitrogen"]]% N; "
- if(data["carbon_dioxide"])
- sensor_part += "[data["carbon_dioxide"]]% CO2; "
- if(data["phoron"])
- sensor_part += "[data["phoron"]]% TX; "
- sensor_part += "
"
-
- else
- sensor_part = "[long_name] can not be found!
"
-
- sensor_data += sensor_part
-
+ var/list/sensor_data = sensor_information[id_tag]
+ sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data)
else
- sensor_data = "No sensors connected."
+ sensors_ui = null
- var/output = {"[name]
-Sensor Data:
[sensor_data]"}
+ data["sensors"] = sensors_ui
- return output
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 525, 600)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(5)
/obj/machinery/computer/general_air_control/proc/set_frequency(new_frequency)
radio_controller.remove_object(src, frequency)
@@ -156,7 +135,6 @@ obj/machinery/computer/general_air_control/Destroy()
/obj/machinery/computer/general_air_control/initialize()
set_frequency(frequency)
-
/obj/machinery/computer/general_air_control/large_tank_control
icon = 'icons/obj/computer.dmi'
@@ -171,39 +149,41 @@ obj/machinery/computer/general_air_control/Destroy()
var/pressure_setting = ONE_ATMOSPHERE * 45
circuit = /obj/item/weapon/circuitboard/air_management/tank_control
+/obj/machinery/computer/general_air_control/large_tank_control/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
-/obj/machinery/computer/general_air_control/large_tank_control/return_text()
- var/output = ..()
- //if(signal.data)
- // input_info = signal.data // Attempting to fix intake control -- TLE
-
- output += "Tank Control System
"
- if(input_info)
- var/power = (input_info["power"])
- var/volume_rate = round(input_info["volume_rate"], 0.1)
- output += "Input: [power?("Injecting"):("On Hold")] Refresh
Flow Rate Limit: [volume_rate] L/s
"
- output += "Command: Toggle Power Set Flow Rate
"
-
+ var/list/data = list()
+ var/sensors_ui[0]
+ if(sensors.len)
+ for(var/id_tag in sensors)
+ var/long_name = sensors[id_tag]
+ var/list/sensor_data = sensor_information[id_tag]
+ sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data)
else
- output += "ERROR: Can not find input port Search
"
+ sensors_ui = null
- output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
"
+ data["sensors"] = sensors_ui
+ data["tanks"] = 1
- output += "
"
+ if(input_info)
+ data["input_info"] = list("power" = input_info["power"], "volume_rate" = round(input_info["volume_rate"], 0.1))
+ else
+ data["input_info"] = null
if(output_info)
- var/power = (output_info["power"])
- var/output_pressure = output_info["internal"]
- output += {"Output: [power?("Open"):("On Hold")] Refresh
-Max Output Pressure: [output_pressure] kPa
"}
- output += "Command: Toggle Power Set Pressure
"
-
+ data["output_info"] = list("power" = output_info["power"], "output_pressure" = output_info["internal"])
else
- output += "ERROR: Can not find output port Search
"
+ data["output_info"] = null
- output += "Max Output Pressure Set: - - - - [pressure_setting] kPa + + + +
"
+ data["input_flow_setting"] = round(input_flow_setting, 0.1)
+ data["pressure_setting"] = pressure_setting
- return output
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 660, 500)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(5)
/obj/machinery/computer/general_air_control/large_tank_control/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
@@ -224,15 +204,11 @@ Max Output Pressure: [output_pressure] kPa
"}
if(href_list["adj_pressure"])
var/change = text2num(href_list["adj_pressure"])
pressure_setting = between(0, pressure_setting + change, 50*ONE_ATMOSPHERE)
- spawn(1)
- src.updateUsrDialog()
return 1
if(href_list["adj_input_flow_rate"])
var/change = text2num(href_list["adj_input_flow_rate"])
input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors
- spawn(1)
- src.updateUsrDialog()
return 1
if(!radio_connection)
@@ -273,9 +249,6 @@ Max Output Pressure: [output_pressure] kPa
"}
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
- spawn(5)
- src.updateUsrDialog()
-
/obj/machinery/computer/general_air_control/supermatter_core
icon = 'icons/obj/computer.dmi'
@@ -290,39 +263,40 @@ Max Output Pressure: [output_pressure] kPa
"}
var/pressure_setting = 100
circuit = /obj/item/weapon/circuitboard/air_management/supermatter_core
+/obj/machinery/computer/general_air_control/supermatter_core/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
-/obj/machinery/computer/general_air_control/supermatter_core/return_text()
- var/output = ..()
- //if(signal.data)
- // input_info = signal.data // Attempting to fix intake control -- TLE
+ var/list/data = list()
+ var/sensors_ui[0]
+ if(sensors.len)
+ for(var/id_tag in sensors)
+ var/long_name = sensors[id_tag]
+ var/list/sensor_data = sensor_information[id_tag]
+ sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data)
+ else
+ sensors_ui = null
+
+ data["sensors"] = sensors_ui
+ data["core"] = 1
- output += "Core Cooling Control System
"
if(input_info)
- var/power = (input_info["power"])
- var/volume_rate = round(input_info["volume_rate"], 0.1)
- output += "Coolant Input: [power?("Injecting"):("On Hold")] Refresh
Flow Rate Limit: [volume_rate] L/s
"
- output += "Command: Toggle Power Set Flow Rate
"
-
+ data["input_info"] = list("power" = input_info["power"], "volume_rate" = round(input_info["volume_rate"], 0.1))
else
- output += "ERROR: Can not find input port Search
"
-
- output += "Flow Rate Limit: - - - - [round(input_flow_setting, 0.1)] L/s + + + +
"
-
- output += "
"
-
+ data["input_info"] = null
if(output_info)
- var/power = (output_info["power"])
- var/pressure_limit = output_info["external"]
- output += {"Core Outpump: [power?("Open"):("On Hold")] Refresh
-Min Core Pressure: [pressure_limit] kPa
"}
- output += "Command: Toggle Power Set Pressure
"
-
+ data["output_info"] = list("power" = output_info["power"], "pressure_limit" = output_info["external"])
else
- output += "ERROR: Can not find output port Search
"
+ data["output_info"] = null
- output += "Min Core Pressure Set: - - - - [pressure_setting] kPa + + + +
"
+ data["input_flow_setting"] = round(input_flow_setting, 0.1)
+ data["pressure_setting"] = pressure_setting
- return output
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 650, 500)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(5)
/obj/machinery/computer/general_air_control/supermatter_core/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
@@ -343,15 +317,11 @@ Min Core Pressure: [pressure_limit] kPa
"}
if(href_list["adj_pressure"])
var/change = text2num(href_list["adj_pressure"])
pressure_setting = between(0, pressure_setting + change, 10*ONE_ATMOSPHERE)
- spawn(1)
- src.updateUsrDialog()
return 1
if(href_list["adj_input_flow_rate"])
var/change = text2num(href_list["adj_input_flow_rate"])
input_flow_setting = between(0, input_flow_setting + change, ATMOS_DEFAULT_VOLUME_PUMP + 500) //default flow rate limit for air injectors
- spawn(1)
- src.updateUsrDialog()
return 1
if(!radio_connection)
@@ -392,9 +362,6 @@ Min Core Pressure: [pressure_limit] kPa
"}
signal.data["sigtype"]="command"
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
- spawn(5)
- src.updateUsrDialog()
-
/obj/machinery/computer/general_air_control/fuel_injection
icon = 'icons/obj/computer.dmi'
icon_screen = "alert:0"
@@ -437,27 +404,34 @@ Min Core Pressure: [pressure_limit] kPa
"}
..()
-/obj/machinery/computer/general_air_control/fuel_injection/return_text()
- var/output = ..()
-
- output += "Fuel Injection System
"
- if(device_info)
- var/power = device_info["power"]
- var/volume_rate = device_info["volume_rate"]
- output += {"Status: [power?("Injecting"):("On Hold")] Refresh
-Rate: [volume_rate] L/sec
"}
-
- if(automation)
- output += "Automated Fuel Injection: Engaged
"
- output += "Injector Controls Locked Out
"
- else
- output += "Automated Fuel Injection: Disengaged
"
- output += "Injector: Toggle Power Inject (1 Cycle)
"
+/obj/machinery/computer/general_air_control/fuel_injection/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
+ var/list/data = list()
+ var/sensors_ui[0]
+ if(sensors.len)
+ for(var/id_tag in sensors)
+ var/long_name = sensors[id_tag]
+ var/list/sensor_data = sensor_information[id_tag]
+ sensors_ui[++sensors_ui.len] = list("long_name" = long_name, "sensor_data" = sensor_data)
else
- output += "ERROR: Can not find device Search
"
+ sensors_ui = null
- return output
+ data["sensors"] = sensors_ui
+ data["fuel"] = 1
+ data["automation"] = automation
+
+ if(device_info)
+ data["device_info"] = list("power" = device_info["power"], "volume_rate" = device_info["volume_rate"])
+ else
+ data["device_info"] = null
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "atmo_control.tmpl", src.name, 650, 500)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(5)
/obj/machinery/computer/general_air_control/fuel_injection/receive_signal(datum/signal/signal)
if(!signal || signal.encryption) return
diff --git a/code/game/machinery/computer/Operating.dm b/code/game/machinery/computer/Operating.dm
index 8427a08418..5cc9801d0f 100644
--- a/code/game/machinery/computer/Operating.dm
+++ b/code/game/machinery/computer/Operating.dm
@@ -22,62 +22,51 @@
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
- interact(user)
+ ui_interact(user)
/obj/machinery/computer/operating/attack_hand(mob/user)
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
- interact(user)
-
-
-/obj/machinery/computer/operating/interact(mob/user)
- if ( (get_dist(src, user) > 1 ) || (stat & (BROKEN|NOPOWER)) )
- if (!istype(user, /mob/living/silicon))
- user.unset_machine()
- user << browse(null, "window=op")
- return
+ ui_interact(user)
+/**
+ * Display the NanoUI window for the operating computer.
+ *
+ * See NanoUI documentation for details.
+ */
+/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
- var/dat = "Operating Computer\n"
- dat += "Close
" //| Update"
- if(src.table && (src.table.check_victim()))
- src.victim = src.table.victim
- dat += {"
-Patient Information:
-
-Name: [src.victim.real_name]
-Age: [src.victim.age]
-Blood Type: [src.victim.b_type]
-
-Health: [src.victim.health]
-Brute Damage: [src.victim.getBruteLoss()]
-Toxins Damage: [src.victim.getToxLoss()]
-Fire Damage: [src.victim.getFireLoss()]
-Suffocation Damage: [src.victim.getOxyLoss()]
-Patient Status: [src.victim.stat ? "Non-Responsive" : "Stable"]
-Heartbeat rate: [victim.get_pulse(GETPULSE_TOOL)]
-"}
- else
- src.victim = null
- dat += {"
-Patient Information:
-
-No Patient Detected
-"}
- user << browse(dat, "window=op")
- onclose(user, "op")
+ var/list/data = list()
+ var/list/victim_ui = list()
+
+ if(table && (table.check_victim()))
+ victim = table.victim
+
+ victim_ui = list("real_name" = victim.real_name, "age" = victim.age, "b_type" = victim.b_type, "health" = victim.health,
+ "brute" = victim.getBruteLoss(), "tox" = src.victim.getToxLoss(), "burn" = victim.getFireLoss(), "oxy" = victim.getOxyLoss(),
+ "stat" = (victim.stat ? "Non-Responsive" : "Stable"), "pulse" = victim.get_pulse(GETPULSE_TOOL))
+ else
+ victim = null
+ victim_ui = null
+
+ data["table"] = table
+ data["victim"] = victim_ui
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "operating.tmpl", src.name, 380, 400)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(5)
/obj/machinery/computer/operating/Topic(href, href_list)
if(..())
return 1
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon)))
usr.set_machine(src)
- return
-
-/obj/machinery/computer/operating/process()
- if(..())
- src.updateDialog()
+ src.add_fingerprint(usr)
+ nanomanager.update_uis(src)
\ No newline at end of file
diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm
index 189fe5b40a..d338edacc1 100644
--- a/code/game/machinery/computer/arcade.dm
+++ b/code/game/machinery/computer/arcade.dm
@@ -53,7 +53,7 @@
prize.loc = src.loc
/obj/machinery/computer/arcade/attack_ai(mob/user as mob)
- return src.attack_hand(user)
+ return attack_hand(user)
/obj/machinery/computer/arcade/emp_act(severity)
@@ -84,6 +84,7 @@
circuit = /obj/item/weapon/circuitboard/arcade/battle
var/enemy_name = "Space Villian"
var/temp = "Winners don't use space drugs" //Temporary message, for attack messages, etc
+ var/enemy_action = ""
var/player_hp = 30 //Player health/attack points
var/player_mp = 10
var/enemy_hp = 45 //Enemy health/attack points
@@ -103,81 +104,80 @@
name_part1 = pick("the Automatic ", "Farmer ", "Lord ", "Professor ", "the Cuban ", "the Evil ", "the Dread King ", "the Space ", "Lord ", "the Great ", "Duke ", "General ")
name_part2 = pick("Melonoid", "Murdertron", "Sorcerer", "Ruin", "Jeff", "Ectoplasm", "Crushulon", "Uhangoid", "Vhakoid", "Peteoid", "slime", "Griefer", "ERPer", "Lizard Man", "Unicorn", "Bloopers")
- src.enemy_name = replacetext((name_part1 + name_part2), "the ", "")
- src.name = (name_action + name_part1 + name_part2)
+ enemy_name = replacetext((name_part1 + name_part2), "the ", "")
+ name = (name_action + name_part1 + name_part2)
/obj/machinery/computer/arcade/battle/attack_hand(mob/user as mob)
if(..())
return
user.set_machine(src)
- var/dat = "Close"
- dat += "[src.enemy_name]
"
+ ui_interact(user)
- dat += "
[src.temp]
"
- dat += "
Health: [src.player_hp] | Magic: [src.player_mp] | Enemy Health: [src.enemy_hp]"
+/**
+ * Display the NanoUI window for the arcade machine.
+ *
+ * See NanoUI documentation for details.
+ */
+/obj/machinery/computer/arcade/battle/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
- dat += ""
- if (src.gameover)
- dat += "New Game"
- else
- dat += "Attack | "
- dat += "Heal | "
- dat += "Recharge Power"
+ var/list/data = list()
+ data["temp"] = temp
+ data["enemyAction"] = enemy_action
+ data["enemyName"] = enemy_name
+ data["playerHP"] = player_hp
+ data["playerMP"] = player_mp
+ data["enemyHP"] = enemy_hp
+ data["gameOver"] = gameover
- dat += ""
-
- user << browse(dat, "window=arcade")
- onclose(user, "arcade")
- return
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "arcade_battle.tmpl", src.name, 400, 300)
+ ui.set_initial_data(data)
+ ui.open()
+ //ui.set_auto_update(2)
/obj/machinery/computer/arcade/battle/Topic(href, href_list)
if(..())
return 1
- if (!src.blocked && !src.gameover)
+ if (!blocked && !gameover)
if (href_list["attack"])
- src.blocked = 1
+ blocked = 1
var/attackamt = rand(2,6)
- src.temp = "You attack for [attackamt] damage!"
- src.updateUsrDialog()
+ temp = "You attack for [attackamt] damage!"
if(turtle > 0)
turtle--
sleep(10)
- src.enemy_hp -= attackamt
- src.arcade_action()
+ enemy_hp -= attackamt
+ arcade_action()
else if (href_list["heal"])
- src.blocked = 1
+ blocked = 1
var/pointamt = rand(1,3)
var/healamt = rand(6,8)
- src.temp = "You use [pointamt] magic to heal for [healamt] damage!"
- src.updateUsrDialog()
+ temp = "You use [pointamt] magic to heal for [healamt] damage!"
turtle++
sleep(10)
- src.player_mp -= pointamt
- src.player_hp += healamt
- src.blocked = 1
- src.updateUsrDialog()
- src.arcade_action()
+ player_mp -= pointamt
+ player_hp += healamt
+ blocked = 1
+ arcade_action()
else if (href_list["charge"])
- src.blocked = 1
+ blocked = 1
var/chargeamt = rand(4,7)
- src.temp = "You regain [chargeamt] points"
- src.player_mp += chargeamt
+ temp = "You regain [chargeamt] points"
+ player_mp += chargeamt
if(turtle > 0)
turtle--
- src.updateUsrDialog()
sleep(10)
- src.arcade_action()
+ arcade_action()
- if (href_list["close"])
- usr.unset_machine()
- usr << browse(null, "window=arcade")
else if (href_list["newgame"]) //Reset everything
temp = "New Round"
@@ -193,14 +193,14 @@
emagged = 0
src.add_fingerprint(usr)
- src.updateUsrDialog()
+ nanomanager.update_uis(src)
return
/obj/machinery/computer/arcade/battle/proc/arcade_action()
- if ((src.enemy_mp <= 0) || (src.enemy_hp <= 0))
+ if ((enemy_mp <= 0) || (enemy_hp <= 0))
if(!gameover)
- src.gameover = 1
- src.temp = "[src.enemy_name] has fallen! Rejoice!"
+ gameover = 1
+ temp = "[enemy_name] has fallen! Rejoice!"
if(emagged)
feedback_inc("arcade_win_emagged")
@@ -212,53 +212,52 @@
emagged = 0
else if(!contents.len)
feedback_inc("arcade_win_normal")
- src.prizevend()
+ prizevend()
else
feedback_inc("arcade_win_normal")
- src.prizevend()
+ prizevend()
else if (emagged && (turtle >= 4))
var/boomamt = rand(5,10)
- src.temp = "[src.enemy_name] throws a bomb, exploding you for [boomamt] damage!"
- src.player_hp -= boomamt
+ enemy_action = "[enemy_name] throws a bomb, exploding you for [boomamt] damage!"
+ player_hp -= boomamt
- else if ((src.enemy_mp <= 5) && (prob(70)))
+ else if ((enemy_mp <= 5) && (prob(70)))
var/stealamt = rand(2,3)
- src.temp = "[src.enemy_name] steals [stealamt] of your power!"
- src.player_mp -= stealamt
- src.updateUsrDialog()
+ enemy_action = "[enemy_name] steals [stealamt] of your power!"
+ player_mp -= stealamt
- if (src.player_mp <= 0)
- src.gameover = 1
+ if (player_mp <= 0)
+ gameover = 1
sleep(10)
- src.temp = "You have been drained! GAME OVER"
+ temp = "You have been drained! GAME OVER"
if(emagged)
feedback_inc("arcade_loss_mana_emagged")
usr.gib()
else
feedback_inc("arcade_loss_mana_normal")
- else if ((src.enemy_hp <= 10) && (src.enemy_mp > 4))
- src.temp = "[src.enemy_name] heals for 4 health!"
- src.enemy_hp += 4
- src.enemy_mp -= 4
+ else if ((enemy_hp <= 10) && (enemy_mp > 4))
+ enemy_action = "[enemy_name] heals for 4 health!"
+ enemy_hp += 4
+ enemy_mp -= 4
else
var/attackamt = rand(3,6)
- src.temp = "[src.enemy_name] attacks for [attackamt] damage!"
- src.player_hp -= attackamt
+ enemy_action = "[enemy_name] attacks for [attackamt] damage!"
+ player_hp -= attackamt
- if ((src.player_mp <= 0) || (src.player_hp <= 0))
- src.gameover = 1
- src.temp = "You have been crushed! GAME OVER"
+ if ((player_mp <= 0) || (player_hp <= 0))
+ gameover = 1
+ temp = "You have been crushed! GAME OVER"
if(emagged)
feedback_inc("arcade_loss_hp_emagged")
usr.gib()
else
feedback_inc("arcade_loss_hp_normal")
- src.blocked = 0
+ blocked = 0
return
@@ -276,7 +275,6 @@
enemy_name = "Cuban Pete"
name = "Outbomb Cuban Pete"
- src.updateUsrDialog()
return 1
diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm
index bdab3bbbb1..da165448da 100644
--- a/code/game/machinery/computer/cloning.dm
+++ b/code/game/machinery/computer/cloning.dm
@@ -16,6 +16,7 @@
var/obj/item/weapon/disk/data/diskette = null //Mostly so the geneticist can steal everything.
var/loading = 0 // Nice loading text
+
/obj/machinery/computer/cloning/initialize()
..()
updatemodules()
@@ -25,7 +26,7 @@
..()
/obj/machinery/computer/cloning/proc/updatemodules()
- src.scanner = findscanner()
+ scanner = findscanner()
releasecloner()
findcloner()
@@ -63,12 +64,12 @@
/obj/machinery/computer/cloning/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/weapon/disk/data)) //INSERT SOME DISKETTES
- if (!src.diskette)
+ if (!diskette)
user.drop_item()
W.loc = src
- src.diskette = W
+ diskette = W
user << "You insert [W]."
- src.updateUsrDialog()
+ updateUsrDialog()
return
else if(istype(W, /obj/item/device/multitool))
var/obj/item/device/multitool/M = W
@@ -78,6 +79,15 @@
P.connected = src
P.name = "[initial(P.name)] #[pods.len]"
user << "You connect [P] to [src]."
+
+ else if (menu == 4 && (istype(W, /obj/item/weapon/card/id) || istype(W, /obj/item/device/pda)))
+ if(check_access(W))
+ records.Remove(active_record)
+ qdel(active_record)
+ temp = "Record deleted."
+ menu = 2
+ else
+ temp = "Access Denied."
else
..()
return
@@ -94,109 +104,55 @@
updatemodules()
- var/dat = "Cloning System Control
"
- dat += "Refresh"
+ ui_interact(user)
- dat += "
[temp]
"
+/obj/machinery/computer/cloning/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
- switch(src.menu)
- if(1)
- // Modules
- dat += "Modules
"
- //dat += "Reload Modules"
- if (isnull(src.scanner))
- dat += " DNA scanner not found.
"
- else
- dat += " DNA scanner found.
"
- if (pods.len)
- dat += " [pods.len] cloning vat\s found.
"
- else
- dat += " No cloning vats found.
"
+ var/data[0]
- // Scanner
- dat += "Scanner Functions
"
+ var/records_list_ui[0]
+ for(var/datum/dna2/record/R in records)
+ records_list_ui[++records_list_ui.len] = list("ckey" = R.ckey, "name" = R.dna.real_name)
- if(loading)
- dat += "Scanning...
"
- else
- dat += "[scantemp]
"
+ var/pods_list_ui[0]
+ for(var/obj/machinery/clonepod/pod in pods)
+ pods_list_ui[++pods_list_ui.len] = list("pod" = pod, "biomass" = pod.biomass)
- if (isnull(src.scanner))
- dat += "No scanner connected!
"
- else
- if (src.scanner.occupant)
- if(scantemp == "Scanner unoccupied") scantemp = "" // Stupid check to remove the text
+ if(pods)
+ data["pods"] = pods_list_ui
+ else
+ data["pods"] = null
- dat += "Scan - [src.scanner.occupant]
"
- else
- scantemp = "Scanner unoccupied"
+ if(records)
+ data["records"] = records_list_ui
+ else
+ data["records"] = null
- dat += "Lock status: [src.scanner.locked ? "Locked" : "Unlocked"]
"
+ if(active_record)
+ data["activeRecord"] = list("ckey" = active_record.ckey, "real_name" = active_record.dna.real_name, \
+ "ui" = active_record.dna.uni_identity, "se" = active_record.dna.struc_enzymes)
+ else
+ data["activeRecord"] = null
- if (pods.len)
- for (var/obj/machinery/clonepod/pod in pods)
- dat += "[pod] biomass: [pod.biomass]
"
+ data["menu"] = menu
+ data["connected"] = scanner
+ data["podsLen"] = pods.len
+ data["loading"] = loading
+ if(!scanner.occupant)
+ scantemp = ""
+ data["scantemp"] = scantemp
+ data["occupant"] = scanner.occupant
+ data["locked"] = scanner.locked
+ data["diskette"] = diskette
+ data["temp"] = temp
- // Database
- dat += "Database Functions
"
- dat += "View Records
"
- if (src.diskette)
- dat += "Eject Disk"
-
-
- if(2)
- dat += "Current records
"
- dat += "Back
"
- for(var/datum/dna2/record/R in src.records)
- dat += "[R.dna.real_name]"
-
- if(3)
- dat += "Selected Record
"
- dat += "Back
"
-
- if (!src.active_record)
- dat += "ERROR: Record not found."
- else
- dat += {"
Delete Record
- Name: [src.active_record.dna.real_name]
"}
- var/obj/item/weapon/implant/health/H = null
- if(src.active_record.implant)
- H=locate(src.active_record.implant)
-
- if ((H) && (istype(H)))
- dat += "Health: [H.sensehealth()] | OXY-BURN-TOX-BRUTE
"
- else
- dat += "Unable to locate implant.
"
-
- if (!isnull(src.diskette))
- dat += "Load from disk."
-
- dat += " | Save: UI + UE"
- dat += " | Save: UI"
- dat += " | Save: SE"
- dat += "
"
- else
- dat += "
" //Keeping a line empty for appearances I guess.
-
- dat += {"UI: [src.active_record.dna.uni_identity]
- SE: [src.active_record.dna.struc_enzymes]
"}
-
- if(pods.len)
- dat += {"Clone
"}
-
- if(4)
- if (!src.active_record)
- src.menu = 2
- dat = "[src.temp]
"
- dat += "Confirm Record Deletion
"
-
- dat += "Scan card to confirm.
"
- dat += "No"
-
-
- user << browse(dat, "window=cloning")
- onclose(user, "cloning")
- return
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "cloning.tmpl", src.name, 400, 450)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(5)
/obj/machinery/computer/cloning/Topic(href, href_list)
if(..())
@@ -205,101 +161,87 @@
if(loading)
return
- if ((href_list["scan"]) && (!isnull(src.scanner)))
+ if ((href_list["scan"]) && (!isnull(scanner)))
scantemp = ""
loading = 1
- src.updateUsrDialog()
spawn(20)
- src.scan_mob(src.scanner.occupant)
+ scan_mob(scanner.occupant)
loading = 0
- src.updateUsrDialog()
-
//No locking an open scanner.
- else if ((href_list["lock"]) && (!isnull(src.scanner)))
- if ((!src.scanner.locked) && (src.scanner.occupant))
- src.scanner.locked = 1
+ else if ((href_list["lock"]) && (!isnull(scanner)))
+ if ((!scanner.locked) && (scanner.occupant))
+ scanner.locked = 1
else
- src.scanner.locked = 0
+ scanner.locked = 0
+
+ else if ((href_list["eject"]) && (!isnull(scanner)))
+ if ((!scanner.locked) && (scanner.occupant))
+ scanner.eject_occupant()
else if (href_list["view_rec"])
- src.active_record = locate(href_list["view_rec"])
- if(istype(src.active_record,/datum/dna2/record))
- if ((isnull(src.active_record.ckey)))
- qdel(src.active_record)
- src.temp = "ERROR: Record Corrupt"
+ active_record = find_record(href_list["view_rec"])
+ if(istype(active_record,/datum/dna2/record))
+ if ((isnull(active_record.ckey)))
+ qdel(active_record)
+ temp = "ERROR: Record Corrupt"
else
- src.menu = 3
+ menu = 3
else
- src.active_record = null
- src.temp = "Record missing."
+ active_record = null
+ temp = "Record missing."
else if (href_list["del_rec"])
- if ((!src.active_record) || (src.menu < 3))
+ if ((!active_record) || (menu < 3))
return
- if (src.menu == 3) //If we are viewing a record, confirm deletion
- src.temp = "Delete record?"
- src.menu = 4
-
- else if (src.menu == 4)
- var/obj/item/weapon/card/id/C = usr.get_active_hand()
- if (istype(C)||istype(C, /obj/item/device/pda))
- if(src.check_access(C))
- src.records.Remove(src.active_record)
- qdel(src.active_record)
- src.temp = "Record deleted."
- src.menu = 2
- else
- src.temp = "Access Denied."
+ if (menu == 3) //If we are viewing a record, confirm deletion
+ temp = "Delete record?"
+ menu = 4
else if (href_list["disk"]) //Load or eject.
switch(href_list["disk"])
if("load")
- if ((isnull(src.diskette)) || isnull(src.diskette.buf))
- src.temp = "Load error."
- src.updateUsrDialog()
+ if ((isnull(diskette)) || isnull(diskette.buf))
+ temp = "Load error."
return
- if (isnull(src.active_record))
- src.temp = "Record error."
- src.menu = 1
- src.updateUsrDialog()
+ if (isnull(active_record))
+ temp = "Record error."
+ menu = 1
return
- src.active_record = src.diskette.buf
+ active_record = diskette.buf
- src.temp = "Load successful."
+ temp = "Load successful."
if("eject")
- if (!isnull(src.diskette))
- src.diskette.loc = src.loc
- src.diskette = null
+ if (!isnull(diskette))
+ diskette.loc = loc
+ diskette = null
else if (href_list["save_disk"]) //Save to disk!
- if ((isnull(src.diskette)) || (src.diskette.read_only) || (isnull(src.active_record)))
- src.temp = "Save error."
- src.updateUsrDialog()
- return
+ if ((isnull(diskette)) || (diskette.read_only) || (isnull(active_record)))
+ temp = "Save error."
// DNA2 makes things a little simpler.
- src.diskette.buf=src.active_record
- src.diskette.buf.types=0
+ diskette.buf = active_record
+ diskette.buf.types = 0
switch(href_list["save_disk"]) //Save as Ui/Ui+Ue/Se
if("ui")
- src.diskette.buf.types=DNA2_BUF_UI
+ diskette.buf.types = DNA2_BUF_UI
if("ue")
- src.diskette.buf.types=DNA2_BUF_UI|DNA2_BUF_UE
+ diskette.buf.types = DNA2_BUF_UI | DNA2_BUF_UE
if("se")
- src.diskette.buf.types=DNA2_BUF_SE
- src.diskette.name = "data disk - '[src.active_record.dna.real_name]'"
- src.temp = "Save \[[href_list["save_disk"]]\] successful."
+ diskette.buf.types = DNA2_BUF_SE
+ diskette.name = "data disk - '[active_record.dna.real_name]'"
+ temp = "Save \[[href_list["save_disk"]]\] successful."
else if (href_list["refresh"])
- src.updateUsrDialog()
+ updateUsrDialog()
else if (href_list["clone"])
- var/datum/dna2/record/C = locate(href_list["clone"])
+ var/datum/dna2/record/C = find_record(href_list["clone"])
//Look for that player! They better be dead!
if(istype(C))
//Can't clone without someone to clone. Or a pod. Or if the pod is busy. Or full of gibs.
@@ -340,11 +282,12 @@
temp = "Error: Data corruption."
else if (href_list["menu"])
- src.menu = text2num(href_list["menu"])
+ menu = href_list["menu"]
+ temp = ""
+ scantemp = ""
- src.add_fingerprint(usr)
- src.updateUsrDialog()
- return
+ nanomanager.update_uis(src)
+ add_fingerprint(usr)
/obj/machinery/computer/cloning/proc/scan_mob(mob/living/carbon/human/subject as mob)
if ((isnull(subject)) || (!(ishuman(subject))) || (!subject.dna))
@@ -381,13 +324,13 @@
subject.dna.check_integrity()
var/datum/dna2/record/R = new /datum/dna2/record()
- R.dna=subject.dna
+ R.dna = subject.dna
R.ckey = subject.ckey
- R.id= copytext(md5(subject.real_name), 2, 6)
- R.name=R.dna.real_name
- R.types=DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE
- R.languages=subject.languages
- R.flavor=subject.flavor_texts.Copy()
+ R.id = copytext(md5(subject.real_name), 2, 6)
+ R.name = R.dna.real_name
+ R.types = DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE
+ R.languages = subject.languages
+ R.flavor = subject.flavor_texts.Copy()
//Add an implant if needed
var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject)
@@ -402,13 +345,13 @@
if (!isnull(subject.mind)) //Save that mind so traitors can continue traitoring after cloning.
R.mind = "\ref[subject.mind]"
- src.records += R
+ records += R
scantemp = "Subject successfully scanned."
//Find a specific record by key.
/obj/machinery/computer/cloning/proc/find_record(var/find_key)
var/selected_record = null
- for(var/datum/dna2/record/R in src.records)
+ for(var/datum/dna2/record/R in records)
if (R.ckey == find_key)
selected_record = R
break
diff --git a/code/game/machinery/computer/guestpass.dm b/code/game/machinery/computer/guestpass.dm
index a4553403bc..b3f9765746 100644
--- a/code/game/machinery/computer/guestpass.dm
+++ b/code/game/machinery/computer/guestpass.dm
@@ -88,7 +88,7 @@
if(!giver && user.unEquip(I))
I.forceMove(src)
giver = I
- updateUsrDialog()
+ nanomanager.update_uis(src)
else if(giver)
user << "There is already ID card inside."
return
@@ -102,40 +102,51 @@
return
user.set_machine(src)
- var/dat
- if (mode == 1) //Logs
- dat += "Activity log
"
- for (var/entry in internal_log)
- dat += "[entry]
"
- dat += "Print
"
- dat += "Back
"
- else
- dat += "Guest pass terminal #[uid]
"
- dat += "View activity log
"
- dat += "Issuing ID: [giver]
"
- dat += "Issued to: [giv_name]
"
- dat += "Reason: [reason]
"
- dat += "Duration (minutes): [duration] m
"
- dat += "Access to areas:
"
- if (giver && giver.access)
- for (var/A in giver.access)
- var/area = get_access_desc(A)
- if (A in accesses)
- area = "[area]"
- dat += "[area]
"
- dat += "
Issue pass
"
+ ui_interact(user)
- user << browse(dat, "window=guestpass;size=400x520")
- onclose(user, "guestpass")
+/**
+ * Display the NanoUI window for the guest pass console.
+ *
+ * See NanoUI documentation for details.
+ */
+/obj/machinery/computer/guestpass/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
+ var/list/data = list()
+
+ var/area_list[0]
+
+ if (giver && giver.access)
+ data["access"] = giver.access
+ for (var/A in giver.access)
+ if(A in accesses)
+ area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = 1)
+ else
+ area_list[++area_list.len] = list("area" = A, "area_name" = get_access_desc(A), "on" = null)
+
+ data["giver"] = giver
+ data["giveName"] = giv_name
+ data["reason"] = reason
+ data["duration"] = duration
+ data["area"] = area_list
+ data["mode"] = mode
+ data["log"] = internal_log
+ data["uid"] = uid
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "guest_pass.tmpl", src.name, 400, 520)
+ ui.set_initial_data(data)
+ ui.open()
+ //ui.set_auto_update(5)
/obj/machinery/computer/guestpass/Topic(href, href_list)
if(..())
return 1
usr.set_machine(src)
if (href_list["mode"])
- mode = text2num(href_list["mode"])
+ mode = href_list["mode"]
if (href_list["choice"])
switch(href_list["choice"])
@@ -182,7 +193,6 @@
if (istype(I, /obj/item/weapon/card/id) && usr.unEquip(I))
I.loc = src
giver = I
- updateUsrDialog()
if ("print")
var/dat = "Activity log of guest pass terminal #[uid]
"
@@ -214,5 +224,6 @@
pass.name = "guest pass #[number]"
else
usr << "Cannot issue pass without issuing ID."
- updateUsrDialog()
- return
+
+ src.add_fingerprint(usr)
+ nanomanager.update_uis(src)
\ No newline at end of file
diff --git a/code/game/machinery/computer3/lapvend.dm b/code/game/machinery/computer3/lapvend.dm
index efd0747b35..6acb530acc 100644
--- a/code/game/machinery/computer3/lapvend.dm
+++ b/code/game/machinery/computer3/lapvend.dm
@@ -6,12 +6,10 @@
layer = 2.9
anchored = 1
density = 1
- var/datum/browser/popup = null
var/obj/machinery/computer3/laptop/vended/newlap = null
var/obj/item/device/laptop/relap = null
var/vendmode = 0
-
var/cardreader = 0
var/floppy = 0
var/radionet = 0
@@ -34,9 +32,11 @@
if(vendmode == 1 && I)
scan_id(I, W)
vendmode = 0
- if(vendmode == 3 && I)
+ nanomanager.update_uis(src)
+ if(vendmode == 2 && I)
if(reimburse_id(I, W))
vendmode = 0
+ nanomanager.update_uis(src)
if(vendmode == 0)
if(istype(W, /obj/item/device/laptop))
var/obj/item/device/laptop/L = W
@@ -44,84 +44,49 @@
calc_reimburse(L)
usr.drop_item()
L.loc = src
- vendmode = 3
+ vendmode = 2
usr << "You slot your [L.name] into \The [src.name]"
+ nanomanager.update_uis(src)
else
..()
/obj/machinery/lapvend/attack_hand(mob/user as mob)
+ if(stat & (BROKEN|NOPOWER))
+ return
+
+ ui_interact(user)
+
+/**
+ * Display the NanoUI window for the vending machine.
+ *
+ * See NanoUI documentation for details.
+ */
+/obj/machinery/lapvend/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
- var/vendorname = (src.name) //import the machine's name
- var/dat = "[vendorname]
" //display the name, and added a horizontal rule
- if(vendmode == 0)
- dat += "Please choose your laptop customization options
"
- dat += "Your comptuer will automatically be loaded with any programs you can use after the transaction is complete."
- dat += "Some programs will require additional components to be installed!
"
- dat += "HDD (Required) : Added
"
- dat += "Card Reader : Single (50) | Dual (125)
"
- dat += "Floppy Drive: Add (50)
"
- dat += "Radio Network card Add (50)
"
- dat += "Camera Card Add (100)
"
- dat += " Network card Area (75) Adjacent (50)Powernet (25)
"
- dat += "
Power source upgrade Extended (175) Unreal (250)"
- if(vendmode == 0 || vendmode == 1)
- dat += "
Cart
"
- dat += "Total: [total()]
"
- if(cardreader == 1)
- dat += "Card Reader: (single) (50)
"
- else if (cardreader == 2)
- dat += "Card Reader: (double) (125)
"
- else
- dat += "Card Reader: None
"
- if(floppy == 0)
- dat += "Floppy Drive: None
"
- else
- dat += "Floppy Drive: Added (50)
"
- if(radionet == 1)
- dat += "Radio Card: Added (50)
"
- else
- dat += "Radio Card: None
"
- if(camera == 1)
- dat += "Camera Card: Added (100)
"
- else
- dat += "Camera Card: None
"
- if(network == 1)
- dat += "Network card: Area (75)
"
- else if(network == 2)
- dat += "Network card: Adjacent (50)
"
- else if(network == 3)
- dat += "Network card: Powernet (25)
"
- else
- dat += "Network card: None"
- if (power == 0)
- dat += "Power source: Regular"
- else if (power == 1)
- dat += "Power source: Extended (175)
"
- else
- dat += "Power source: Unreal (250)
"
-
- if(vendmode == 0)
- dat += "
Vend Laptop"
-
- if(vendmode == 1)
- dat += "Please swipe your card and enter your PIN to complete the transaction"
-
- if(vendmode == 3)
- dat += "Please swipe your card and enter your PIN to be finish returning your computer
"
- dat += "Cancel"
-
-
-
-
- popup = new(user, "lapvend", name, 450, 500)
- popup.set_content(dat)
- popup.open()
- return
+ var/list/data = list()
+ data["mode"] = vendmode
+ data["cardreader"] = cardreader
+ data["floppy"] = floppy
+ data["radionet"] = radionet
+ data["camera"] = camera
+ data["network"] = network
+ data["power"] = power
+ data["total"] = total()
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "laptop_vendor.tmpl", src.name, 480, 425)
+ ui.set_initial_data(data)
+ ui.open()
+ //ui.set_auto_update(5)
/obj/machinery/lapvend/Topic(href, href_list)
+ if(stat & (BROKEN|NOPOWER))
+ return
+ if(usr.stat || usr.restrained())
+ return
if ((usr.contents.Find(src) || (in_range(src, usr) && istype(src.loc, /turf))))
usr.set_machine(src)
switch(href_list["choice"])
@@ -146,7 +111,7 @@
if ("super_add")
power = 2
- if ("single_rem" || "dual_rem")
+ if ("cardreader_rem")
cardreader = 0
if ("floppy_rem")
floppy = 0
@@ -154,9 +119,9 @@
radionet = 0
if ("camnet_rem")
camera = 0
- if ("area_rem" || "prox_rem" || "cable_rem")
+ if ("network_rem")
network = 0
- if ("high_rem" || "super_rem")
+ if ("power_rem")
power = 0
if("vend")
@@ -168,9 +133,8 @@
relap = null
vendmode = 0
- src.updateUsrDialog()
- return
-
+ src.add_fingerprint(usr)
+ nanomanager.update_uis(src)
/obj/machinery/lapvend/proc/vend()
if(cardreader > 0)
@@ -253,7 +217,6 @@
choose_progs(C)
vend()
- popup.close()
newlap.close_laptop()
newlap = null
cardreader = 0
diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm
index c7c1d59a08..7532cb1407 100644
--- a/code/game/machinery/flasher.dm
+++ b/code/game/machinery/flasher.dm
@@ -77,11 +77,12 @@
if(!E)
return
if(E.is_bruised() && prob(E.damage + 50))
- flick("e_flash", O:flash)
+ H.flash_eyes()
E.damage += rand(1, 5)
else
- if(!O.blinded)
- flick("flash", O:flash)
+ if(!O.blinded && isliving(O))
+ var/mob/living/L = O
+ L.flash_eyes()
O.Weaken(flash_time)
/obj/machinery/flasher/emp_act(severity)
diff --git a/code/game/machinery/kitchen/cooking_machines/_cooker.dm b/code/game/machinery/kitchen/cooking_machines/_cooker.dm
new file mode 100644
index 0000000000..a6af0f13f2
--- /dev/null
+++ b/code/game/machinery/kitchen/cooking_machines/_cooker.dm
@@ -0,0 +1,242 @@
+// This folder contains code that was originally ported from Apollo Station and then refactored/optimized/changed.
+
+// Tracks precooked food to stop deep fried baked grilled grilled grilled diona nymph cereal.
+/obj/item/weapon/reagent_containers/food/snacks/var/list/cooked
+
+// Root type for cooking machines. See following files for specific implementations.
+/obj/machinery/cooker
+ name = "cooker"
+ desc = "You shouldn't be seeing this!"
+ icon = 'icons/obj/cooking_machines.dmi'
+ density = 1
+ anchored = 1
+ use_power = 1
+ idle_power_usage = 5
+
+ var/on_icon // Icon state used when cooking.
+ var/off_icon // Icon state used when not cooking.
+ var/cooking // Whether or not the machine is currently operating.
+ var/cook_type // A string value used to track what kind of food this machine makes.
+ var/cook_time = 200 // How many ticks the cooking will take.
+ var/can_cook_mobs // Whether or not this machine accepts grabbed mobs.
+ var/food_color // Colour of resulting food item.
+ var/cooked_sound // Sound played when cooking completes.
+ var/can_burn_food // Can the object burn food that is left inside?
+ var/burn_chance = 10 // How likely is the food to burn?
+ var/obj/item/cooking_obj // Holder for the currently cooking object.
+
+ // If the machine has multiple output modes, define them here.
+ var/selected_option
+ var/list/output_options = list()
+
+/obj/machinery/cooker/Destroy()
+ if(cooking_obj)
+ qdel(cooking_obj)
+ cooking_obj = null
+ return ..()
+
+/obj/machinery/cooker/examine()
+ ..()
+ if(cooking_obj && Adjacent(usr))
+ usr << "You can see \a [cooking_obj] inside."
+
+/obj/machinery/cooker/attackby(var/obj/item/I, var/mob/user)
+
+ if(!cook_type || (stat & (NOPOWER|BROKEN)))
+ user << "\The [src] is not working."
+ return
+
+ if(cooking)
+ user << "\The [src] is running!"
+ return
+
+ // We are trying to cook a grabbed mob.
+ var/obj/item/weapon/grab/G = I
+ if(istype(G))
+
+ if(!can_cook_mobs)
+ user << "That's not going to fit."
+ return
+
+ if(!isliving(G.affecting))
+ user << "You can't cook that."
+ return
+
+ cook_mob(G.affecting, user)
+ return
+
+ // We're trying to cook something else. Check if it's valid.
+ var/obj/item/weapon/reagent_containers/food/snacks/check = I
+ if(istype(check) && islist(check.cooked) && (cook_type in check.cooked))
+ user << "\The [check] has already been [cook_type]."
+ return 0
+ else if(istype(check, /obj/item/weapon/reagent_containers/glass))
+ user << "That would probably break [src]."
+ return 0
+ else if(istype(check, /obj/item/weapon/disk/nuclear))
+ user << "Central Command would kill you if you [cook_type] that."
+ return 0
+ else if(!istype(check) && !istype(check, /obj/item/weapon/holder) && !istype(check, /obj/item/organ))
+ user << "That's not edible."
+ return 0
+
+ if(istype(I, /obj/item/organ))
+ var/obj/item/organ/O = I
+ if(O.robotic)
+ user << "That would probably break [src]."
+ return
+
+ // Gotta hurt.
+ if(istype(cooking_obj, /obj/item/weapon/holder))
+ for(var/mob/living/M in cooking_obj.contents)
+ M.apply_damage(rand(30,40), BURN, "chest")
+
+ // Not sure why a food item that passed the previous checks would fail to drop, but safety first.
+ if(!user.unEquip(I))
+ return
+
+ // We can actually start cooking now.
+ user.visible_message("\The [user] puts \the [I] into \the [src].")
+ cooking_obj = I
+ cooking_obj.forceMove(src)
+ cooking = 1
+ icon_state = on_icon
+
+ // Doop de doo. Jeopardy theme goes here.
+ sleep(cook_time)
+
+ // Sanity checks.
+ if(!cooking_obj || cooking_obj.loc != src)
+ cooking_obj = null
+ icon_state = off_icon
+ cooking = 0
+ return
+
+ // RIP slow-moving held mobs.
+ if(istype(cooking_obj, /obj/item/weapon/holder))
+ for(var/mob/living/M in cooking_obj.contents)
+ M.death()
+
+ // Cook the food.
+ var/cook_path
+ if(selected_option && output_options.len)
+ cook_path = output_options[selected_option]
+ if(!cook_path)
+ cook_path = /obj/item/weapon/reagent_containers/food/snacks/variable
+ var/obj/item/weapon/reagent_containers/food/snacks/result = new cook_path(src) //Holy typepaths, Batman.
+
+ // Set icon and appearance.
+ change_product_appearance(result)
+
+ // Update strings.
+ change_product_strings(result)
+
+ // Copy reagents over. trans_to_obj must be used, as trans_to fails for snacks due to is_open_container() failing.
+ if(cooking_obj.reagents && cooking_obj.reagents.total_volume)
+ cooking_obj.reagents.trans_to_obj(result, cooking_obj.reagents.total_volume)
+
+ // Set cooked data.
+ var/obj/item/weapon/reagent_containers/food/snacks/food_item = cooking_obj
+ if(istype(food_item) && islist(food_item.cooked))
+ result.cooked = food_item.cooked.Copy()
+ else
+ result.cooked = list()
+ result.cooked |= cook_type
+
+ // Reset relevant variables.
+ qdel(cooking_obj)
+ src.visible_message("\The [src] pings!")
+ if(cooked_sound)
+ playsound(get_turf(src), cooked_sound, 50, 1)
+
+ if(!can_burn_food)
+ icon_state = off_icon
+ cooking = 0
+ result.forceMove(get_turf(src))
+ cooking_obj = null
+ else
+ var/failed
+ var/overcook_period = max(Floor(cook_time/5),1)
+ cooking_obj = result
+ var/count = overcook_period
+ while(1)
+ sleep(overcook_period)
+ count += overcook_period
+ if(!cooking || !result || result.loc != src)
+ failed = 1
+ else if(prob(burn_chance) || count == cook_time) //Fail before it has a chance to cook again.
+ // You dun goofed.
+ qdel(cooking_obj)
+ cooking_obj = new /obj/item/weapon/reagent_containers/food/snacks/badrecipe(src)
+ // Produce nasty smoke.
+ visible_message("\The [src] vomits a gout of rancid smoke!")
+ var/datum/effect/effect/system/smoke_spread/bad/smoke = PoolOrNew(/datum/effect/effect/system/smoke_spread/bad)
+ smoke.attach(src)
+ smoke.set_up(10, 0, usr.loc)
+ smoke.start()
+ failed = 1
+
+ if(failed)
+ cooking = 0
+ icon_state = off_icon
+ break
+
+/obj/machinery/cooker/attack_hand(var/mob/user)
+
+ if(cooking_obj)
+ user << "You grab \the [cooking_obj] from \the [src]."
+ user.put_in_hands(cooking_obj)
+ cooking = 0
+ cooking_obj = null
+ icon_state = off_icon
+ return
+
+ if(output_options.len)
+
+ if(cooking)
+ user << "\The [src] is in use!"
+ return
+
+ var/choice = input("What specific food do you wish to make with \the [src]?") as null|anything in output_options+"Default"
+ if(!choice)
+ return
+ if(choice == "Default")
+ selected_option = null
+ user << "You decide not to make anything specific with \the [src]."
+ else
+ selected_option = choice
+ user << "You prepare \the [src] to make \a [selected_option]."
+
+ ..()
+
+/obj/machinery/cooker/proc/cook_mob(var/mob/living/victim, var/mob/user)
+ return
+
+/obj/machinery/cooker/proc/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product)
+ if(product.type == /obj/item/weapon/reagent_containers/food/snacks/variable) // Base type, generic.
+ product.name = "[cook_type] [cooking_obj.name]"
+ product.desc = "[cooking_obj.desc] It has been [cook_type]."
+ else
+ product.name = "[cooking_obj.name] [product.name]"
+
+/obj/machinery/cooker/proc/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/product)
+ if(product.type == /obj/item/weapon/reagent_containers/food/snacks/variable) // Base type, generic.
+ product.appearance = cooking_obj
+ product.color = food_color
+ product.filling_color = food_color
+
+ // Make 'em into a corpse.
+ if(istype(cooking_obj, /obj/item/weapon/holder))
+ var/matrix/M = matrix()
+ M.Turn(90)
+ M.Translate(1,-6)
+ product.transform = M
+ else
+ var/image/I = image(product.icon, "[product.icon_state]_filling")
+ if(istype(cooking_obj, /obj/item/weapon/reagent_containers/food/snacks))
+ var/obj/item/weapon/reagent_containers/food/snacks/S = cooking_obj
+ I.color = S.filling_color
+ if(!I.color)
+ I.color = food_color
+ product.overlays += I
+
diff --git a/code/game/machinery/kitchen/cooking_machines/_cooker_output.dm b/code/game/machinery/kitchen/cooking_machines/_cooker_output.dm
new file mode 100644
index 0000000000..cb4dcd15ed
--- /dev/null
+++ b/code/game/machinery/kitchen/cooking_machines/_cooker_output.dm
@@ -0,0 +1,72 @@
+// Wrapper obj for cooked food. Appearance is set in the cooking code, not on spawn.
+/obj/item/weapon/reagent_containers/food/snacks/variable
+ name = "cooked food"
+ icon = 'icons/obj/food_custom.dmi'
+ desc = "If you can see this description then something is wrong. Please report the bug on the tracker."
+ nutriment_amt = 5
+ bitesize = 2
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/pizza
+ name = "personal pizza"
+ desc = "A personalized pan pizza meant for only one person."
+ icon_state = "personal_pizza"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/bread
+ name = "bread"
+ desc = "Tasty bread."
+ icon_state = "breadcustom"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/pie
+ name = "pie"
+ desc = "Tasty pie."
+ icon_state = "piecustom"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/cake
+ name = "cake"
+ desc = "A popular band."
+ icon_state = "cakecustom"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/pocket
+ name = "hot pocket"
+ desc = "You wanna put a bangin- oh, nevermind."
+ icon_state = "donk"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/kebab
+ name = "kebab"
+ desc = "Remove this!"
+ icon_state = "kabob"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/waffles
+ name = "waffles"
+ desc = "Made with love."
+ icon_state = "waffles"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/cookie
+ name = "cookie"
+ desc = "Sugar snap!"
+ icon_state = "cookie"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/donut
+ name = "filled donut"
+ desc = "Donut eat this!" // kill me
+ icon_state = "donut"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/jawbreaker
+ name = "flavored jawbreaker"
+ desc = "It's like cracking a molar on a rainbow."
+ icon_state = "jawbreaker"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/candybar
+ name = "flavored chocolate bar"
+ desc = "Made in a factory downtown."
+ icon_state = "bar"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/sucker
+ name = "flavored sucker"
+ desc = "Suck, suck, suck."
+ icon_state = "sucker"
+
+/obj/item/weapon/reagent_containers/food/snacks/variable/jelly
+ name = "jelly"
+ desc = "All your friends will be jelly."
+ icon_state = "jellycustom"
diff --git a/code/game/machinery/kitchen/cooking_machines/candy.dm b/code/game/machinery/kitchen/cooking_machines/candy.dm
new file mode 100644
index 0000000000..21fd506911
--- /dev/null
+++ b/code/game/machinery/kitchen/cooking_machines/candy.dm
@@ -0,0 +1,18 @@
+/obj/machinery/cooker/candy
+ name = "candy machine"
+ desc = "Get yer candied cheese wheels here!"
+ icon_state = "mixer_off"
+ off_icon = "mixer_off"
+ on_icon = "mixer_on"
+ cook_type = "candied"
+
+ output_options = list(
+ "Jawbreaker" = /obj/item/weapon/reagent_containers/food/snacks/variable/jawbreaker,
+ "Candy Bar" = /obj/item/weapon/reagent_containers/food/snacks/variable/candybar,
+ "Sucker" = /obj/item/weapon/reagent_containers/food/snacks/variable/sucker,
+ "Jelly" = /obj/item/weapon/reagent_containers/food/snacks/variable/jelly
+ )
+
+/obj/machinery/cooker/candy/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/cooked/product)
+ food_color = get_random_colour(1)
+ . = ..()
diff --git a/code/game/machinery/kitchen/cooking_machines/cereal.dm b/code/game/machinery/kitchen/cooking_machines/cereal.dm
new file mode 100644
index 0000000000..3a7b19c9b1
--- /dev/null
+++ b/code/game/machinery/kitchen/cooking_machines/cereal.dm
@@ -0,0 +1,25 @@
+/obj/machinery/cooker/cereal
+ name = "cereal maker"
+ desc = "Now with Dann O's available!"
+ icon = 'icons/obj/cooking_machines.dmi'
+ icon_state = "cereal_off"
+ cook_type = "cerealized"
+ on_icon = "cereal_on"
+ off_icon = "cereal_off"
+
+/obj/machinery/cooker/cereal/change_product_strings(var/obj/item/weapon/reagent_containers/food/snacks/product)
+ . = ..()
+ product.name = "box of [cooking_obj.name] cereal"
+
+/obj/machinery/cooker/cereal/change_product_appearance(var/obj/item/weapon/reagent_containers/food/snacks/product)
+ product.icon = 'icons/obj/food.dmi'
+ product.icon_state = "cereal_box"
+ product.filling_color = cooking_obj.color
+
+ var/image/food_image = image(cooking_obj.icon, cooking_obj.icon_state)
+ food_image.color = cooking_obj.color
+ food_image.overlays += cooking_obj.overlays
+ food_image.transform *= 0.7
+
+ product.overlays += food_image
+
diff --git a/code/game/machinery/kitchen/cooking_machines/fryer.dm b/code/game/machinery/kitchen/cooking_machines/fryer.dm
new file mode 100644
index 0000000000..1fc0e75ef1
--- /dev/null
+++ b/code/game/machinery/kitchen/cooking_machines/fryer.dm
@@ -0,0 +1,67 @@
+/obj/machinery/cooker/fryer
+ name = "deep fryer"
+ desc = "Deep fried everything."
+ icon_state = "fryer_off"
+ can_cook_mobs = 1
+ cook_type = "deep fried"
+ on_icon = "fryer_on"
+ off_icon = "fryer_off"
+ food_color = "#FFAD33"
+ cooked_sound = 'sound/machines/ding.ogg'
+
+/obj/machinery/cooker/fryer/cook_mob(var/mob/living/victim, var/mob/user)
+
+ if(!istype(victim))
+ return
+
+ user.visible_message("\The [user] starts pushing \the [victim] into \the [src]!")
+ icon_state = on_icon
+ cooking = 1
+
+ if(!do_mob(user, victim, 20))
+ cooking = 0
+ icon_state = off_icon
+ return
+
+ if(!victim || !victim.Adjacent(user))
+ user << "Your victim slipped free!"
+ cooking = 0
+ icon_state = off_icon
+ return
+
+ var/obj/item/organ/external/E
+ var/nopain
+ if(ishuman(victim) && user.zone_sel.selecting != "groin" && user.zone_sel.selecting != "chest")
+ var/mob/living/carbon/human/H = victim
+ if(H.species.flags & NO_PAIN)
+ nopain = 2
+ E = H.get_organ(user.zone_sel.selecting)
+ if(E.status & ORGAN_ROBOT)
+ nopain = 1
+
+ user.visible_message("\The [user] shoves \the [victim][E ? "'s [E.name]" : ""] into \the [src]!")
+
+ if(E)
+ E.take_damage(0, rand(20,30))
+ if(E.children && E.children.len)
+ for(var/obj/item/organ/external/child in E.children)
+ if(nopain && nopain < 2 && !(child.status & ORGAN_ROBOT))
+ nopain = 0
+ child.take_damage(0, rand(20,30))
+ else
+ victim.apply_damage(rand(30,40), BURN, user.zone_sel.selecting)
+
+ if(!nopain)
+ victim << "Agony consumes you as searing hot oil scorches your [E ? E.name : "flesh"] horribly!"
+ victim.emote("scream")
+ else
+ victim << "Searing hot oil scorches your [E ? E.name : "flesh"]!"
+
+ if(victim.client)
+ user.attack_log += text("\[[time_stamp()]\] Has [cook_type] \the [victim] ([victim.ckey]) in \a [src]")
+ victim.attack_log += text("\[[time_stamp()]\] Has been [cook_type] in \a [src] by [user.name] ([user.ckey])")
+ msg_admin_attack("[user] ([user.ckey]) [cook_type] \the [victim] ([victim.ckey]) in \a [src]. (JMP)")
+
+ icon_state = off_icon
+ cooking = 0
+ return
diff --git a/code/game/machinery/kitchen/cooking_machines/grill.dm b/code/game/machinery/kitchen/cooking_machines/grill.dm
new file mode 100644
index 0000000000..312189c588
--- /dev/null
+++ b/code/game/machinery/kitchen/cooking_machines/grill.dm
@@ -0,0 +1,10 @@
+/obj/machinery/cooker/grill
+ name = "grill"
+ desc = "Backyard grilling, IN SPACE."
+ icon_state = "grill_off"
+ cook_type = "grilled"
+ cook_time = 100
+ food_color = "#A34719"
+ on_icon = "grill_on"
+ off_icon = "grill_off"
+ can_burn_food = 1
\ No newline at end of file
diff --git a/code/game/machinery/kitchen/cooking_machines/oven.dm b/code/game/machinery/kitchen/cooking_machines/oven.dm
new file mode 100644
index 0000000000..ec941af223
--- /dev/null
+++ b/code/game/machinery/kitchen/cooking_machines/oven.dm
@@ -0,0 +1,23 @@
+/obj/machinery/cooker/oven
+ name = "oven"
+ desc = "Cookies are ready, dear."
+ icon = 'icons/obj/cooking_machines.dmi'
+ icon_state = "oven_off"
+ on_icon = "oven_on"
+ off_icon = "oven_off"
+ cook_type = "baked"
+ cook_time = 300
+ food_color = "#A34719"
+ can_burn_food = 1
+
+ output_options = list(
+ "Personal Pizza" = /obj/item/weapon/reagent_containers/food/snacks/variable/pizza,
+ "Bread" = /obj/item/weapon/reagent_containers/food/snacks/variable/bread,
+ "Pie" = /obj/item/weapon/reagent_containers/food/snacks/variable/pie,
+ "Small Cake" = /obj/item/weapon/reagent_containers/food/snacks/variable/cake,
+ "Hot Pocket" = /obj/item/weapon/reagent_containers/food/snacks/variable/pocket,
+ "Kebab" = /obj/item/weapon/reagent_containers/food/snacks/variable/kebab,
+ "Waffles" = /obj/item/weapon/reagent_containers/food/snacks/variable/waffles,
+ "Cookie" = /obj/item/weapon/reagent_containers/food/snacks/variable/cookie,
+ "Donut" = /obj/item/weapon/reagent_containers/food/snacks/variable/donut,
+ )
\ No newline at end of file
diff --git a/code/game/machinery/kitchen/icecream.dm b/code/game/machinery/kitchen/icecream.dm
new file mode 100644
index 0000000000..448b252fd4
--- /dev/null
+++ b/code/game/machinery/kitchen/icecream.dm
@@ -0,0 +1,196 @@
+#define ICECREAM_VANILLA 1
+#define ICECREAM_CHOCOLATE 2
+#define ICECREAM_STRAWBERRY 3
+#define ICECREAM_BLUE 4
+#define CONE_WAFFLE 5
+#define CONE_CHOC 6
+
+// Ported wholesale from Apollo Station.
+
+/obj/machinery/icecream_vat
+ name = "icecream vat"
+ desc = "Ding-aling ding dong. Get your NanoTrasen-approved ice cream!"
+ icon = 'icons/obj/kitchen.dmi'
+ icon_state = "icecream_vat"
+ density = 1
+ anchored = 0
+ use_power = 0
+ flags = OPENCONTAINER | NOREACT
+
+ var/list/product_types = list()
+ var/dispense_flavour = ICECREAM_VANILLA
+ var/flavour_name = "vanilla"
+
+/obj/machinery/icecream_vat/proc/get_ingredient_list(var/type)
+ switch(type)
+ if(ICECREAM_CHOCOLATE)
+ return list("milk", "ice", "coco")
+ if(ICECREAM_STRAWBERRY)
+ return list("milk", "ice", "berryjuice")
+ if(ICECREAM_BLUE)
+ return list("milk", "ice", "singulo")
+ if(CONE_WAFFLE)
+ return list("flour", "sugar")
+ if(CONE_CHOC)
+ return list("flour", "sugar", "coco")
+ else
+ return list("milk", "ice")
+
+/obj/machinery/icecream_vat/proc/get_flavour_name(var/flavour_type)
+ switch(flavour_type)
+ if(ICECREAM_CHOCOLATE)
+ return "chocolate"
+ if(ICECREAM_STRAWBERRY)
+ return "strawberry"
+ if(ICECREAM_BLUE)
+ return "blue"
+ if(CONE_WAFFLE)
+ return "waffle"
+ if(CONE_CHOC)
+ return "chocolate"
+ else
+ return "vanilla"
+
+/obj/machinery/icecream_vat/initialize()
+ ..()
+ create_reagents(100)
+ while(product_types.len < 6)
+ product_types.Add(5)
+ reagents.add_reagent("milk", 5)
+ reagents.add_reagent("flour", 5)
+ reagents.add_reagent("sugar", 5)
+ reagents.add_reagent("ice", 5)
+
+/obj/machinery/icecream_vat/attack_hand(mob/user as mob)
+ user.set_machine(src)
+ interact(user)
+
+/obj/machinery/icecream_vat/interact(mob/user as mob)
+ var/dat
+ dat += "ICECREAM
"
+ dat += "
Dispensing: [flavour_name] icecream "
+ dat += "
Vanilla icecream: Select Make x5 [product_types[ICECREAM_VANILLA]] scoops left. (Ingredients: milk, ice)
"
+ dat += "
Strawberry icecream: Select Make x5 [product_types[ICECREAM_STRAWBERRY]] dollops left. (Ingredients: milk, ice, berry juice)
"
+ dat += "
Chocolate icecream: Select Make x5 [product_types[ICECREAM_CHOCOLATE]] dollops left. (Ingredients: milk, ice, coco powder)
"
+ dat += "
Blue icecream: Select Make x5 [product_types[ICECREAM_BLUE]] dollops left. (Ingredients: milk, ice, singulo)
"
+ dat += "
CONES
"
+ dat += "
Waffle cones: Dispense Make x5 [product_types[CONE_WAFFLE]] cones left. (Ingredients: flour, sugar)
"
+ dat += "
Chocolate cones: Dispense Make x5 [product_types[CONE_CHOC]] cones left. (Ingredients: flour, sugar, coco powder)
"
+ dat += "
"
+ dat += "VAT CONTENT
"
+ for(var/datum/reagent/R in reagents.reagent_list)
+ dat += "[R.name]: [R.volume]"
+ dat += "Purge
"
+ dat += "Refresh Close"
+
+ var/datum/browser/popup = new(user, "icecreamvat","Icecream Vat", 700, 500, src)
+ popup.set_content(dat)
+ popup.open()
+
+/obj/machinery/icecream_vat/attackby(var/obj/item/O as obj, var/mob/user as mob)
+ if(istype(O, /obj/item/weapon/reagent_containers/food/snacks/icecream))
+ var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = O
+ if(!I.ice_creamed)
+ if(product_types[dispense_flavour] > 0)
+ src.visible_message("\icon[src] [user] scoops delicious [flavour_name] icecream into [I].")
+ product_types[dispense_flavour] -= 1
+ I.add_ice_cream(flavour_name)
+ // if(beaker)
+ // beaker.reagents.trans_to(I, 10)
+ if(I.reagents.total_volume < 10)
+ I.reagents.add_reagent("sugar", 10 - I.reagents.total_volume)
+ else
+ user << "There is not enough icecream left!"
+ else
+ user << "[O] already has icecream in it."
+ return 1
+ else if(O.is_open_container())
+ return
+ else
+ ..()
+
+/obj/machinery/icecream_vat/proc/make(var/mob/user, var/make_type, var/amount)
+ for(var/R in get_ingredient_list(make_type))
+ if(reagents.has_reagent(R, amount))
+ continue
+ amount = 0
+ break
+ if(amount)
+ for(var/R in get_ingredient_list(make_type))
+ reagents.remove_reagent(R, amount)
+ product_types[make_type] += amount
+ var/flavour = get_flavour_name(make_type)
+ if(make_type > 4)
+ src.visible_message("[user] cooks up some [flavour] cones.")
+ else
+ src.visible_message("[user] whips up some [flavour] icecream.")
+ else
+ user << "You don't have the ingredients to make this."
+
+/obj/machinery/icecream_vat/Topic(href, href_list)
+
+ if(..())
+ return
+
+ if(href_list["select"])
+ dispense_flavour = text2num(href_list["select"])
+ flavour_name = get_flavour_name(dispense_flavour)
+ src.visible_message("[usr] sets [src] to dispense [flavour_name] flavoured icecream.")
+
+ if(href_list["cone"])
+ var/dispense_cone = text2num(href_list["cone"])
+ var/cone_name = get_flavour_name(dispense_cone)
+ if(product_types[dispense_cone] >= 1)
+ product_types[dispense_cone] -= 1
+ var/obj/item/weapon/reagent_containers/food/snacks/icecream/I = new(src.loc)
+ I.cone_type = cone_name
+ I.icon_state = "icecream_cone_[cone_name]"
+ I.desc = "Delicious [cone_name] cone, but no ice cream."
+ src.visible_message("[usr] dispenses a crunchy [cone_name] cone from [src].")
+ else
+ usr << "There are no [cone_name] cones left!"
+
+ if(href_list["make"])
+ var/amount = (text2num(href_list["amount"]))
+ var/C = text2num(href_list["make"])
+ make(usr, C, amount)
+
+ if(href_list["disposeI"])
+ reagents.del_reagent(href_list["disposeI"])
+
+ updateDialog()
+
+ if(href_list["refresh"])
+ updateDialog()
+
+ if(href_list["close"])
+ usr.unset_machine()
+ usr << browse(null,"window=icecreamvat")
+ return
+
+/obj/item/weapon/reagent_containers/food/snacks/icecream
+ name = "ice cream cone"
+ desc = "Delicious waffle cone, but no ice cream."
+ icon_state = "icecream_cone_waffle" //default for admin-spawned cones, href_list["cone"] should overwrite this all the time
+ layer = 3.1
+ bitesize = 3
+
+ var/ice_creamed = 0
+ var/cone_type
+
+/obj/item/weapon/reagent_containers/food/snacks/icecream/New()
+ create_reagents(20)
+ reagents.add_reagent("nutriment", 5)
+
+/obj/item/weapon/reagent_containers/food/snacks/icecream/proc/add_ice_cream(var/flavour_name)
+ name = "[flavour_name] icecream"
+ src.overlays += "icecream_[flavour_name]"
+ desc = "Delicious [cone_type] cone with a dollop of [flavour_name] ice cream."
+ ice_creamed = 1
+
+#undef ICECREAM_VANILLA
+#undef FLAVOUR_CHOCOLATE
+#undef FLAVOUR_STRAWBERRY
+#undef FLAVOUR_BLUE
+#undef CONE_WAFFLE
+#undef CONE_CHOC
\ No newline at end of file
diff --git a/code/game/machinery/pipe/construction.dm b/code/game/machinery/pipe/construction.dm
index 3a08a681d2..9c5fc61332 100644
--- a/code/game/machinery/pipe/construction.dm
+++ b/code/game/machinery/pipe/construction.dm
@@ -476,7 +476,7 @@ Buildable meters
if(PIPE_SUPPLY_STRAIGHT, PIPE_SUPPLY_BENT)
var/obj/machinery/atmospherics/pipe/simple/hidden/supply/P = new( src.loc )
- P.color = color
+ P.pipe_color = color
P.set_dir(src.dir)
P.initialize_directions = pipe_dir
var/turf/T = P.loc
@@ -495,7 +495,7 @@ Buildable meters
if(PIPE_SCRUBBERS_STRAIGHT, PIPE_SCRUBBERS_BENT)
var/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers/P = new( src.loc )
- P.color = color
+ P.pipe_color = color
P.set_dir(src.dir)
P.initialize_directions = pipe_dir
var/turf/T = P.loc
@@ -514,7 +514,7 @@ Buildable meters
if(PIPE_UNIVERSAL)
var/obj/machinery/atmospherics/pipe/simple/hidden/universal/P = new( src.loc )
- P.color = color
+ P.pipe_color = color
P.set_dir(src.dir)
P.initialize_directions = pipe_dir
var/turf/T = P.loc
@@ -588,7 +588,7 @@ Buildable meters
if(PIPE_SUPPLY_MANIFOLD) //manifold
var/obj/machinery/atmospherics/pipe/manifold/hidden/supply/M = new( src.loc )
- M.color = color
+ M.pipe_color = color
M.set_dir(dir)
M.initialize_directions = pipe_dir
//M.New()
@@ -611,7 +611,7 @@ Buildable meters
if(PIPE_SCRUBBERS_MANIFOLD) //manifold
var/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers/M = new( src.loc )
- M.color = color
+ M.pipe_color = color
M.set_dir(dir)
M.initialize_directions = pipe_dir
//M.New()
@@ -660,7 +660,7 @@ Buildable meters
if(PIPE_SUPPLY_MANIFOLD4W) //4-way manifold
var/obj/machinery/atmospherics/pipe/manifold4w/hidden/supply/M = new( src.loc )
- M.color = color
+ M.pipe_color = color
M.set_dir(dir)
M.initialize_directions = pipe_dir
M.connect_types = src.connect_types
@@ -687,7 +687,7 @@ Buildable meters
if(PIPE_SCRUBBERS_MANIFOLD4W) //4-way manifold
var/obj/machinery/atmospherics/pipe/manifold4w/hidden/scrubbers/M = new( src.loc )
- M.color = color
+ M.pipe_color = color
M.set_dir(dir)
M.initialize_directions = pipe_dir
M.connect_types = src.connect_types
diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm
index 4fc07a2a8a..b7bb820f54 100644
--- a/code/game/objects/effects/overlays.dm
+++ b/code/game/objects/effects/overlays.dm
@@ -73,27 +73,9 @@
icon_state = "snowairlock"
layer = 3.2 //Just above airlocks
-/obj/effect/overlay/snow/floor/north
- icon_state = "snowfloor_n"
+/obj/effect/overlay/snow/floor/pointy
+ icon_state = "snowfloorpointy"
-/obj/effect/overlay/snow/floor/south
- icon_state = "snowfloor_s"
-
-/obj/effect/overlay/snow/floor/east
- icon_state = "snowfloor_e"
-
-/obj/effect/overlay/snow/floor/west
- icon_state = "snowfloor_w"
-
-/obj/effect/overlay/snow/wall/north
- icon_state = "snowwall_n"
+/obj/effect/overlay/snow/wall
+ icon_state = "snowwall"
layer = 5 //Same as lights so humans can stand under it
-
-/obj/effect/overlay/snow/wall/south
- icon_state = "snowwall_s"
-
-/obj/effect/overlay/snow/wall/east
- icon_state = "snowwall_e"
-
-/obj/effect/overlay/snow/wall/west
- icon_state = "snowwall_w"
\ No newline at end of file
diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm
index ae18aed86c..d143220935 100644
--- a/code/game/objects/items/devices/flash.dm
+++ b/code/game/objects/items/devices/flash.dm
@@ -80,7 +80,7 @@
flash_strength *= H.species.flash_mod
if(flash_strength > 0)
M.Weaken(flash_strength)
- flick("e_flash", M.flash)
+ M.flash_eyes()
else
flashfail = 1
@@ -158,7 +158,7 @@
var/safety = M:eyecheck()
if(!safety)
if(!M.blinded)
- flick("flash", M.flash)
+ M.flash_eyes()
return
@@ -177,7 +177,7 @@
var/safety = M.eyecheck()
if(safety <= 0)
M.Weaken(10)
- flick("e_flash", M.flash)
+ M.flash_eyes()
for(var/mob/O in viewers(M, null))
O.show_message("[M] is blinded by the flash!")
..()
diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm
index c3fcf893ac..6a68d555b0 100644
--- a/code/game/objects/items/devices/flashlight.dm
+++ b/code/game/objects/items/devices/flashlight.dm
@@ -79,9 +79,9 @@
user << "\The [M]'s pupils narrow slightly, but are still very dilated."
else
user << "\The [M]'s pupils narrow."
-
+
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN) //can be used offensively
- flick("flash", M.flash)
+ M.flash_eyes()
else
return ..()
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index a4b159b734..8c9452ea49 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -24,8 +24,16 @@ REAGENT SCANNER
origin_tech = list(TECH_MAGNET = 1, TECH_BIO = 1)
var/mode = 1;
+/obj/item/device/healthanalyzer/do_surgery(mob/living/M, mob/living/user)
+ if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
+ return ..()
+ scan_mob(M, user) //default surgery behaviour is just to scan as usual
+ return 1
-/obj/item/device/healthanalyzer/attack(mob/living/M as mob, mob/living/user as mob)
+/obj/item/device/healthanalyzer/attack(mob/living/M, mob/living/user)
+ scan_mob(M, user)
+
+/obj/item/device/healthanalyzer/proc/scan_mob(mob/living/M, mob/living/user)
if ((CLUMSY in user.mutations) && prob(50))
user << text("You try to analyze the floor's vitals!")
for(var/mob/O in viewers(M, null))
@@ -168,8 +176,7 @@ REAGENT SCANNER
else
user.show_message("Blood Level Normal: [blood_percent]% [blood_volume]cl. Type: [blood_type]")
user.show_message("Subject's pulse: [H.get_pulse(GETPULSE_TOOL)] bpm.")
- src.add_fingerprint(user)
- return
+
/obj/item/device/healthanalyzer/verb/toggle_mode()
set name = "Switch Verbosity"
diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm
index 571b0462df..b9b854f76a 100644
--- a/code/game/objects/items/devices/uplink.dm
+++ b/code/game/objects/items/devices/uplink.dm
@@ -6,6 +6,7 @@
var/list/nanoui_items // List of items for NanoUI use
var/nanoui_menu = 0 // The current menu we are in
var/list/nanoui_data = new // Additional data for NanoUI use
+ var/faction = "" //Antag faction holder.
var/list/purchase_log = new
var/datum/mind/uplink_owner = null
@@ -96,6 +97,9 @@
var/title = "Remote Uplink"
var/data[0]
uses = user.mind.tcrystals
+ if(ishuman(user))
+ var/mob/living/carbon/human/H = user
+ faction = H.antag_faction
data["welcome"] = welcome
data["crystals"] = uses
@@ -188,7 +192,10 @@
nanoui_data["exploit"]["faction"] = html_encode(L.fields["faction"])
nanoui_data["exploit"]["religion"] = html_encode(L.fields["religion"])
nanoui_data["exploit"]["fingerprint"] = html_encode(L.fields["fingerprint"])
-
+ if(L.fields["antagvis"] == ANTAG_KNOWN || (faction == L.fields["antagfac"] && (L.fields["antagvis"] == ANTAG_SHARED)))
+ nanoui_data["exploit"]["antagfaction"] = html_encode(L.fields["antagfac"])
+ else
+ nanoui_data["exploit"]["antagfaction"] = html_encode("None")
nanoui_data["exploit_exists"] = 1
break
diff --git a/code/game/objects/items/stacks/medical.dm b/code/game/objects/items/stacks/medical.dm
index 2ddbd4e330..1298206b3e 100644
--- a/code/game/objects/items/stacks/medical.dm
+++ b/code/game/objects/items/stacks/medical.dm
@@ -73,50 +73,47 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
- if(affecting.open == 0)
- if(affecting.is_bandaged())
- user << "The wounds on [M]'s [affecting.name] have already been bandaged."
- return 1
- else
- user.visible_message("\The [user] starts treating [M]'s [affecting.name].", \
- "You start treating [M]'s [affecting.name]." )
- var/used = 0
- for (var/datum/wound/W in affecting.wounds)
- if (W.internal)
- continue
- if(W.bandaged)
- continue
- if(used == amount)
- break
- if(!do_mob(user, M, W.damage/5))
- user << "You must stand still to bandage wounds."
- break
+ if(affecting.open)
+ user << "The [affecting.name] is cut open, you'll need more than a bandage!"
+ return
- if (W.current_stage <= W.max_bleeding_stage)
- user.visible_message("\The [user] bandages \a [W.desc] on [M]'s [affecting.name].", \
- "You bandage \a [W.desc] on [M]'s [affecting.name]." )
- //H.add_side_effect("Itch")
- else if (W.damage_type == BRUISE)
- user.visible_message("\The [user] places a bruise patch over \a [W.desc] on [M]'s [affecting.name].", \
- "You place a bruise patch over \a [W.desc] on [M]'s [affecting.name]." )
- else
- user.visible_message("\The [user] places a bandaid over \a [W.desc] on [M]'s [affecting.name].", \
- "You place a bandaid over \a [W.desc] on [M]'s [affecting.name]." )
- W.bandage()
- used++
- affecting.update_damages()
- if(used == amount)
- if(affecting.is_bandaged())
- user << "\The [src] is used up."
- else
- user << "\The [src] is used up, but there are more wounds to treat on \the [affecting.name]."
- use(used)
+ if(affecting.is_bandaged())
+ user << "The wounds on [M]'s [affecting.name] have already been bandaged."
+ return 1
else
- if (can_operate(H)) //Checks if mob is lying down on table for surgery
- if (do_surgery(H,user,src))
- return
- else
- user << "The [affecting.name] is cut open, you'll need more than a bandage!"
+ user.visible_message("\The [user] starts treating [M]'s [affecting.name].", \
+ "You start treating [M]'s [affecting.name]." )
+ var/used = 0
+ for (var/datum/wound/W in affecting.wounds)
+ if (W.internal)
+ continue
+ if(W.bandaged)
+ continue
+ if(used == amount)
+ break
+ if(!do_mob(user, M, W.damage/5))
+ user << "You must stand still to bandage wounds."
+ break
+
+ if (W.current_stage <= W.max_bleeding_stage)
+ user.visible_message("\The [user] bandages \a [W.desc] on [M]'s [affecting.name].", \
+ "You bandage \a [W.desc] on [M]'s [affecting.name]." )
+ //H.add_side_effect("Itch")
+ else if (W.damage_type == BRUISE)
+ user.visible_message("\The [user] places a bruise patch over \a [W.desc] on [M]'s [affecting.name].", \
+ "You place a bruise patch over \a [W.desc] on [M]'s [affecting.name]." )
+ else
+ user.visible_message("\The [user] places a bandaid over \a [W.desc] on [M]'s [affecting.name].", \
+ "You place a bandaid over \a [W.desc] on [M]'s [affecting.name]." )
+ W.bandage()
+ used++
+ affecting.update_damages()
+ if(used == amount)
+ if(affecting.is_bandaged())
+ user << "\The [src] is used up."
+ else
+ user << "\The [src] is used up, but there are more wounds to treat on \the [affecting.name]."
+ use(used)
/obj/item/stack/medical/ointment
name = "ointment"
@@ -135,26 +132,23 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
- if(affecting.open == 0)
- if(affecting.is_salved())
- user << "The wounds on [M]'s [affecting.name] have already been salved."
- return 1
- else
- user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \
- "You start salving the wounds on [M]'s [affecting.name]." )
- if(!do_mob(user, M, 10))
- user << "You must stand still to salve wounds."
- return 1
- user.visible_message("[user] salved wounds on [M]'s [affecting.name].", \
- "You salved wounds on [M]'s [affecting.name]." )
- use(1)
- affecting.salve()
+ if(affecting.open)
+ user << "The [affecting.name] is cut open, you'll need more than a bandage!"
+ return
+
+ if(affecting.is_salved())
+ user << "The wounds on [M]'s [affecting.name] have already been salved."
+ return 1
else
- if (can_operate(H)) //Checks if mob is lying down on table for surgery
- if (do_surgery(H,user,src))
- return
- else
- user << "The [affecting.name] is cut open, you'll need more than a bandage!"
+ user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \
+ "You start salving the wounds on [M]'s [affecting.name]." )
+ if(!do_mob(user, M, 10))
+ user << "You must stand still to salve wounds."
+ return 1
+ user.visible_message("[user] salved wounds on [M]'s [affecting.name].", \
+ "You salved wounds on [M]'s [affecting.name]." )
+ use(1)
+ affecting.salve()
/obj/item/stack/medical/advanced/bruise_pack
name = "advanced trauma kit"
@@ -172,50 +166,47 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
- if(affecting.open == 0)
- if(affecting.is_bandaged() && affecting.is_disinfected())
- user << "The wounds on [M]'s [affecting.name] have already been treated."
- return 1
- else
- user.visible_message("\The [user] starts treating [M]'s [affecting.name].", \
- "You start treating [M]'s [affecting.name]." )
- var/used = 0
- for (var/datum/wound/W in affecting.wounds)
- if (W.internal)
- continue
- if (W.bandaged && W.disinfected)
- continue
- if(used == amount)
- break
- if(!do_mob(user, M, W.damage/5))
- user << "You must stand still to bandage wounds."
- break
- if (W.current_stage <= W.max_bleeding_stage)
- user.visible_message("\The [user] cleans \a [W.desc] on [M]'s [affecting.name] and seals the edges with bioglue.", \
- "You clean and seal \a [W.desc] on [M]'s [affecting.name]." )
- else if (W.damage_type == BRUISE)
- user.visible_message("\The [user] places a medical patch over \a [W.desc] on [M]'s [affecting.name].", \
- "You place a medical patch over \a [W.desc] on [M]'s [affecting.name]." )
- else
- user.visible_message("\The [user] smears some bioglue over \a [W.desc] on [M]'s [affecting.name].", \
- "You smear some bioglue over \a [W.desc] on [M]'s [affecting.name]." )
- W.bandage()
- W.disinfect()
- W.heal_damage(heal_brute)
- used++
- affecting.update_damages()
- if(used == amount)
- if(affecting.is_bandaged())
- user << "\The [src] is used up."
- else
- user << "\The [src] is used up, but there are more wounds to treat on \the [affecting.name]."
- use(used)
+ if(affecting.open)
+ user << "The [affecting.name] is cut open, you'll need more than a bandage!"
+ return
+
+ if(affecting.is_bandaged() && affecting.is_disinfected())
+ user << "The wounds on [M]'s [affecting.name] have already been treated."
+ return 1
else
- if (can_operate(H)) //Checks if mob is lying down on table for surgery
- if (do_surgery(H,user,src))
- return
- else
- user << "The [affecting.name] is cut open, you'll need more than a bandage!"
+ user.visible_message("\The [user] starts treating [M]'s [affecting.name].", \
+ "You start treating [M]'s [affecting.name]." )
+ var/used = 0
+ for (var/datum/wound/W in affecting.wounds)
+ if (W.internal)
+ continue
+ if (W.bandaged && W.disinfected)
+ continue
+ if(used == amount)
+ break
+ if(!do_mob(user, M, W.damage/5))
+ user << "You must stand still to bandage wounds."
+ break
+ if (W.current_stage <= W.max_bleeding_stage)
+ user.visible_message("\The [user] cleans \a [W.desc] on [M]'s [affecting.name] and seals the edges with bioglue.", \
+ "You clean and seal \a [W.desc] on [M]'s [affecting.name]." )
+ else if (W.damage_type == BRUISE)
+ user.visible_message("\The [user] places a medical patch over \a [W.desc] on [M]'s [affecting.name].", \
+ "You place a medical patch over \a [W.desc] on [M]'s [affecting.name]." )
+ else
+ user.visible_message("\The [user] smears some bioglue over \a [W.desc] on [M]'s [affecting.name].", \
+ "You smear some bioglue over \a [W.desc] on [M]'s [affecting.name]." )
+ W.bandage()
+ W.disinfect()
+ W.heal_damage(heal_brute)
+ used++
+ affecting.update_damages()
+ if(used == amount)
+ if(affecting.is_bandaged())
+ user << "\The [src] is used up."
+ else
+ user << "\The [src] is used up, but there are more wounds to treat on \the [affecting.name]."
+ use(used)
/obj/item/stack/medical/advanced/ointment
name = "advanced burn kit"
@@ -234,27 +225,23 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/affecting = H.get_organ(user.zone_sel.selecting)
- if(affecting.open == 0)
- if(affecting.is_salved())
- user << "The wounds on [M]'s [affecting.name] have already been salved."
- return 1
- else
- user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \
- "You start salving the wounds on [M]'s [affecting.name]." )
- if(!do_mob(user, M, 10))
- user << "You must stand still to salve wounds."
- return 1
- user.visible_message( "[user] covers wounds on [M]'s [affecting.name] with regenerative membrane.", \
- "You cover wounds on [M]'s [affecting.name] with regenerative membrane." )
- affecting.heal_damage(0,heal_burn)
- use(1)
- affecting.salve()
+ if(affecting.open)
+ user << "The [affecting.name] is cut open, you'll need more than a bandage!"
+
+ if(affecting.is_salved())
+ user << "The wounds on [M]'s [affecting.name] have already been salved."
+ return 1
else
- if (can_operate(H)) //Checks if mob is lying down on table for surgery
- if (do_surgery(H,user,src))
- return
- else
- user << "The [affecting.name] is cut open, you'll need more than a bandage!"
+ user.visible_message("\The [user] starts salving wounds on [M]'s [affecting.name].", \
+ "You start salving the wounds on [M]'s [affecting.name]." )
+ if(!do_mob(user, M, 10))
+ user << "You must stand still to salve wounds."
+ return 1
+ user.visible_message( "[user] covers wounds on [M]'s [affecting.name] with regenerative membrane.", \
+ "You cover wounds on [M]'s [affecting.name] with regenerative membrane." )
+ affecting.heal_damage(0,heal_burn)
+ use(1)
+ affecting.salve()
/obj/item/stack/medical/splint
name = "medical splints"
diff --git a/code/game/objects/items/stacks/nanopaste.dm b/code/game/objects/items/stacks/nanopaste.dm
index 1ff55adf85..da2b23e0e3 100644
--- a/code/game/objects/items/stacks/nanopaste.dm
+++ b/code/game/objects/items/stacks/nanopaste.dm
@@ -18,7 +18,7 @@
R.adjustFireLoss(-15)
R.updatehealth()
use(1)
- user.visible_message("\The [user] applied some [src] at [R]'s damaged areas.",\
+ user.visible_message("\The [user] applied some [src] on [R]'s damaged areas.",\
"You apply some [src] at [R]'s damaged areas.")
else
user << "All [R]'s systems are nominal."
@@ -27,12 +27,14 @@
var/mob/living/carbon/human/H = M
var/obj/item/organ/external/S = H.get_organ(user.zone_sel.selecting)
- if (S && (S.robotic >= ORGAN_ROBOT))
- if(S.robo_repair(15, "omni", 0, src, user))
- use(1)
- user.visible_message("\The [user] applies some nanite paste on [user != M ? "\the [M]'s" : "their"] [S.name].",\
- "You apply some nanite paste on [user == M ? "your" : "[M]'s"] [S.name].")
- else
- if (can_operate(H))
- if (do_surgery(H,user,src))
- return
+ if(S.open >= 2)
+ if (S && (S.robotic >= ORGAN_ROBOT))
+ if(!S.get_damage())
+ user << "Nothing to fix here."
+ else if(can_use(1))
+ user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
+ S.heal_damage(15, 15, robo_repair = 1)
+ H.updatehealth()
+ use(1)
+ user.visible_message("\The [user] applies some nanite paste on [user != M ? "[M]'s [S.name]" : "[S]"] with [src].",\
+ "You apply some nanite paste on [user == M ? "your" : "[M]'s"] [S.name].")
diff --git a/code/game/objects/items/stacks/stack.dm b/code/game/objects/items/stacks/stack.dm
index 83ce6d3f49..ee1cc1b078 100644
--- a/code/game/objects/items/stacks/stack.dm
+++ b/code/game/objects/items/stacks/stack.dm
@@ -298,14 +298,16 @@
/obj/item/stack/attack_hand(mob/user as mob)
if (user.get_inactive_hand() == src)
- var/obj/item/stack/F = src.split(1)
- if (F)
- user.put_in_hands(F)
- src.add_fingerprint(user)
- F.add_fingerprint(user)
- spawn(0)
- if (src && usr.machine==src)
- src.interact(usr)
+ var/N = input("How many stacks of [src] would you like to split off?", "Split stacks", 1) as num|null
+ if(N)
+ var/obj/item/stack/F = src.split(N)
+ if (F)
+ user.put_in_hands(F)
+ src.add_fingerprint(user)
+ F.add_fingerprint(user)
+ spawn(0)
+ if (src && usr.machine==src)
+ src.interact(usr)
else
..()
return
@@ -313,10 +315,7 @@
/obj/item/stack/attackby(obj/item/W as obj, mob/user as mob)
if (istype(W, /obj/item/stack))
var/obj/item/stack/S = W
- if (user.get_inactive_hand()==src)
- src.transfer_to(S, 1)
- else
- src.transfer_to(S)
+ src.transfer_to(S)
spawn(0) //give the stacks a chance to delete themselves if necessary
if (S && usr.machine==S)
diff --git a/code/game/objects/items/weapons/autopsy.dm b/code/game/objects/items/weapons/autopsy.dm
index d196bc4ea7..61c6668c33 100644
--- a/code/game/objects/items/weapons/autopsy.dm
+++ b/code/game/objects/items/weapons/autopsy.dm
@@ -162,19 +162,16 @@
if(istype(usr,/mob/living/carbon))
usr.put_in_hands(src)
-/obj/item/weapon/autopsy_scanner/attack(mob/living/carbon/human/M as mob, mob/living/carbon/user as mob)
+/obj/item/weapon/autopsy_scanner/do_surgery(mob/living/carbon/human/M, mob/living/user)
if(!istype(M))
- return
-
- if(!can_operate(M))
- return
+ return 0
if(target_name != M.name)
target_name = M.name
src.wdata = list()
src.chemtraces = list()
src.timeofdeath = null
- user << "A new patient has been registered.. Purging data for previous patient."
+ user << "A new patient has been registered. Purging data for previous patient."
src.timeofdeath = M.timeofdeath
@@ -183,10 +180,9 @@
usr << "You can't scan this body part."
return
if(!S.open)
- usr << "You have to cut the limb open first!"
+ usr << "You have to cut [S] open first!"
return
- for(var/mob/O in viewers(M))
- O.show_message("\The [user] scans the wounds on [M.name]'s [S.name] with \the [src]", 1)
+ M.visible_message("\The [user] scans the wounds on [M]'s [S.name] with [src]")
src.add_data(S)
diff --git a/code/game/objects/items/weapons/dice.dm b/code/game/objects/items/weapons/dice.dm
index 074543296f..86310d2b78 100644
--- a/code/game/objects/items/weapons/dice.dm
+++ b/code/game/objects/items/weapons/dice.dm
@@ -10,12 +10,42 @@
/obj/item/weapon/dice/New()
icon_state = "[name][rand(1,sides)]"
+/obj/item/weapon/dice/d4
+ name = "d4"
+ desc = "A dice with four sides."
+ icon_state = "d44"
+ sides = 4
+
+/obj/item/weapon/dice/d8
+ name = "d8"
+ desc = "A dice with eight sides."
+ icon_state = "d88"
+ sides = 8
+
+/obj/item/weapon/dice/d10
+ name = "d10"
+ desc = "A dice with ten sides."
+ icon_state = "d1010"
+ sides = 10
+
+/obj/item/weapon/dice/d12
+ name = "d12"
+ desc = "A dice with twelve sides."
+ icon_state = "d1212"
+ sides = 12
+
/obj/item/weapon/dice/d20
name = "d20"
desc = "A dice with twenty sides."
icon_state = "d2020"
sides = 20
+/obj/item/weapon/dice/d100
+ name = "d100"
+ desc = "A dice with ten sides. This one is for the tens digit."
+ icon_state = "d10010"
+ sides = 10
+
/obj/item/weapon/dice/attack_self(mob/user as mob)
var/result = rand(1, sides)
var/comment = ""
diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm
index 17616942c1..a38c66333c 100644
--- a/code/game/objects/items/weapons/grenades/flashbang.dm
+++ b/code/game/objects/items/weapons/grenades/flashbang.dm
@@ -40,7 +40,7 @@
//Flashing everyone
if(eye_safety < 1)
- flick("e_flash", M.flash)
+ M.flash_eyes()
M.Stun(2)
M.Weaken(10)
diff --git a/code/game/objects/items/weapons/grenades/spawnergrenade.dm b/code/game/objects/items/weapons/grenades/spawnergrenade.dm
index 05ad73489a..db85bbc6f9 100644
--- a/code/game/objects/items/weapons/grenades/spawnergrenade.dm
+++ b/code/game/objects/items/weapons/grenades/spawnergrenade.dm
@@ -18,7 +18,7 @@
playsound(T, 'sound/effects/phasein.ogg', 100, 1)
for(var/mob/living/carbon/human/M in viewers(T, null))
if(M:eyecheck() <= 0)
- flick("e_flash", M.flash)
+ M.flash_eyes()
// Spawn some hostile syndicate critters
for(var/i=1, i<=deliveryamt, i++)
diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm
index 69f14d7c2b..4bddb29a06 100644
--- a/code/game/objects/items/weapons/implants/implant.dm
+++ b/code/game/objects/items/weapons/implants/implant.dm
@@ -15,43 +15,44 @@
var/malfunction = 0
show_messages = 1
- proc/trigger(emote, source as mob)
- return
+/obj/item/weapon/implant/proc/trigger(emote, source as mob)
+ return
- proc/activate()
- return
+/obj/item/weapon/implant/proc/activate()
+ return
// What does the implant do upon injection?
// return 0 if the implant fails (ex. Revhead and loyalty implant.)
// return 1 if the implant succeeds (ex. Nonrevhead and loyalty implant.)
- proc/implanted(var/mob/source)
- return 1
+/obj/item/weapon/implant/proc/implanted(var/mob/source)
+ listening_objects |= src
+ return 1
- proc/get_data()
- return "No information available"
+/obj/item/weapon/implant/proc/get_data()
+ return "No information available"
- proc/hear(message, source as mob)
- return
+/obj/item/weapon/implant/proc/hear(message, source as mob)
+ return
- proc/islegal()
- return 0
+/obj/item/weapon/implant/proc/islegal()
+ return 0
- proc/meltdown() //breaks it down, making implant unrecongizible
- imp_in << "You feel something melting inside [part ? "your [part.name]" : "you"]!"
- if (part)
- part.take_damage(burn = 15, used_weapon = "Electronics meltdown")
- else
- var/mob/living/M = imp_in
- M.apply_damage(15,BURN)
- name = "melted implant"
- desc = "Charred circuit in melted plastic case. Wonder what that used to be..."
- icon_state = "implant_melted"
- malfunction = MALFUNCTION_PERMANENT
+/obj/item/weapon/implant/proc/meltdown() //breaks it down, making implant unrecongizible
+ imp_in << "You feel something melting inside [part ? "your [part.name]" : "you"]!"
+ if (part)
+ part.take_damage(burn = 15, used_weapon = "Electronics meltdown")
+ else
+ var/mob/living/M = imp_in
+ M.apply_damage(15,BURN)
+ name = "melted implant"
+ desc = "Charred circuit in melted plastic case. Wonder what that used to be..."
+ icon_state = "implant_melted"
+ malfunction = MALFUNCTION_PERMANENT
- Destroy()
- if(part)
- part.implants.Remove(src)
- ..()
+/obj/item/weapon/implant/Destroy()
+ if(part)
+ part.implants.Remove(src)
+ ..()
/obj/item/weapon/implant/tracking
name = "tracking implant"
@@ -59,8 +60,8 @@
var/id = 1.0
- get_data()
- var/dat = {"Implant Specifications:
+/obj/item/weapon/implant/tracking/get_data()
+ var/dat = {"Implant Specifications:
Name: Tracking Beacon
Life: 10 minutes after death of host
Important Notes: None
@@ -74,23 +75,23 @@ disintegrate into bio-safe elements.
Integrity: Gradient creates slight risk of being overcharged and frying the
circuitry. As a result neurotoxins can cause massive damage.
Implant Specifics:
"}
- return dat
+ return dat
- emp_act(severity)
- if (malfunction) //no, dawg, you can't malfunction while you are malfunctioning
- return
- malfunction = MALFUNCTION_TEMPORARY
+/obj/item/weapon/implant/tracking/emp_act(severity)
+ if (malfunction) //no, dawg, you can't malfunction while you are malfunctioning
+ return
+ malfunction = MALFUNCTION_TEMPORARY
- var/delay = 20
- switch(severity)
- if(1)
- if(prob(60))
- meltdown()
- if(2)
- delay = rand(5*60*10,15*60*10) //from 5 to 15 minutes of free time
+ var/delay = 20
+ switch(severity)
+ if(1)
+ if(prob(60))
+ meltdown()
+ if(2)
+ delay = rand(5*60*10,15*60*10) //from 5 to 15 minutes of free time
- spawn(delay)
- malfunction--
+ spawn(delay)
+ malfunction--
/obj/item/weapon/implant/dexplosive
@@ -98,8 +99,8 @@ Implant Specifics:
"}
desc = "And boom goes the weasel."
icon_state = "implant_evil"
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/dexplosive/get_data()
+ var/dat = {"
Implant Specifications:
Name: Robust Corp RX-78 Employee Management Implant
Life: Activates upon death.
@@ -109,23 +110,23 @@ Implant Specifics:
"}
Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
Special Features: Explodes
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
- return dat
+ return dat
- trigger(emote, source as mob)
- if(emote == "deathgasp")
- src.activate("death")
- return
+/obj/item/weapon/implant/dexplosive/trigger(emote, source as mob)
+ if(emote == "deathgasp")
+ src.activate("death")
+ return
- activate(var/cause)
- if((!cause) || (!src.imp_in)) return 0
- explosion(src, -1, 0, 2, 3, 0)//This might be a bit much, dono will have to see.
- if(src.imp_in)
- src.imp_in.gib()
+/obj/item/weapon/implant/dexplosive/activate(var/cause)
+ if((!cause) || (!src.imp_in)) return 0
+ explosion(src, -1, 0, 2, 3, 0)//This might be a bit much, dono will have to see.
+ if(src.imp_in)
+ src.imp_in.gib()
- islegal()
- return 0
+/obj/item/weapon/implant/dexplosive/islegal()
+ return 0
//BS12 Explosive
/obj/item/weapon/implant/explosive
@@ -135,8 +136,8 @@ Implant Specifics:
"}
var/phrase = "supercalifragilisticexpialidocious"
icon_state = "implant_evil"
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/explosive/get_data()
+ var/dat = {"
Implant Specifications:
Name: Robust Corp RX-78 Intimidation Class Implant
Life: Activates upon codephrase.
@@ -146,120 +147,121 @@ Implant Specifics:
"}
Function: Contains a compact, electrically detonated explosive that detonates upon receiving a specially encoded signal or upon host death.
Special Features: Explodes
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
- return dat
+ return dat
- hear_talk(mob/M as mob, msg)
- hear(msg)
+/obj/item/weapon/implant/explosive/hear_talk(mob/M as mob, msg)
+ hear(msg)
+ return
+
+/obj/item/weapon/implant/explosive/hear(var/msg)
+ var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
+ msg = replace_characters(msg, replacechars)
+ if(findtext(msg,phrase))
+ activate()
+ qdel(src)
+
+/obj/item/weapon/implant/explosive/activate()
+ if (malfunction == MALFUNCTION_PERMANENT)
return
- hear(var/msg)
- var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
- msg = replace_characters(msg, replacechars)
- if(findtext(msg,phrase))
- activate()
- qdel(src)
+ var/need_gib = null
+ if(istype(imp_in, /mob/))
+ var/mob/T = imp_in
+ message_admins("Explosive implant triggered in [T] ([T.key]). (JMP) ")
+ log_game("Explosive implant triggered in [T] ([T.key]).")
+ need_gib = 1
- activate()
- if (malfunction == MALFUNCTION_PERMANENT)
- return
-
- var/need_gib = null
- if(istype(imp_in, /mob/))
- var/mob/T = imp_in
- message_admins("Explosive implant triggered in [T] ([T.key]). (JMP) ")
- log_game("Explosive implant triggered in [T] ([T.key]).")
- need_gib = 1
-
- if(ishuman(imp_in))
- if (elevel == "Localized Limb")
- if(part) //For some reason, small_boom() didn't work. So have this bit of working copypaste.
- imp_in.visible_message("Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")
- playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
- sleep(25)
- if (istype(part,/obj/item/organ/external/chest) || \
- istype(part,/obj/item/organ/external/groin) || \
- istype(part,/obj/item/organ/external/head))
- part.createwound(BRUISE, 60) //mangle them instead
- explosion(get_turf(imp_in), -1, -1, 2, 3)
- qdel(src)
- else
- explosion(get_turf(imp_in), -1, -1, 2, 3)
- part.droplimb(0,DROPLIMB_BLUNT)
- qdel(src)
- if (elevel == "Destroy Body")
- explosion(get_turf(T), -1, 0, 1, 6)
- T.gib()
- if (elevel == "Full Explosion")
- explosion(get_turf(T), 0, 1, 3, 6)
- T.gib()
-
- else
- explosion(get_turf(imp_in), 0, 1, 3, 6)
-
- if(need_gib)
- imp_in.gib()
-
- var/turf/t = get_turf(imp_in)
-
- if(t)
- t.hotspot_expose(3500,125)
-
- implanted(mob/source as mob)
- elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion")
- phrase = input("Choose activation phrase:") as text
- var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
- phrase = replace_characters(phrase, replacechars)
- usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0)
- usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate."
- return 1
-
- emp_act(severity)
- if (malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
- switch (severity)
- if (2.0) //Weak EMP will make implant tear limbs off.
- if (prob(50))
- small_boom()
- if (1.0) //strong EMP will melt implant either making it go off, or disarming it
- if (prob(70))
- if (prob(50))
- small_boom()
- else
- if (prob(50))
- activate() //50% chance of bye bye
- else
- meltdown() //50% chance of implant disarming
- spawn (20)
- malfunction--
-
- islegal()
- return 0
-
- proc/small_boom()
- if (ishuman(imp_in) && part)
- imp_in.visible_message("Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")
- playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
- spawn(25)
- if (ishuman(imp_in) && part)
- //No tearing off these parts since it's pretty much killing
- //and you can't replace groins
+ if(ishuman(imp_in))
+ if (elevel == "Localized Limb")
+ if(part) //For some reason, small_boom() didn't work. So have this bit of working copypaste.
+ imp_in.visible_message("Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")
+ playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
+ sleep(25)
if (istype(part,/obj/item/organ/external/chest) || \
istype(part,/obj/item/organ/external/groin) || \
istype(part,/obj/item/organ/external/head))
part.createwound(BRUISE, 60) //mangle them instead
+ explosion(get_turf(imp_in), -1, -1, 2, 3)
+ qdel(src)
else
+ explosion(get_turf(imp_in), -1, -1, 2, 3)
part.droplimb(0,DROPLIMB_BLUNT)
- explosion(get_turf(imp_in), -1, -1, 2, 3)
- qdel(src)
+ qdel(src)
+ if (elevel == "Destroy Body")
+ explosion(get_turf(T), -1, 0, 1, 6)
+ T.gib()
+ if (elevel == "Full Explosion")
+ explosion(get_turf(T), 0, 1, 3, 6)
+ T.gib()
+
+ else
+ explosion(get_turf(imp_in), 0, 1, 3, 6)
+
+ if(need_gib)
+ imp_in.gib()
+
+ var/turf/t = get_turf(imp_in)
+
+ if(t)
+ t.hotspot_expose(3500,125)
+
+/obj/item/weapon/implant/explosive/implanted(mob/source as mob)
+ elevel = alert("What sort of explosion would you prefer?", "Implant Intent", "Localized Limb", "Destroy Body", "Full Explosion")
+ phrase = input("Choose activation phrase:") as text
+ var/list/replacechars = list("'" = "","\"" = "",">" = "","<" = "","(" = "",")" = "")
+ phrase = replace_characters(phrase, replacechars)
+ usr.mind.store_memory("Explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate.", 0, 0)
+ usr << "The implanted explosive implant in [source] can be activated by saying something containing the phrase ''[src.phrase]'', say [src.phrase] to attempt to activate."
+ listening_objects |= src
+ return 1
+
+/obj/item/weapon/implant/explosive/emp_act(severity)
+ if (malfunction)
+ return
+ malfunction = MALFUNCTION_TEMPORARY
+ switch (severity)
+ if (2.0) //Weak EMP will make implant tear limbs off.
+ if (prob(50))
+ small_boom()
+ if (1.0) //strong EMP will melt implant either making it go off, or disarming it
+ if (prob(70))
+ if (prob(50))
+ small_boom()
+ else
+ if (prob(50))
+ activate() //50% chance of bye bye
+ else
+ meltdown() //50% chance of implant disarming
+ spawn (20)
+ malfunction--
+
+/obj/item/weapon/implant/explosive/islegal()
+ return 0
+
+/obj/item/weapon/implant/explosive/proc/small_boom()
+ if (ishuman(imp_in) && part)
+ imp_in.visible_message("Something beeps inside [imp_in][part ? "'s [part.name]" : ""]!")
+ playsound(loc, 'sound/items/countdown.ogg', 75, 1, -3)
+ spawn(25)
+ if (ishuman(imp_in) && part)
+ //No tearing off these parts since it's pretty much killing
+ //and you can't replace groins
+ if (istype(part,/obj/item/organ/external/chest) || \
+ istype(part,/obj/item/organ/external/groin) || \
+ istype(part,/obj/item/organ/external/head))
+ part.createwound(BRUISE, 60) //mangle them instead
+ else
+ part.droplimb(0,DROPLIMB_BLUNT)
+ explosion(get_turf(imp_in), -1, -1, 2, 3)
+ qdel(src)
/obj/item/weapon/implant/chem
name = "chemical implant"
desc = "Injects things."
allow_reagents = 1
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/chem/get_data()
+ var/dat = {"
Implant Specifications:
Name: Robust Corp MJ-420 Prisoner Management Implant
Life: Deactivates upon death but remains within the body.
@@ -274,55 +276,55 @@ the implant releases the chemicals directly into the blood stream.
Can only be loaded while still in its original case.
Integrity: Implant will last so long as the subject is alive. However, if the subject suffers from malnutrition,
the implant may become unstable and either pre-maturely inject the subject or simply break."}
- return dat
+ return dat
- New()
- ..()
- var/datum/reagents/R = new/datum/reagents(50)
- reagents = R
- R.my_atom = src
+/obj/item/weapon/implant/chem/New()
+ ..()
+ var/datum/reagents/R = new/datum/reagents(50)
+ reagents = R
+ R.my_atom = src
- trigger(emote, source as mob)
- if(emote == "deathgasp")
- src.activate(src.reagents.total_volume)
+/obj/item/weapon/implant/chem/trigger(emote, source as mob)
+ if(emote == "deathgasp")
+ src.activate(src.reagents.total_volume)
+ return
+
+
+/obj/item/weapon/implant/chem/activate(var/cause)
+ if((!cause) || (!src.imp_in)) return 0
+ var/mob/living/carbon/R = src.imp_in
+ src.reagents.trans_to_mob(R, cause, CHEM_BLOOD)
+ R << "You hear a faint *beep*."
+ if(!src.reagents.total_volume)
+ R << "You hear a faint click from your chest."
+ spawn(0)
+ qdel(src)
+ return
+
+/obj/item/weapon/implant/chem/emp_act(severity)
+ if (malfunction)
return
+ malfunction = MALFUNCTION_TEMPORARY
+ switch(severity)
+ if(1)
+ if(prob(60))
+ activate(20)
+ if(2)
+ if(prob(30))
+ activate(5)
- activate(var/cause)
- if((!cause) || (!src.imp_in)) return 0
- var/mob/living/carbon/R = src.imp_in
- src.reagents.trans_to_mob(R, cause, CHEM_BLOOD)
- R << "You hear a faint *beep*."
- if(!src.reagents.total_volume)
- R << "You hear a faint click from your chest."
- spawn(0)
- qdel(src)
- return
-
- emp_act(severity)
- if (malfunction)
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- switch(severity)
- if(1)
- if(prob(60))
- activate(20)
- if(2)
- if(prob(30))
- activate(5)
-
- spawn(20)
- malfunction--
+ spawn(20)
+ malfunction--
/obj/item/weapon/implant/loyalty
name = "loyalty implant"
desc = "Makes you loyal or such."
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/loyalty/get_data()
+ var/dat = {"
Implant Specifications:
Name: [company_name] Employee Management Implant
Life: Ten years.
@@ -332,20 +334,20 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Contains a small pod of nanobots that manipulate the host's mental functions.
Special Features: Will prevent and cure most forms of brainwashing.
Integrity: Implant will last so long as the nanobots are inside the bloodstream."}
- return dat
+ return dat
- implanted(mob/M)
- if(!istype(M, /mob/living/carbon/human)) return 0
- var/mob/living/carbon/human/H = M
- var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
- if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE))
- H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of [company_name] try to invade your mind!")
- return 0
- else
- clear_antag_roles(H.mind, 1)
- H << "You feel a surge of loyalty towards [company_name]."
- return 1
+/obj/item/weapon/implant/loyalty/implanted(mob/M)
+ if(!istype(M, /mob/living/carbon/human)) return 0
+ var/mob/living/carbon/human/H = M
+ var/datum/antagonist/antag_data = get_antag_data(H.mind.special_role)
+ if(antag_data && (antag_data.flags & ANTAG_IMPLANT_IMMUNE))
+ H.visible_message("[H] seems to resist the implant!", "You feel the corporate tendrils of [company_name] try to invade your mind!")
+ return 0
+ else
+ clear_antag_roles(H.mind, 1)
+ H << "You feel a surge of loyalty towards [company_name]."
+ return 1
/obj/item/weapon/implant/adrenalin
@@ -353,8 +355,8 @@ the implant may become unstable and either pre-maturely inject the subject or si
desc = "Removes all stuns and knockdowns."
var/uses
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/adrenalin/get_data()
+ var/dat = {"
Implant Specifications:
Name: Cybersun Industries Adrenalin Implant
Life: Five days.
@@ -364,25 +366,26 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Contains nanobots to stimulate body to mass-produce Adrenalin.
Special Features: Will prevent and cure most forms of brainwashing.
Integrity: Implant can only be used three times before the nanobots are depleted."}
- return dat
+ return dat
- trigger(emote, mob/source as mob)
- if (src.uses < 1) return 0
- if (emote == "pale")
- src.uses--
- source << "You feel a sudden surge of energy!"
- source.SetStunned(0)
- source.SetWeakened(0)
- source.SetParalysis(0)
+/obj/item/weapon/implant/adrenalin/trigger(emote, mob/source as mob)
+ if (src.uses < 1) return 0
+ if (emote == "pale")
+ src.uses--
+ source << "You feel a sudden surge of energy!"
+ source.SetStunned(0)
+ source.SetWeakened(0)
+ source.SetParalysis(0)
- return
+ return
- implanted(mob/source)
- source.mind.store_memory("A implant can be activated by using the pale emote, say *pale to attempt to activate.", 0, 0)
- source << "The implanted freedom implant can be activated by using the pale emote, say *pale to attempt to activate."
- return 1
+/obj/item/weapon/implant/adrenalin/implanted(mob/source)
+ source.mind.store_memory("A implant can be activated by using the pale emote, say *pale to attempt to activate.", 0, 0)
+ source << "The implanted freedom implant can be activated by using the pale emote, say *pale to attempt to activate."
+ listening_objects |= src
+ return 1
/obj/item/weapon/implant/death_alarm
@@ -390,8 +393,8 @@ the implant may become unstable and either pre-maturely inject the subject or si
desc = "An alarm which monitors host vital signs and transmits a radio message upon death."
var/mobname = "Will Robinson"
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/death_alarm/get_data()
+ var/dat = {"
Implant Specifications:
Name: [company_name] \"Profit Margin\" Class Employee Lifesign Sensor
Life: Activates upon death.
@@ -401,65 +404,65 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
Special Features: Alerts crew to crewmember death.
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
- return dat
+ return dat
- process()
- if (!implanted) return
- var/mob/M = imp_in
+/obj/item/weapon/implant/death_alarm/process()
+ if (!implanted) return
+ var/mob/M = imp_in
- if(isnull(M)) // If the mob got gibbed
- activate()
- else if(M.stat == 2)
- activate("death")
+ if(isnull(M)) // If the mob got gibbed
+ activate()
+ else if(M.stat == 2)
+ activate("death")
- activate(var/cause)
- var/mob/M = imp_in
- var/area/t = get_area(M)
- switch (cause)
- if("death")
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
- if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) )
- //give the syndies a bit of stealth
- a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm", "Security")
- a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm", "Medical")
- else
- a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm", "Security")
- a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm", "Medical")
- qdel(a)
- processing_objects.Remove(src)
- if ("emp")
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
- var/name = prob(50) ? t.name : pick(teleportlocs)
- a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm", "Security")
- a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm", "Medical")
- qdel(a)
+/obj/item/weapon/implant/death_alarm/activate(var/cause)
+ var/mob/M = imp_in
+ var/area/t = get_area(M)
+ switch (cause)
+ if("death")
+ var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
+ if(istype(t, /area/syndicate_station) || istype(t, /area/syndicate_mothership) || istype(t, /area/shuttle/syndicate_elite) )
+ //give the syndies a bit of stealth
+ a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm", "Security")
+ a.autosay("[mobname] has died in Space!", "[mobname]'s Death Alarm", "Medical")
else
- var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
- a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm", "Security")
- a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm", "Medical")
- qdel(a)
- processing_objects.Remove(src)
-
- emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
- if (malfunction) //so I'm just going to add a meltdown chance here
- return
- malfunction = MALFUNCTION_TEMPORARY
-
- activate("emp") //let's shout that this dude is dead
- if(severity == 1)
- if(prob(40)) //small chance of obvious meltdown
- meltdown()
- else if (prob(60)) //but more likely it will just quietly die
- malfunction = MALFUNCTION_PERMANENT
+ a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm", "Security")
+ a.autosay("[mobname] has died in [t.name]!", "[mobname]'s Death Alarm", "Medical")
+ qdel(a)
+ processing_objects.Remove(src)
+ if ("emp")
+ var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
+ var/name = prob(50) ? t.name : pick(teleportlocs)
+ a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm", "Security")
+ a.autosay("[mobname] has died in [name]!", "[mobname]'s Death Alarm", "Medical")
+ qdel(a)
+ else
+ var/obj/item/device/radio/headset/a = new /obj/item/device/radio/headset/heads/captain(null)
+ a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm", "Security")
+ a.autosay("[mobname] has died-zzzzt in-in-in...", "[mobname]'s Death Alarm", "Medical")
+ qdel(a)
processing_objects.Remove(src)
- spawn(20)
- malfunction--
+/obj/item/weapon/implant/death_alarm/emp_act(severity) //for some reason alarms stop going off in case they are emp'd, even without this
+ if (malfunction) //so I'm just going to add a meltdown chance here
+ return
+ malfunction = MALFUNCTION_TEMPORARY
- implanted(mob/source as mob)
- mobname = source.real_name
- processing_objects.Add(src)
- return 1
+ activate("emp") //let's shout that this dude is dead
+ if(severity == 1)
+ if(prob(40)) //small chance of obvious meltdown
+ meltdown()
+ else if (prob(60)) //but more likely it will just quietly die
+ malfunction = MALFUNCTION_PERMANENT
+ processing_objects.Remove(src)
+
+ spawn(20)
+ malfunction--
+
+/obj/item/weapon/implant/death_alarm/implanted(mob/source as mob)
+ mobname = source.real_name
+ processing_objects.Add(src)
+ return 1
/obj/item/weapon/implant/compressed
name = "compressed matter implant"
@@ -468,8 +471,8 @@ the implant may become unstable and either pre-maturely inject the subject or si
var/activation_emote = "sigh"
var/obj/item/scanned = null
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/compressed/get_data()
+ var/dat = {"
Implant Specifications:
Name: [company_name] \"Profit Margin\" Class Employee Lifesign Sensor
Life: Activates upon death.
@@ -479,30 +482,31 @@ the implant may become unstable and either pre-maturely inject the subject or si
Function: Contains a compact radio signaler that triggers when the host's lifesigns cease.
Special Features: Alerts crew to crewmember death.
Integrity: Implant will occasionally be degraded by the body's immune system and thus will occasionally malfunction."}
- return dat
+ return dat
- trigger(emote, mob/source as mob)
- if (src.scanned == null)
- return 0
-
- if (emote == src.activation_emote)
- source << "The air glows as \the [src.scanned.name] uncompresses."
- activate()
-
- activate()
- var/turf/t = get_turf(src)
- if (imp_in)
- imp_in.put_in_hands(scanned)
- else
- scanned.loc = t
- qdel(src)
-
- implanted(mob/source as mob)
- src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
- if (source.mind)
- source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
- source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
- return 1
-
- islegal()
+/obj/item/weapon/implant/compressed/trigger(emote, mob/source as mob)
+ if (src.scanned == null)
return 0
+
+ if (emote == src.activation_emote)
+ source << "The air glows as \the [src.scanned.name] uncompresses."
+ activate()
+
+/obj/item/weapon/implant/compressed/activate()
+ var/turf/t = get_turf(src)
+ if (imp_in)
+ imp_in.put_in_hands(scanned)
+ else
+ scanned.loc = t
+ qdel(src)
+
+/obj/item/weapon/implant/compressed/implanted(mob/source as mob)
+ src.activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
+ if (source.mind)
+ source.mind.store_memory("Compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
+ source << "The implanted compressed matter implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
+ listening_objects |= src
+ return 1
+
+/obj/item/weapon/implant/compressed/islegal()
+ return 0
diff --git a/code/game/objects/items/weapons/implants/implantfreedom.dm b/code/game/objects/items/weapons/implants/implantfreedom.dm
index 5131961060..3913ebf1b2 100644
--- a/code/game/objects/items/weapons/implants/implantfreedom.dm
+++ b/code/game/objects/items/weapons/implants/implantfreedom.dm
@@ -8,53 +8,54 @@
var/uses = 1.0
- New()
- src.activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
- src.uses = rand(1, 5)
- ..()
- return
+/obj/item/weapon/implant/freedom/New()
+ src.activation_emote = pick("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
+ src.uses = rand(1, 5)
+ ..()
+ return
- trigger(emote, mob/living/carbon/source as mob)
- if (src.uses < 1) return 0
- if (emote == src.activation_emote)
- src.uses--
- source << "You feel a faint click."
- if (source.handcuffed)
- var/obj/item/weapon/W = source.handcuffed
- source.handcuffed = null
- if(source.buckled && source.buckled.buckle_require_restraints)
- source.buckled.unbuckle_mob()
- source.update_inv_handcuffed()
- if (source.client)
- source.client.screen -= W
+/obj/item/weapon/implant/freedom/trigger(emote, mob/living/carbon/source as mob)
+ if (src.uses < 1) return 0
+ if (emote == src.activation_emote)
+ src.uses--
+ source << "You feel a faint click."
+ if (source.handcuffed)
+ var/obj/item/weapon/W = source.handcuffed
+ source.handcuffed = null
+ if(source.buckled && source.buckled.buckle_require_restraints)
+ source.buckled.unbuckle_mob()
+ source.update_inv_handcuffed()
+ if (source.client)
+ source.client.screen -= W
+ if (W)
+ W.loc = source.loc
+ dropped(source)
if (W)
- W.loc = source.loc
- dropped(source)
- if (W)
- W.layer = initial(W.layer)
- if (source.legcuffed)
- var/obj/item/weapon/W = source.legcuffed
- source.legcuffed = null
- source.update_inv_legcuffed()
- if (source.client)
- source.client.screen -= W
+ W.layer = initial(W.layer)
+ if (source.legcuffed)
+ var/obj/item/weapon/W = source.legcuffed
+ source.legcuffed = null
+ source.update_inv_legcuffed()
+ if (source.client)
+ source.client.screen -= W
+ if (W)
+ W.loc = source.loc
+ dropped(source)
if (W)
- W.loc = source.loc
- dropped(source)
- if (W)
- W.layer = initial(W.layer)
- return
+ W.layer = initial(W.layer)
+ return
- implanted(mob/living/carbon/source)
- source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
- source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
- return 1
+/obj/item/weapon/implant/freedom/implanted(mob/living/carbon/source)
+ source.mind.store_memory("Freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
+ source << "The implanted freedom implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
+ listening_objects |= src
+ return 1
- get_data()
- var/dat = {"
+/obj/item/weapon/implant/freedom/get_data()
+ var/dat = {"
Implant Specifications:
Name: Freedom Beacon
Life: optimum 5 uses
@@ -68,4 +69,4 @@ mechanisms
Integrity: The battery is extremely weak and commonly after injection its
life can drive down to only 1 use.
No Implant Specifics"}
- return dat
+ return dat
diff --git a/code/game/objects/items/weapons/implants/implantuplink.dm b/code/game/objects/items/weapons/implants/implantuplink.dm
index f38daa4085..785fc64f75 100644
--- a/code/game/objects/items/weapons/implants/implantuplink.dm
+++ b/code/game/objects/items/weapons/implants/implantuplink.dm
@@ -15,6 +15,7 @@
activation_emote = input("Choose activation emote:") in list("blink", "blink_r", "eyebrow", "chuckle", "twitch_s", "frown", "nod", "blush", "giggle", "grin", "groan", "shrug", "smile", "pale", "sniff", "whimper", "wink")
source.mind.store_memory("Uplink implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate.", 0, 0)
source << "The implanted uplink implant can be activated by using the [src.activation_emote] emote, say *[src.activation_emote] to attempt to activate."
+ listening_objects |= src
return 1
diff --git a/code/game/objects/items/weapons/storage/misc.dm b/code/game/objects/items/weapons/storage/misc.dm
index cf1af1ea79..4bd34c52c7 100644
--- a/code/game/objects/items/weapons/storage/misc.dm
+++ b/code/game/objects/items/weapons/storage/misc.dm
@@ -1,11 +1,29 @@
-/obj/item/weapon/storage/pill_bottle/dice
- name = "pack of dice"
- desc = "It's a small container with dice inside."
+/obj/item/weapon/storage/pill_bottle/dice //7d6
+ name = "bag of dice"
+ desc = "It's a small bag with dice inside."
+ icon = 'icons/obj/dice.dmi'
+ icon_state = "dicebag"
- New()
- ..()
+/obj/item/weapon/storage/pill_bottle/dice/New()
+ ..()
+ for(var/i = 1 to 7)
new /obj/item/weapon/dice( src )
- new /obj/item/weapon/dice/d20( src )
+
+/obj/item/weapon/storage/pill_bottle/dice_nerd //DnD dice
+ name = "bag of gaming dice"
+ desc = "It's a small bag with gaming dice inside."
+ icon = 'icons/obj/dice.dmi'
+ icon_state = "magicdicebag"
+
+/obj/item/weapon/storage/pill_bottle/dice_nerd/New()
+ ..()
+ new /obj/item/weapon/dice/d4( src )
+ new /obj/item/weapon/dice( src )
+ new /obj/item/weapon/dice/d8( src )
+ new /obj/item/weapon/dice/d10( src )
+ new /obj/item/weapon/dice/d12( src )
+ new /obj/item/weapon/dice/d20( src )
+ new /obj/item/weapon/dice/d100( src )
/*
* Donut Box
diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm
index b7e55cddb8..5e01c43e55 100644
--- a/code/game/objects/items/weapons/stunbaton.dm
+++ b/code/game/objects/items/weapons/stunbaton.dm
@@ -122,7 +122,7 @@
var/mob/living/carbon/human/H = target
affecting = H.get_organ(hit_zone)
- if(user.a_intent == I_HURT)
+ if(user.a_intent == I_HURT || user.a_intent == I_DISARM)
. = ..()
//whacking someone causes a much poorer electrical contact than deliberately prodding them.
agony *= 0.5
diff --git a/code/game/turfs/flooring/flooring.dm b/code/game/turfs/flooring/flooring.dm
index 927facec8d..779f76fc93 100644
--- a/code/game/turfs/flooring/flooring.dm
+++ b/code/game/turfs/flooring/flooring.dm
@@ -57,6 +57,12 @@ var/list/flooring_types
build_type = null
/decl/flooring/snow
+ name = "snow"
+ desc = "A layer of many tiny bits of frozen water. It's hard to tell how deep it is."
+ icon = 'icons/turf/snow_new.dmi'
+ icon_base = "snow"
+
+/decl/flooring/snow/snow2
name = "snow"
desc = "A layer of many tiny bits of frozen water. It's hard to tell how deep it is."
icon = 'icons/turf/snow.dmi'
diff --git a/code/game/turfs/flooring/flooring_premade.dm b/code/game/turfs/flooring/flooring_premade.dm
index 86ec1b2891..55795bc5b3 100644
--- a/code/game/turfs/flooring/flooring_premade.dm
+++ b/code/game/turfs/flooring/flooring_premade.dm
@@ -45,27 +45,6 @@
icon_state = "reinforced"
initial_flooring = /decl/flooring/reinforced
-/turf/simulated/floor/snow
- name = "snow"
- icon = 'icons/turf/snow.dmi'
- icon_state = "snow"
- initial_flooring = /decl/flooring/snow
-
-/turf/simulated/floor/snow/gravsnow
- name = "snow"
- icon_state = "gravsnow"
- initial_flooring = /decl/flooring/snow/gravsnow
-
-/turf/simulated/floor/snow/plating
- name = "snowy playing"
- icon_state = "snowyplating"
- initial_flooring = /decl/flooring/snow/plating
-
-/turf/simulated/floor/snow/plating/drift
- name = "snowy plating"
- icon_state = "snowyplayingdrift"
- initial_flooring = /decl/flooring/snow/plating/drift
-
/turf/simulated/floor/reinforced/airless
oxygen = 0
nitrogen = 0
@@ -225,4 +204,57 @@
/turf/simulated/floor/beach/water/ocean
*/
/turf/simulated/floor/airless/ceiling
-/turf/simulated/floor/plating
\ No newline at end of file
+/turf/simulated/floor/plating
+
+
+//**** Here lives snow ****
+/turf/simulated/floor/snow
+ name = "snow"
+ icon = 'icons/turf/snow_new.dmi'
+ icon_state = "snow"
+ var/list/crossed_dirs = list()
+
+/turf/simulated/floor/snow/snow2
+ name = "snow"
+ icon = 'icons/turf/snow.dmi'
+ icon_state = "snow"
+ initial_flooring = /decl/flooring/snow
+
+/turf/simulated/floor/snow/gravsnow
+ name = "snow"
+ icon_state = "gravsnow"
+ initial_flooring = /decl/flooring/snow/gravsnow
+
+/turf/simulated/floor/snow/plating
+ name = "snowy playing"
+ icon_state = "snowyplating"
+ initial_flooring = /decl/flooring/snow/plating
+
+/turf/simulated/floor/snow/plating/drift
+ name = "snowy plating"
+ icon_state = "snowyplayingdrift"
+ initial_flooring = /decl/flooring/snow/plating/drift
+
+#define FOOTSTEP_SPRITE_AMT 2
+
+/turf/snow/Entered(atom/A)
+ if(ismob(A))
+ var/mdir = "[A.dir]"
+ if(crossed_dirs[mdir])
+ crossed_dirs[mdir] = min(crossed_dirs[mdir] + 1, FOOTSTEP_SPRITE_AMT)
+ else
+ crossed_dirs[mdir] = 1
+
+ update_icon()
+
+ . = ..()
+
+/turf/snow/update_icon()
+ overlays.Cut()
+ for(var/d in crossed_dirs)
+ var/amt = crossed_dirs[d]
+
+ for(var/i in 1 to amt)
+ overlays += icon(icon, "footprint[i]", text2num(d))
+
+//**** Here ends snow ****
\ No newline at end of file
diff --git a/code/game/turfs/snow/snow.dm b/code/game/turfs/snow/snow.dm
new file mode 100644
index 0000000000..b09275ca41
--- /dev/null
+++ b/code/game/turfs/snow/snow.dm
@@ -0,0 +1,51 @@
+/turf/snow
+ name = "snow"
+
+ dynamic_lighting = 0
+ icon = 'icons/turf/snow_new.dmi'
+ icon_state = "snow"
+
+ oxygen = MOLES_O2STANDARD * 1.15
+ nitrogen = MOLES_N2STANDARD * 1.15
+
+ temperature = TN60C
+ var/list/crossed_dirs = list()
+
+#define FOOTSTEP_SPRITE_AMT 2
+
+/turf/snow/Entered(atom/A)
+ if(ismob(A))
+ var/mdir = "[A.dir]"
+ if(crossed_dirs[mdir])
+ crossed_dirs[mdir] = min(crossed_dirs[mdir] + 1, FOOTSTEP_SPRITE_AMT)
+ else
+ crossed_dirs[mdir] = 1
+
+ update_icon()
+
+ . = ..()
+
+/turf/snow/update_icon()
+ overlays.Cut()
+ for(var/d in crossed_dirs)
+ var/amt = crossed_dirs[d]
+
+ for(var/i in 1 to amt)
+ overlays += icon(icon, "footprint[i]", text2num(d))
+
+/turf/snow/snow2
+ name = "snow"
+ icon = 'icons/turf/snow.dmi'
+ icon_state = "snow"
+
+/turf/snow/gravsnow
+ name = "snow"
+ icon_state = "gravsnow"
+
+/turf/snow/plating
+ name = "snowy playing"
+ icon_state = "snowyplating"
+
+/turf/snow/drift
+ name = "snowy plating"
+ icon_state = "snowyplayingdrift"
diff --git a/code/game/verbs/who.dm b/code/game/verbs/who.dm
index c8dfc8dedd..8b50dfb095 100644
--- a/code/game/verbs/who.dm
+++ b/code/game/verbs/who.dm
@@ -69,9 +69,11 @@
var/msg = ""
var/modmsg = ""
+ var/devmsg = ""
var/mentmsg = ""
var/num_mods_online = 0
var/num_admins_online = 0
+ var/num_devs_online = 0
var/num_mentors_online = 0
if(holder)
for(var/client/C in admins)
@@ -118,6 +120,23 @@
modmsg += "\n"
num_mods_online++
+ else if(R_SERVER & C.holder.rights)
+ devmsg += "\t[C] is a [C.holder.rank]"
+ if(isobserver(C.mob))
+ devmsg += " - Observing"
+ else if(istype(C.mob,/mob/new_player))
+ devmsg += " - Lobby"
+ else
+ devmsg += " - Playing"
+
+ if(C.is_afk())
+ var/seconds = C.last_activity_seconds()
+ devmsg += "(AFK - "
+ devmsg += "[round(seconds / 60)] minutes, "
+ devmsg += "[seconds % 60] seconds)"
+ devmsg += "\n"
+ num_devs_online++
+
else if(R_MENTOR & C.holder.rights)
mentmsg += "\t[C] is a [C.holder.rank]"
if(isobserver(C.mob))
@@ -144,6 +163,9 @@
else if (R_MOD & C.holder.rights)
modmsg += "\t[C] is a [C.holder.rank]\n"
num_mods_online++
+ else if (R_SERVER & C.holder.rights)
+ devmsg += "\t[C] is a [C.holder.rank]\n"
+ num_devs_online++
else if (R_MENTOR & C.holder.rights)
mentmsg += "\t[C] is a [C.holder.rank]\n"
num_mentors_online++
@@ -155,6 +177,9 @@
if(config.show_mods)
msg += "\n Current Moderators ([num_mods_online]):\n" + modmsg
+ if(config.show_devs)
+ msg += "\n Current Developers ([num_devs_online]):\n" + devmsg
+
if(config.show_mentors)
msg += "\n Current Mentors ([num_mentors_online]):\n" + mentmsg
diff --git a/code/hub.dm b/code/hub.dm
index 6c38b00143..767ff8510f 100644
--- a/code/hub.dm
+++ b/code/hub.dm
@@ -1,8 +1,10 @@
/world
hub = "Exadv1.spacestation13"
- hub_password = "SORRYNOPASSWORD"
+ hub_password = "kMZy3U5jJHSiBQjr"
+ //hub_password = "SORRYNOPASSWORD"
name = "Space Station 13"
+
/* This is for any host that would like their server to appear on the main SS13 hub.
To use it, simply replace the password above, with the password found below, and it should work.
If not, let us know on the main tgstation IRC channel of irc.rizon.net #tgstation13 we can help you there.
diff --git a/code/modules/admin/verbs/buildmode.dm b/code/modules/admin/verbs/buildmode.dm
index 0ecc220ae2..5a211d960b 100644
--- a/code/modules/admin/verbs/buildmode.dm
+++ b/code/modules/admin/verbs/buildmode.dm
@@ -71,38 +71,61 @@
screen_loc = "NORTH,WEST+1"
Click()
switch(master.cl.buildmode)
- if(1)
- usr << "\blue ***********************************************************"
- usr << "\blue Left Mouse Button = Construct / Upgrade"
- usr << "\blue Right Mouse Button = Deconstruct / Delete / Downgrade"
- usr << "\blue Left Mouse Button + ctrl = R-Window"
- usr << "\blue Left Mouse Button + alt = Airlock"
+ if(1) // Basic Build
+ usr << "***********************************************************"
+ usr << "Left Mouse Button = Construct / Upgrade"
+ usr << "Right Mouse Button = Deconstruct / Delete / Downgrade"
+ usr << "Left Mouse Button + ctrl = R-Window"
+ usr << "Left Mouse Button + alt = Airlock"
usr << ""
- usr << "\blue Use the button in the upper left corner to"
- usr << "\blue change the direction of built objects."
- usr << "\blue ***********************************************************"
- if(2)
- usr << "\blue ***********************************************************"
- usr << "\blue Right Mouse Button on buildmode button = Set object type"
- usr << "\blue Middle Mouse Button on buildmode button= On/Off object type saying"
- usr << "\blue Middle Mouse Button on turf/obj = Capture object type"
- usr << "\blue Left Mouse Button on turf/obj = Place objects"
- usr << "\blue Right Mouse Button = Delete objects"
+ usr << "Use the button in the upper left corner to"
+ usr << "change the direction of built objects."
+ usr << "***********************************************************"
+ if(2) // Adv. Build
+ usr << "***********************************************************"
+ usr << "Right Mouse Button on buildmode button = Set object type"
+ usr << "Middle Mouse Button on buildmode button= On/Off object type saying"
+ usr << "Middle Mouse Button on turf/obj = Capture object type"
+ usr << "Left Mouse Button on turf/obj = Place objects"
+ usr << "Right Mouse Button = Delete objects"
+ usr << "Mouse Button + ctrl = Copy object type"
usr << ""
- usr << "\blue Use the button in the upper left corner to"
- usr << "\blue change the direction of built objects."
- usr << "\blue ***********************************************************"
- if(3)
- usr << "\blue ***********************************************************"
- usr << "\blue Right Mouse Button on buildmode button = Select var(type) & value"
- usr << "\blue Left Mouse Button on turf/obj/mob = Set var(type) & value"
- usr << "\blue Right Mouse Button on turf/obj/mob = Reset var's value"
- usr << "\blue ***********************************************************"
- if(4)
- usr << "\blue ***********************************************************"
- usr << "\blue Left Mouse Button on turf/obj/mob = Select"
- usr << "\blue Right Mouse Button on turf/obj/mob = Throw"
- usr << "\blue ***********************************************************"
+ usr << "Use the button in the upper left corner to"
+ usr << "change the direction of built objects."
+ usr << "***********************************************************"
+ if(3) // Edit
+ usr << "***********************************************************"
+ usr << "Right Mouse Button on buildmode button = Select var(type) & value"
+ usr << "Left Mouse Button on turf/obj/mob = Set var(type) & value"
+ usr << "Right Mouse Button on turf/obj/mob = Reset var's value"
+ usr << "***********************************************************"
+ if(4) // Throw
+ usr << "***********************************************************"
+ usr << "Left Mouse Button on turf/obj/mob = Select"
+ usr << "Right Mouse Button on turf/obj/mob = Throw"
+ usr << "***********************************************************"
+ if(5) // Room Build
+ usr << "***********************************************************"
+ usr << "Left Mouse Button on turf = Select as point A"
+ usr << "Right Mouse Button on turf = Select as point B"
+ usr << "Right Mouse Button on buildmode button = Change floor/wall type"
+ usr << "***********************************************************"
+ if(6) // Make Ladders
+ usr << "***********************************************************"
+ usr << "Left Mouse Button on turf = Set as upper ladder loc"
+ usr << "Right Mouse Button on turf = Set as lower ladder loc"
+ usr << "***********************************************************"
+ if(7) // Move Into Contents
+ usr << "***********************************************************"
+ usr << "Left Mouse Button on turf/obj/mob = Select"
+ usr << "Right Mouse Button on turf/obj/mob = Move into selection"
+ usr << "***********************************************************"
+ if(8) // Make Lights
+ usr << "***********************************************************"
+ usr << "Left Mouse Button on turf/obj/mob = Make it glow"
+ usr << "Right Mouse Button on turf/obj/mob = Reset glowing"
+ usr << "Right Mouse Button on buildmode button = Change glow properties"
+ usr << "***********************************************************"
return 1
/obj/effect/bmode/buildquit
@@ -144,62 +167,100 @@
var/objholder = /obj/structure/closet
var/objsay = 1
- Click(location, control, params)
- var/list/pa = params2list(params)
+ var/wall_holder = /turf/simulated/wall
+ var/floor_holder = /turf/simulated/floor/plating
+ var/turf/coordA = null
+ var/turf/coordB = null
- if(pa.Find("middle"))
- switch(master.cl.buildmode)
- if(2)
- objsay=!objsay
+ var/new_light_color = "#FFFFFF"
+ var/new_light_range = 3
+ var/new_light_intensity = 3
+
+/obj/effect/bmode/buildmode/Click(location, control, params)
+ var/list/pa = params2list(params)
+
+ if(pa.Find("middle"))
+ switch(master.cl.buildmode)
+ if(2)
+ objsay=!objsay
- if(pa.Find("left"))
- switch(master.cl.buildmode)
- if(1)
- master.cl.buildmode = 2
- src.icon_state = "buildmode2"
- if(2)
- master.cl.buildmode = 3
- src.icon_state = "buildmode3"
- if(3)
- master.cl.buildmode = 4
- src.icon_state = "buildmode4"
- if(4)
- master.cl.buildmode = 1
- src.icon_state = "buildmode1"
+ if(pa.Find("left"))
+ switch(master.cl.buildmode)
+ if(1)
+ master.cl.buildmode = 2
+ src.icon_state = "buildmode2"
+ if(2)
+ master.cl.buildmode = 3
+ src.icon_state = "buildmode3"
+ if(3)
+ master.cl.buildmode = 4
+ src.icon_state = "buildmode4"
+ if(4)
+ master.cl.buildmode = 5
+ src.icon_state = "buildmode5"
+ if(5)
+ master.cl.buildmode = 6
+ src.icon_state = "buildmode6"
+ if(6)
+ master.cl.buildmode = 7
+ src.icon_state = "buildmode7"
+ if(7)
+ master.cl.buildmode = 8
+ src.icon_state = "buildmode8"
+ if(8)
+ master.cl.buildmode = 1
+ src.icon_state = "buildmode1"
- else if(pa.Find("right"))
- switch(master.cl.buildmode)
- if(1)
+ else if(pa.Find("right"))
+ switch(master.cl.buildmode)
+ if(1) // Basic Build
+ return 1
+ if(2) // Adv. Build
+ objholder = get_path_from_partial_text(/obj/structure/closet)
+
+ if(3) // Edit
+ var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
+
+ master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name")
+ if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0))
return 1
- if(2)
- objholder = text2path(input(usr,"Enter typepath:" ,"Typepath","/obj/structure/closet"))
- if(!ispath(objholder))
- objholder = /obj/structure/closet
- alert("That path is not allowed.")
- else
- if(ispath(objholder,/mob) && !check_rights(R_DEBUG,0))
- objholder = /obj/structure/closet
- if(3)
- var/list/locked = list("vars", "key", "ckey", "client", "firemut", "ishulk", "telekinesis", "xray", "virus", "viruses", "cuffed", "ka", "last_eaten", "urine")
-
- master.buildmode.varholder = input(usr,"Enter variable name:" ,"Name", "name")
- if(master.buildmode.varholder in locked && !check_rights(R_DEBUG,0))
- return 1
- var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
- if(!thetype) return 1
- switch(thetype)
- if("text")
- master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text
- if("number")
- master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num
- if("mob-reference")
- master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list
- if("obj-reference")
- master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world
- if("turf-reference")
- master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world
- return 1
+ var/thetype = input(usr,"Select variable type:" ,"Type") in list("text","number","mob-reference","obj-reference","turf-reference")
+ if(!thetype) return 1
+ switch(thetype)
+ if("text")
+ master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", "value") as text
+ if("number")
+ master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value", 123) as num
+ if("mob-reference")
+ master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as mob in mob_list
+ if("obj-reference")
+ master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as obj in world
+ if("turf-reference")
+ master.buildmode.valueholder = input(usr,"Enter variable value:" ,"Value") as turf in world
+ if(5) // Room build
+ var/choice = alert("Would you like to change the floor or wall holders?","Room Builder", "Floor", "Wall")
+ switch(choice)
+ if("Floor")
+ floor_holder = get_path_from_partial_text(/turf/simulated/floor/plating)
+ if("Wall")
+ wall_holder = get_path_from_partial_text(/turf/simulated/wall)
+ if(8) // Lights
+ var/choice = alert("Change the new light range, power, or color?", "Light Maker", "Range", "Power", "Color")
+ switch(choice)
+ if("Range")
+ var/input = input("New light range.","Light Maker",3) as null|num
+ if(input)
+ new_light_range = input
+ if("Power")
+ var/input = input("New light power.","Light Maker",3) as null|num
+ if(input)
+ new_light_intensity = input
+ if("Color")
+ var/input = input("New light color.","Light Maker",3) as null|color
+ if(input)
+ new_light_color = input
+ return 1
/proc/build_click(var/mob/user, buildmode, params, var/obj/object)
var/obj/effect/bmode/buildholder/holder = null
@@ -211,7 +272,7 @@
var/list/pa = params2list(params)
switch(buildmode)
- if(1)
+ if(1) // Basic Build
if(istype(object,/turf) && pa.Find("left") && !pa.Find("alt") && !pa.Find("ctrl") )
if(istype(object,/turf/space))
var/turf/T = object
@@ -260,8 +321,8 @@
if(NORTHWEST)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
WIN.set_dir(NORTHWEST)
- if(2)
- if(pa.Find("left"))
+ if(2) // Adv. Build
+ if(pa.Find("left") && !pa.Find("ctrl"))
if(ispath(holder.buildmode.objholder,/turf))
var/turf/T = get_turf(object)
T.ChangeTurf(holder.buildmode.objholder)
@@ -269,27 +330,31 @@
var/obj/A = new holder.buildmode.objholder (get_turf(object))
A.set_dir(holder.builddir.dir)
else if(pa.Find("right"))
- if(isobj(object)) qdel(object)
+ if(isobj(object))
+ qdel(object)
+ else if(pa.Find("ctrl"))
+ holder.buildmode.objholder = object.type
+ user << "[object]([object.type]) copied to buildmode."
if(pa.Find("middle"))
holder.buildmode.objholder = text2path("[object.type]")
if(holder.buildmode.objsay) usr << "[object.type]"
- if(3)
+ if(3) // Edit
if(pa.Find("left")) //I cant believe this shit actually compiles.
if(object.vars.Find(holder.buildmode.varholder))
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
object.vars[holder.buildmode.varholder] = holder.buildmode.valueholder
else
- usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
+ user << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
if(pa.Find("right"))
if(object.vars.Find(holder.buildmode.varholder))
log_admin("[key_name(usr)] modified [object.name]'s [holder.buildmode.varholder] to [holder.buildmode.valueholder]")
object.vars[holder.buildmode.varholder] = initial(object.vars[holder.buildmode.varholder])
else
- usr << "\red [initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
+ user << "[initial(object.name)] does not have a var called '[holder.buildmode.varholder]'"
- if(4)
+ if(4) // Throw
if(pa.Find("left"))
if(istype(object, /atom/movable))
holder.throw_atom = object
@@ -297,3 +362,127 @@
if(holder.throw_atom)
holder.throw_atom.throw_at(object, 10, 1)
log_admin("[key_name(usr)] threw [holder.throw_atom] at [object]")
+ if(5) // Room build
+ if(pa.Find("left"))
+ holder.buildmode.coordA = get_turf(object)
+ user << "Defined [object] ([object.type]) as point A."
+
+ if(pa.Find("right"))
+ holder.buildmode.coordB = get_turf(object)
+ user << "Defined [object] ([object.type]) as point B."
+
+ if(holder.buildmode.coordA && holder.buildmode.coordB)
+ user << "A and B set, creating rectangle."
+ holder.buildmode.make_rectangle(
+ holder.buildmode.coordA,
+ holder.buildmode.coordB,
+ holder.buildmode.wall_holder,
+ holder.buildmode.floor_holder
+ )
+ holder.buildmode.coordA = null
+ holder.buildmode.coordB = null
+ if(6) // Ladders
+ if(pa.Find("left"))
+ holder.buildmode.coordA = get_turf(object)
+ user << "Defined [object] ([object.type]) as upper ladder location."
+
+ if(pa.Find("right"))
+ holder.buildmode.coordB = get_turf(object)
+ user << "Defined [object] ([object.type]) as lower ladder location."
+
+ if(holder.buildmode.coordA && holder.buildmode.coordB)
+ user << "Ladder locations set, building ladders."
+ var/obj/structure/ladder/A = new /obj/structure/ladder(holder.buildmode.coordA)
+ var/obj/structure/ladder/B = new /obj/structure/ladder(holder.buildmode.coordB)
+ A.target = B
+ B.target = A
+ B.icon_state = "ladderup"
+ holder.buildmode.coordA = null
+ holder.buildmode.coordB = null
+ if(7) // Move into contents
+ if(pa.Find("left"))
+ if(istype(object, /atom))
+ holder.throw_atom = object
+ if(pa.Find("right"))
+ if(holder.throw_atom && istype(object, /atom/movable))
+ object.forceMove(holder.throw_atom)
+ log_admin("[key_name(usr)] moved [object] into [holder.throw_atom].")
+ if(8) // Lights
+ if(pa.Find("left"))
+ if(object)
+ object.set_light(holder.buildmode.new_light_range, holder.buildmode.new_light_intensity, holder.buildmode.new_light_color)
+ if(pa.Find("right"))
+ if(object)
+ object.set_light(0, 0, "#FFFFFF")
+
+/obj/effect/bmode/buildmode/proc/get_path_from_partial_text(default_path)
+ var/desired_path = input("Enter full or partial typepath.","Typepath","[default_path]")
+
+ var/list/types = typesof(/atom)
+ var/list/matches = list()
+
+ for(var/path in types)
+ if(findtext("[path]", desired_path))
+ matches += path
+
+ if(matches.len==0)
+ alert("No results found. Sorry.")
+ return
+
+ var/result = null
+
+ if(matches.len==1)
+ result = matches[1]
+ else
+ result = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches
+ if(!objholder)
+ result = default_path
+ return result
+
+/obj/effect/bmode/buildmode/proc/make_rectangle(var/turf/A, var/turf/B, var/turf/wall_type, var/turf/floor_type)
+ if(!A || !B) // No coords
+ return
+ if(A.z != B.z) // Not same z-level
+ return
+
+ var/height = A.y - B.y
+ var/width = A.x - B.x
+ var/z_level = A.z
+
+ var/turf/lower_left_corner = null
+ // First, try to find the lowest part
+ var/desired_y = 0
+ if(A.y <= B.y)
+ desired_y = A.y
+ else
+ desired_y = B.y
+
+ //Now for the left-most part.
+ var/desired_x = 0
+ if(A.x <= B.x)
+ desired_x = A.x
+ else
+ desired_x = B.x
+
+ lower_left_corner = locate(desired_x, desired_y, z_level)
+
+ // Now we can begin building the actual room. This defines the boundries for the room.
+ var/low_bound_x = lower_left_corner.x
+ var/low_bound_y = lower_left_corner.y
+
+ var/high_bound_x = lower_left_corner.x + abs(width)
+ var/high_bound_y = lower_left_corner.y + abs(height)
+
+ for(var/i = low_bound_x, i <= high_bound_x, i++)
+ for(var/j = low_bound_y, j <= high_bound_y, j++)
+ var/turf/T = locate(i, j, z_level)
+ if(i == low_bound_x || i == high_bound_x || j == low_bound_y || j == high_bound_y)
+ if(isturf(wall_type))
+ T.ChangeTurf(wall_type)
+ else
+ new wall_type(T)
+ else
+ if(isturf(floor_type))
+ T.ChangeTurf(floor_type)
+ else
+ new floor_type(T)
\ No newline at end of file
diff --git a/code/modules/admin/verbs/custom_event.dm b/code/modules/admin/verbs/custom_event.dm
index 265c16a868..35931f8e54 100644
--- a/code/modules/admin/verbs/custom_event.dm
+++ b/code/modules/admin/verbs/custom_event.dm
@@ -7,7 +7,7 @@
src << "Only administrators may use this command."
return
- var/input = sanitize(input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", custom_event_msg) as message|null, MAX_BOOK_MESSAGE_LEN, extra = 0)
+ var/input = sanitize(input(usr, "Enter the description of the custom event. Be descriptive. To cancel the event, make this blank or hit cancel.", "Custom Event", custom_event_msg) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
if(!input || input == "")
custom_event_msg = null
log_admin("[usr.key] has cleared the custom event text.")
diff --git a/code/modules/admin/verbs/pray.dm b/code/modules/admin/verbs/pray.dm
index 23f5a75e2c..844f74b5f6 100644
--- a/code/modules/admin/verbs/pray.dm
+++ b/code/modules/admin/verbs/pray.dm
@@ -21,6 +21,7 @@
if(R_ADMIN & C.holder.rights)
if(C.is_preference_enabled(/datum/client_preference/admin/show_chat_prayers))
C << msg
+ C << 'sound/effects/ding.ogg'
usr << "Your prayers have been received by the gods."
feedback_add_details("admin_verb","PR") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -31,9 +32,11 @@
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << msg
+ C << 'sound/machines/signal.ogg'
/proc/Syndicate_announce(var/msg, var/mob/Sender)
msg = "\blue ILLEGAL:[key_name(Sender, 1)] (PP) (VV) (SM) ([admin_jump_link(Sender, src)]) (CA) (BSA) (RPLY): [msg]"
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << msg
+ C << 'sound/machines/signal.ogg'
\ No newline at end of file
diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm
index b33b5746a9..48e3b76dcf 100644
--- a/code/modules/client/client procs.dm
+++ b/code/modules/client/client procs.dm
@@ -158,6 +158,7 @@
if(!void)
void = new()
+ void.MakeGreed()
screen += void
if(prefs.lastchangelog != changelog_hash) //bolds the changelog button on the interface so we know there are updates.
diff --git a/code/modules/client/preference_setup/antagonism/01_basic.dm b/code/modules/client/preference_setup/antagonism/01_basic.dm
index 5b0be7bb71..e0a60b6313 100644
--- a/code/modules/client/preference_setup/antagonism/01_basic.dm
+++ b/code/modules/client/preference_setup/antagonism/01_basic.dm
@@ -7,19 +7,29 @@ var/global/list/uplink_locations = list("PDA", "Headset", "None")
/datum/category_item/player_setup_item/antagonism/basic/load_character(var/savefile/S)
S["uplinklocation"] >> pref.uplinklocation
S["exploit_record"] >> pref.exploit_record
+ S["antag_faction"] >> pref.antag_faction
+ S["antag_vis"] >> pref.antag_vis
/datum/category_item/player_setup_item/antagonism/basic/save_character(var/savefile/S)
S["uplinklocation"] << pref.uplinklocation
S["exploit_record"] << pref.exploit_record
+ S["antag_faction"] << pref.antag_faction
+ S["antag_vis"] << pref.antag_vis
/datum/category_item/player_setup_item/antagonism/basic/sanitize_character()
pref.uplinklocation = sanitize_inlist(pref.uplinklocation, uplink_locations, initial(pref.uplinklocation))
+ if(!pref.antag_faction) pref.antag_faction = "None"
+ if(!pref.antag_vis) pref.antag_vis = "Hidden"
// Moved from /datum/preferences/proc/copy_to()
/datum/category_item/player_setup_item/antagonism/basic/copy_to_mob(var/mob/living/carbon/human/character)
character.exploit_record = pref.exploit_record
+ character.antag_faction = pref.antag_faction
+ character.antag_vis = pref.antag_vis
/datum/category_item/player_setup_item/antagonism/basic/content(var/mob/user)
+ . += "Faction: [pref.antag_faction]
"
+ . += "Visibility: [pref.antag_vis]
"
. +="Uplink Type : [pref.uplinklocation]"
. +="
"
. +="Exploitable information:
"
@@ -34,9 +44,29 @@ var/global/list/uplink_locations = list("PDA", "Headset", "None")
return TOPIC_REFRESH
if(href_list["exploitable_record"])
- var/exploitmsg = sanitize(input(user,"Set exploitable information about you here.","Exploitable Information", html_decode(pref.exploit_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
+ var/exploitmsg = sanitize(input(user,"Set exploitable information about you here.","Exploitable Information", html_decode(pref.exploit_record)) as message|null, MAX_RECORD_LENGTH, extra = 0)
if(!isnull(exploitmsg) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.exploit_record = exploitmsg
return TOPIC_REFRESH
+
+ if(href_list["antagfaction"])
+ var/choice = input(user, "Please choose an antagonistic faction to work for.", "Character Preference", pref.antag_faction) as null|anything in antag_faction_choices + list("None","Other")
+ if(!choice || !CanUseTopic(user))
+ return TOPIC_NOACTION
+ if(choice == "Other")
+ var/raw_choice = sanitize(input(user, "Please enter a faction.", "Character Preference") as text|null, MAX_NAME_LEN)
+ if(raw_choice)
+ pref.antag_faction = raw_choice
+ else
+ pref.antag_faction = choice
+ return TOPIC_REFRESH
+
+ if(href_list["antagvis"])
+ var/choice = input(user, "Please choose an antagonistic visibility level.", "Character Preference", pref.antag_vis) as null|anything in antag_visiblity_choices
+ if(!choice || !CanUseTopic(user))
+ return TOPIC_NOACTION
+ else
+ pref.antag_vis = choice
+ return TOPIC_REFRESH
return ..()
diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm
index 8bd528cb5d..3842d243f8 100644
--- a/code/modules/client/preference_setup/general/03_body.dm
+++ b/code/modules/client/preference_setup/general/03_body.dm
@@ -121,6 +121,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
I.mechassist()
else if(status == "mechanical")
I.robotize()
+ else if(status == "digital")
+ I.digitize()
return
/datum/category_item/player_setup_item/general/body/content(var/mob/user)
@@ -197,6 +199,11 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if(ind > 1)
. += ", "
. += "\tSynthetic [organ_name]"
+ else if(status == "digital")
+ ++ind
+ if(ind > 1)
+ . += ", "
+ . += "\tDigital [organ_name]"
else if(status == "assisted")
++ind
if(ind > 1)
@@ -549,6 +556,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/list/organ_choices = list("Normal","Assisted","Mechanical")
if(pref.organ_data[BP_TORSO] == "cyborg")
organ_choices -= "Normal"
+ if(organ_name == "Brain")
+ organ_choices += "Digital"
var/new_state = input(user, "What state do you wish the organ to be in?") as null|anything in organ_choices
if(!new_state) return
@@ -560,6 +569,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.organ_data[organ] = "assisted"
if("Mechanical")
pref.organ_data[organ] = "mechanical"
+ if("Digital")
+ pref.organ_data[organ] = "digital"
return TOPIC_REFRESH
else if(href_list["disabilities"])
diff --git a/code/modules/client/preference_setup/general/05_background.dm b/code/modules/client/preference_setup/general/05_background.dm
index e3076629a8..c36ce85834 100644
--- a/code/modules/client/preference_setup/general/05_background.dm
+++ b/code/modules/client/preference_setup/general/05_background.dm
@@ -115,19 +115,19 @@
return TOPIC_REFRESH
else if(href_list["set_medical_records"])
- var/new_medical = sanitize(input(user,"Enter medical information here.","Character Preference", html_decode(pref.med_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
+ var/new_medical = sanitize(input(user,"Enter medical information here.","Character Preference", html_decode(pref.med_record)) as message|null, MAX_RECORD_LENGTH, extra = 0)
if(!isnull(new_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.med_record = new_medical
return TOPIC_REFRESH
else if(href_list["set_general_records"])
- var/new_general = sanitize(input(user,"Enter employment information here.","Character Preference", html_decode(pref.gen_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
+ var/new_general = sanitize(input(user,"Enter employment information here.","Character Preference", html_decode(pref.gen_record)) as message|null, MAX_RECORD_LENGTH, extra = 0)
if(!isnull(new_general) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.gen_record = new_general
return TOPIC_REFRESH
else if(href_list["set_security_records"])
- var/sec_medical = sanitize(input(user,"Enter security information here.","Character Preference", html_decode(pref.sec_record)) as message|null, MAX_PAPER_MESSAGE_LEN, extra = 0)
+ var/sec_medical = sanitize(input(user,"Enter security information here.","Character Preference", html_decode(pref.sec_record)) as message|null, MAX_RECORD_LENGTH, extra = 0)
if(!isnull(sec_medical) && !jobban_isbanned(user, "Records") && CanUseTopic(user))
pref.sec_record = sec_medical
return TOPIC_REFRESH
diff --git a/code/modules/client/preference_setup/loadout/loadout_general.dm b/code/modules/client/preference_setup/loadout/loadout_general.dm
index b659f8db13..a97d5776fc 100644
--- a/code/modules/client/preference_setup/loadout/loadout_general.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_general.dm
@@ -3,8 +3,12 @@
path = /obj/item/weapon/cane
/datum/gear/dice
- display_name = "d20"
- path = /obj/item/weapon/dice/d20
+ display_name = "dice pack"
+ path = /obj/item/weapon/storage/pill_bottle/dice
+
+/datum/gear/dice/nerd
+ display_name = "dice pack (gaming)"
+ path = /obj/item/weapon/storage/pill_bottle/dice_nerd
/datum/gear/cards
display_name = "deck of cards"
diff --git a/code/modules/client/preference_setup/loadout/loadout_gloves.dm b/code/modules/client/preference_setup/loadout/loadout_gloves.dm
index 244977334f..91d20d8371 100644
--- a/code/modules/client/preference_setup/loadout/loadout_gloves.dm
+++ b/code/modules/client/preference_setup/loadout/loadout_gloves.dm
@@ -48,4 +48,12 @@
/datum/gear/gloves/white
display_name = "gloves, white"
- path = /obj/item/clothing/gloves/white
\ No newline at end of file
+ path = /obj/item/clothing/gloves/white
+
+/datum/gear/gloves/evening
+ display_name = "evening gloves"
+ path = /obj/item/clothing/gloves/evening
+
+/datum/gear/gloves/evening/New()
+ ..()
+ gear_tweaks = list(gear_tweak_free_color_choice)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 6600b78c83..023acdfd9d 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -54,8 +54,10 @@ datum/preferences
//Some faction information.
var/home_system = "Unset" //System of birth.
var/citizenship = "None" //Current home system.
- var/faction = "None" //Antag faction/general associated faction.
+ var/faction = "None" //General associated faction.
var/religion = "None" //Religious association.
+ var/antag_faction = "None" //Antag associated faction.
+ var/antag_vis = "Hidden" //How visible antag association is to others.
//Mob preview
var/icon/preview_icon = null
diff --git a/code/modules/client/preferences_factions.dm b/code/modules/client/preferences_factions.dm
index 61d6810224..030c8d08a3 100644
--- a/code/modules/client/preferences_factions.dm
+++ b/code/modules/client/preferences_factions.dm
@@ -1,6 +1,7 @@
var/global/list/seen_citizenships = list()
var/global/list/seen_systems = list()
var/global/list/seen_factions = list()
+var/global/list/seen_antag_factions = list()
var/global/list/seen_religions = list()
//Commenting this out for now until I work the lists it into the event generator/journalist/chaplain.
@@ -25,6 +26,7 @@ var/global/list/home_system_choices = list(
starsys_name,
"Nyx",
"Tau Ceti",
+ "Qerr'Vallis",
"Epsilon Ursae Minoris",
"S'randarr"
)
@@ -42,6 +44,14 @@ var/global/list/faction_choices = list(
"Zeng-Hu Pharmaceuticals",
"Hesphaistos Industries"
)
+
+var/global/list/antag_faction_choices = list() //Should be populated after brainstorming. Leaving as blank in case brainstorming does not occur.
+
+var/global/list/antag_visiblity_choices = list(
+ "Hidden",
+ "Shared",
+ "Known"
+ )
var/global/list/religion_choices = list(
"Unitarianism",
diff --git a/code/modules/clothing/gloves/color.dm b/code/modules/clothing/gloves/color.dm
index 870fcc487f..870d537dd3 100644
--- a/code/modules/clothing/gloves/color.dm
+++ b/code/modules/clothing/gloves/color.dm
@@ -16,7 +16,7 @@
New()
//average of 0.5, somewhat better than regular gloves' 0.75
- siemens_coefficient = pick(0,0.1,0.3,0.5,0.5,0.75,1.35)
+ siemens_coefficient = pick(0,0.1,0.3,0.5,0.5,0.75,1.35)
/obj/item/clothing/gloves/black
desc = "These work gloves are thick and fire-resistant."
@@ -84,3 +84,14 @@
desc = "A pair of gloves, they don't look special in any way."
icon_state = "brown"
item_state = "browngloves"
+
+/obj/item/clothing/gloves/evening
+ desc = "A pair of gloves that reach past the elbow. Fancy!"
+ name = "evening gloves"
+ icon_state = "evening_gloves"
+ item_state = "graygloves"
+
+ cold_protection = HANDS
+ min_cold_protection_temperature = GLOVES_MIN_COLD_PROTECTION_TEMPERATURE
+ heat_protection = HANDS
+ max_heat_protection_temperature = GLOVES_MAX_HEAT_PROTECTION_TEMPERATURE
diff --git a/code/modules/clothing/spacesuits/rig/modules/computer.dm b/code/modules/clothing/spacesuits/rig/modules/computer.dm
index c8a2296680..ccfc307993 100644
--- a/code/modules/clothing/spacesuits/rig/modules/computer.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/computer.dm
@@ -434,6 +434,8 @@
holder.spark_system.start()
playsound(H.loc, 'sound/effects/sparks2.ogg', 50, 1)
+ H.break_cloak()
+
if(!holder.cell)
H << "Your power sink flashes an error; there is no cell in your rig."
drain_complete(H)
diff --git a/code/modules/clothing/spacesuits/rig/modules/ninja.dm b/code/modules/clothing/spacesuits/rig/modules/ninja.dm
index 5f6ce6249c..cb269daa2e 100644
--- a/code/modules/clothing/spacesuits/rig/modules/ninja.dm
+++ b/code/modules/clothing/spacesuits/rig/modules/ninja.dm
@@ -42,7 +42,7 @@
anim(get_turf(H), H, 'icons/effects/effects.dmi', "electricity",null,20,null)
- H.visible_message("[H.name] vanishes into thin air!",1)
+ H.visible_message("[H.name] vanishes into thin air!")
/obj/item/rig_module/stealth_field/deactivate()
diff --git a/code/modules/clothing/spacesuits/rig/suits/light.dm b/code/modules/clothing/spacesuits/rig/suits/light.dm
index 3c4975f7d3..f33200a242 100644
--- a/code/modules/clothing/spacesuits/rig/suits/light.dm
+++ b/code/modules/clothing/spacesuits/rig/suits/light.dm
@@ -74,7 +74,7 @@
/obj/item/weapon/rig/light/ninja
name = "ominous suit control module"
suit_type = "ominous"
- desc = "A unique, vaccum-proof suit of nano-enhanced armor designed specifically for Spider Clan assassins."
+ desc = "A unique suit of nano-enhanced armor designed for covert operations."
icon_state = "ninja_rig"
armor = list(melee = 50, bullet = 15, laser = 30, energy = 10, bomb = 25, bio = 100, rad = 30)
emp_protection = 40 //change this to 30 if too high.
diff --git a/code/modules/clothing/under/accessories/accessory.dm b/code/modules/clothing/under/accessories/accessory.dm
index c9ac0fb4f4..747f02552d 100644
--- a/code/modules/clothing/under/accessories/accessory.dm
+++ b/code/modules/clothing/under/accessories/accessory.dm
@@ -12,6 +12,8 @@
var/image/mob_overlay = null
var/overlay_state = null
+ sprite_sheets = list("Teshari" = 'icons/mob/species/seromi/ties.dmi') //Teshari can into webbing, too!
+
/obj/item/clothing/accessory/Destroy()
on_removed()
return ..()
diff --git a/code/modules/games/cards.dm b/code/modules/games/cards.dm
index 1b353e3407..3fcf07713b 100644
--- a/code/modules/games/cards.dm
+++ b/code/modules/games/cards.dm
@@ -134,7 +134,7 @@
if(P.name != "Blank Card")
user << "You cannot write on that card."
return
- var/cardtext = sanitize(input(user, "What do you wish to write on the card?", "Card Editing") as text|null, MAX_BOOK_MESSAGE_LEN)
+ var/cardtext = sanitize(input(user, "What do you wish to write on the card?", "Card Editing") as text|null, MAX_PAPER_MESSAGE_LEN)
if(!cardtext)
return
P.name = cardtext
diff --git a/code/modules/holodeck/HolodeckControl.dm b/code/modules/holodeck/HolodeckControl.dm
index 4c0d0a755e..1bc0c721c7 100644
--- a/code/modules/holodeck/HolodeckControl.dm
+++ b/code/modules/holodeck/HolodeckControl.dm
@@ -30,62 +30,60 @@
"Snow Field" = "snowfield", \
"Theatre" = "theatre", \
"Meeting Hall" = "meetinghall", \
- "Courtroom" = "courtroom" \
+ "Courtroom" = "courtroom", \
+ "Turn Off" = "turnoff" \
)
var/list/restricted_programs = list("Atmospheric Burn Simulation" = "burntest", "Wildlife Simulation" = "wildlifecarp")
+ var/current_program = "turnoff"
/obj/machinery/computer/HolodeckControl/attack_ai(var/mob/user as mob)
return src.attack_hand(user)
/obj/machinery/computer/HolodeckControl/attack_hand(var/mob/user as mob)
-
if(..())
return
user.set_machine(src)
- var/dat
- dat += "Holodeck Control System
"
- dat += "
Current Loaded Programs:
"
- for(var/prog in supported_programs)
- dat += "([prog])
"
+ ui_interact(user)
- dat += "
"
- dat += "(Turn Off)
"
+/**
+ * Display the NanoUI window for the Holodeck Computer.
+ *
+ * See NanoUI documentation for details.
+ */
+/obj/machinery/computer/HolodeckControl/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
- dat += "
"
- dat += "Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
"
+ var/list/data = list()
+ var/program_list[0]
+ var/restricted_program_list[0]
+ for(var/P in supported_programs)
+ program_list[++program_list.len] = list("name" = P, "program" = supported_programs[P])
+
+ for(var/P in restricted_programs)
+ restricted_program_list[++restricted_program_list.len] = list("name" = P, "program" = restricted_programs[P])
+
+ data["supportedPrograms"] = program_list
+ data["restrictedPrograms"] = restricted_program_list
+ data["currentProgram"] = current_program
if(issilicon(user))
- dat += "
"
- if(safety_disabled)
- if (emagged)
- dat += "ERROR: Cannot re-enable Safety Protocols.
"
- else
- dat += "(Re-Enable Safety Protocols?)
"
- else
- dat += "(Override Safety Protocols?)
"
-
- dat += "
"
-
- if(safety_disabled)
- for(var/prog in restricted_programs)
- dat += "(Begin [prog])
"
- dat += "Ensure the holodeck is empty before testing.
"
- dat += "
"
- dat += "Safety Protocols are DISABLED
"
+ data["isSilicon"] = 1
else
- dat += "Safety Protocols are ENABLED
"
-
+ data["isSilicon"] = null
+ data["safetyDisabled"] = safety_disabled
+ data["emagged"] = emagged
if(linkedholodeck.has_gravity)
- dat += "Gravity is (ON)
"
+ data["gravity"] = 1
else
- dat += "Gravity is (OFF)
"
-
- user << browse(dat, "window=computer;size=400x500")
- onclose(user, "computer")
-
- return
+ data["gravity"] = null
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "holodeck.tmpl", src.name, 400, 550)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(20)
/obj/machinery/computer/HolodeckControl/Topic(href, href_list)
if(..())
@@ -97,6 +95,7 @@
var/prog = href_list["program"]
if(prog in holodeck_programs)
loadProgram(holodeck_programs[prog])
+ current_program = href_list["program"]
else if(href_list["AIoverride"])
if(!issilicon(usr))
@@ -118,8 +117,8 @@
toggleGravity(linkedholodeck)
src.add_fingerprint(usr)
- src.updateUsrDialog()
- return
+
+ nanomanager.update_uis(src)
/obj/machinery/computer/HolodeckControl/emag_act(var/remaining_charges, var/mob/user as mob)
playsound(src.loc, 'sound/effects/sparks4.ogg', 75, 1)
@@ -132,7 +131,6 @@
user << "Warning. Automatic shutoff and derezing protocols have been corrupted. Please call [company_name] maintenance and do not use the simulator."
log_game("[key_name(usr)] emagged the Holodeck Control Computer")
return 1
- src.updateUsrDialog()
return
/obj/machinery/computer/HolodeckControl/proc/update_projections()
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index 6e88aabee5..eb1eeb40ca 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -73,7 +73,7 @@
set_trait(TRAIT_PRODUCTION,5)
set_trait(TRAIT_YIELD,2)
set_trait(TRAIT_POTENCY,10)
- set_trait(TRAIT_PRODUCT_COLOUR,"c9fa16")
+ set_trait(TRAIT_PRODUCT_COLOUR,"#c9fa16")
set_trait(TRAIT_WATER_CONSUMPTION, 3)
set_trait(TRAIT_NUTRIENT_CONSUMPTION, 0.25)
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index 8e9155d044..1c93444aad 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -450,7 +450,7 @@ var/list/mining_overlay_cache = list()
if(prob(50))
M.adjustBruteLoss(5)
else
- flick("flash",M.flash)
+ M.flash_eyes()
if(prob(50))
M.Stun(5)
M.apply_effect(25, IRRADIATE)
diff --git a/code/modules/mob/death.dm b/code/modules/mob/death.dm
index 4b6598cf1b..c867e642b4 100644
--- a/code/modules/mob/death.dm
+++ b/code/modules/mob/death.dm
@@ -66,9 +66,6 @@
layer = MOB_LAYER
- if(blind && client)
- blind.layer = 0
-
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
see_in_dark = 8
see_invisible = SEE_INVISIBLE_LEVEL_TWO
diff --git a/code/modules/mob/holder.dm b/code/modules/mob/holder.dm
index e02b635ed9..b56435a59e 100644
--- a/code/modules/mob/holder.dm
+++ b/code/modules/mob/holder.dm
@@ -114,6 +114,11 @@ var/list/holder_mob_icon_cache = list()
if(!holder_type || buckled || pinned.len)
return
+ if(self_grab)
+ if(src.incapacitated()) return
+ else
+ if(grabber.incapacitated()) return
+
var/obj/item/weapon/holder/H = new holder_type(get_turf(src))
H.held_mob = src
src.forceMove(H)
diff --git a/code/modules/mob/living/carbon/alien/alien_damage.dm b/code/modules/mob/living/carbon/alien/alien_damage.dm
index 99c5e52f75..f2d147641f 100644
--- a/code/modules/mob/living/carbon/alien/alien_damage.dm
+++ b/code/modules/mob/living/carbon/alien/alien_damage.dm
@@ -1,7 +1,7 @@
/mob/living/carbon/alien/ex_act(severity)
if(!blinded)
- flick("flash", flash)
+ flash_eyes()
var/b_loss = null
var/f_loss = null
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index 9352ada1c5..a7764d3d1d 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -124,21 +124,16 @@
if (client)
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
- if ((blind && stat != 2))
+ if ( stat != 2)
if ((blinded))
- blind.layer = 18
+ overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else
- blind.layer = 0
- if (disabilities & NEARSIGHTED)
- client.screen += global_hud.vimpaired
- if (eye_blurry)
- client.screen += global_hud.blurry
- if (druggy)
- client.screen += global_hud.druggy
-
- if (stat != 2)
- if (machine)
- if ( machine.check_eye(src) < 0)
+ clear_fullscreen("blind")
+ set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
+ set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
+ set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
+ if(machine)
+ if(machine.check_eye(src) < 0)
reset_view(null)
else
if(client && !client.adminobs)
diff --git a/code/modules/mob/living/carbon/brain/brain_item.dm b/code/modules/mob/living/carbon/brain/brain_item.dm
index 6e1d4bce9c..11e3b1197a 100644
--- a/code/modules/mob/living/carbon/brain/brain_item.dm
+++ b/code/modules/mob/living/carbon/brain/brain_item.dm
@@ -21,6 +21,9 @@
/obj/item/organ/internal/brain/mechassist()
replace_self_with(/obj/item/organ/internal/mmi_holder)
+/obj/item/organ/internal/brain/digitize()
+ replace_self_with(/obj/item/organ/internal/mmi_holder/robot)
+
/obj/item/organ/internal/brain/proc/replace_self_with(replace_path)
var/mob/living/carbon/human/tmp_owner = owner
qdel(src)
diff --git a/code/modules/mob/living/carbon/brain/life.dm b/code/modules/mob/living/carbon/brain/life.dm
index 29ef1a2484..cb889b570f 100644
--- a/code/modules/mob/living/carbon/brain/life.dm
+++ b/code/modules/mob/living/carbon/brain/life.dm
@@ -208,22 +208,15 @@
if (client)
client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
- if ((blind && stat != 2))
- if ((blinded))
- blind.layer = 18
- else
- blind.layer = 0
-
- if (disabilities & NEARSIGHTED)
- client.screen += global_hud.vimpaired
-
- if (eye_blurry)
- client.screen += global_hud.blurry
-
- if (druggy)
- client.screen += global_hud.druggy
-
if (stat != 2)
+ if ((blinded))
+ overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
+ else
+ clear_fullscreen("blind")
+ set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
+ set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
+ set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
+
if (machine)
if (!( machine.check_eye(src) ))
reset_view(null)
@@ -239,17 +232,4 @@
reset_view(null)
else
if(client && !client.adminobs)
- reset_view(null)
-
-/*/mob/living/carbon/brain/emp_act(severity)
- if(!(container && istype(container, /obj/item/device/mmi)))
- return
- else
- switch(severity)
- if(1)
- emp_damage += rand(20,30)
- if(2)
- emp_damage += rand(10,20)
- if(3)
- emp_damage += rand(0,10)
- ..()*/
+ reset_view(null)
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 6b9cbf0258..4eaf5aa8fe 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -194,7 +194,7 @@
status += "hurts when touched"
if(org.status & ORGAN_DEAD)
status += "is bruised and necrotic"
- if(!org.is_usable())
+ if(!org.is_usable() || org.is_dislocated())
status += "dangling uselessly"
if(status.len)
src.show_message("My [org.name] is [english_list(status)].",1)
@@ -309,14 +309,19 @@
if(!item) return
+ var/throw_range = item.throw_range
if (istype(item, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = item
item = G.throw_held() //throw the person instead of the grab
if(ismob(item))
+ var/mob/M = item
+
+ //limit throw range by relative mob size
+ throw_range = round(M.throw_range * min(src.mob_size/M.mob_size, 1))
+
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
var/turf/end_T = get_turf(target)
if(start_T && end_T)
- var/mob/M = item
var/start_T_descriptor = "tile at [start_T.x], [start_T.y], [start_T.z] in area [get_area(start_T)]"
var/end_T_descriptor = "tile at [end_T.x], [end_T.y], [end_T.z] in area [get_area(end_T)]"
@@ -324,31 +329,28 @@
usr.attack_log += text("\[[time_stamp()]\] Has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor]")
msg_admin_attack("[usr.name] ([usr.ckey]) has thrown [M.name] ([M.ckey]) from [start_T_descriptor] with the target [end_T_descriptor] (JMP)")
- if(!item) return //Grab processing has a chance of returning null
-
-
- src.remove_from_mob(item)
- item.loc = src.loc
+ src.drop_from_inventory(item)
+ if(!item || !isturf(item.loc))
+ return
//actually throw it!
- if (item)
- src.visible_message("\red [src] has thrown [item].")
+ src.visible_message("[src] has thrown [item].")
- if(!src.lastarea)
- src.lastarea = get_area(src.loc)
- if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0))
- src.inertia_dir = get_dir(target, src)
- step(src, inertia_dir)
+ if(!src.lastarea)
+ src.lastarea = get_area(src.loc)
+ if((istype(src.loc, /turf/space)) || (src.lastarea.has_gravity == 0))
+ src.inertia_dir = get_dir(target, src)
+ step(src, inertia_dir)
/*
- if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction
- src.inertia_dir = get_dir(target, src)
- step(src, inertia_dir)
+ if(istype(src.loc, /turf/space) || (src.flags & NOGRAV)) //they're in space, move em one space in the opposite direction
+ src.inertia_dir = get_dir(target, src)
+ step(src, inertia_dir)
*/
- item.throw_at(target, item.throw_range, item.throw_speed, src)
+ item.throw_at(target, throw_range, item.throw_speed, src)
/mob/living/carbon/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
..()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 96b34c0949..7a36cfa3ba 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -84,7 +84,7 @@
/mob/living/carbon/human/ex_act(severity)
if(!blinded)
- flick("flash", flash)
+ flash_eyes()
var/shielded = 0
var/b_loss = null
@@ -779,13 +779,6 @@
b_eyes = hex2num(copytext(new_eyes, 6, 8))
update_eyes()
- var/new_tone = input("Please select skin tone level: 1-220 (1=albino, 35=caucasian, 150=black, 220='very' black)", "Character Generation", "[35-s_tone]") as text
-
- if (!new_tone)
- new_tone = 35
- s_tone = max(min(round(text2num(new_tone)), 220), 1)
- s_tone = -s_tone + 35
-
// hair
var/list/all_hairs = typesof(/datum/sprite_accessory/hair) - /datum/sprite_accessory/hair
var/list/hairs = list()
@@ -1336,8 +1329,8 @@
var/list/limbs = list()
for(var/limb in organs_by_name)
var/obj/item/organ/external/current_limb = organs_by_name[limb]
- if(current_limb && current_limb.dislocated == 2)
- limbs |= limb
+ if(current_limb && current_limb.dislocated > 0 && !current_limb.is_parent_dislocated()) //if the parent is also dislocated you will have to relocate that first
+ limbs |= current_limb
var/choice = input(usr,"Which joint do you wish to relocate?") as null|anything in limbs
if(!choice)
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 728de86748..d638d779d1 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -9,7 +9,6 @@
return null
/mob/living/carbon/human/attack_hand(mob/living/carbon/M as mob)
-
var/mob/living/carbon/human/H = M
if(istype(H))
var/obj/item/organ/external/temp = H.organs_by_name["r_hand"]
@@ -18,7 +17,7 @@
if(!temp || !temp.is_usable())
H << "\red You can't use your hand."
return
- break_cloak()
+ H.break_cloak()
..()
// Should this all be in Touch()?
@@ -331,7 +330,7 @@
if(!target_zone)
return 0
var/obj/item/organ/external/organ = get_organ(check_zone(target_zone))
- if(!organ || organ.is_dislocated() || organ.dislocated == -1)
+ if(!organ || organ.dislocated > 0 || organ.dislocated == -1) //don't use is_dislocated() here, that checks parent
return 0
user.visible_message("[user] begins to dislocate [src]'s [organ.joint]!")
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 614bbe1de8..6edefd2951 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -187,11 +187,13 @@ emp_act
// Handle striking to cripple.
if(user.a_intent == I_DISARM)
- effective_force /= 2
- if(..(I, user, effective_force, blocked, hit_zone))
- attack_joint(affecting, I, blocked)
- else
+ effective_force *= 0.66 //reduced effective force...
+ if(!..(I, user, effective_force, blocked, hit_zone))
return 0
+
+ //set the dislocate mult less than the effective force mult so that
+ //dislocating limbs on disarm is a bit easier than breaking limbs on harm
+ attack_joint(affecting, I, effective_force, 0.5, blocked) //...but can dislocate joints
else if(!..())
return 0
@@ -242,10 +244,16 @@ emp_act
return 1
-/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/blocked)
+/mob/living/carbon/human/proc/attack_joint(var/obj/item/organ/external/organ, var/obj/item/W, var/effective_force, var/dislocate_mult, var/blocked)
if(!organ || (organ.dislocated == 2) || (organ.dislocated == -1) || blocked >= 100)
return 0
- if(prob(W.force * (100 - blocked)/100))
+
+ if(W.damtype != BRUTE)
+ return 0
+
+ //want the dislocation chance to be such that the limb is expected to dislocate after dealing a fraction of the damage needed to break the limb
+ var/dislocate_chance = effective_force/(dislocate_mult * organ.min_broken_damage * config.organ_health_multiplier)*100
+ if(prob(dislocate_chance * (100 - blocked)/100))
visible_message("[src]'s [organ.joint] [pick("gives way","caves in","crumbles","collapses")]!")
organ.dislocate(1)
return 1
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 6b877dcb04..3779e791cc 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -45,6 +45,8 @@
var/citizenship = ""
var/personal_faction = ""
var/religion = ""
+ var/antag_faction = ""
+ var/antag_vis = ""
//Equipment slots
var/obj/item/wear_suit = null
diff --git a/code/modules/mob/living/carbon/human/human_organs.dm b/code/modules/mob/living/carbon/human/human_organs.dm
index 9743475332..494126e312 100644
--- a/code/modules/mob/living/carbon/human/human_organs.dm
+++ b/code/modules/mob/living/carbon/human/human_organs.dm
@@ -68,7 +68,7 @@
/mob/living/carbon/human/proc/handle_stance()
// Don't need to process any of this if they aren't standing anyways
// unless their stance is damaged, and we want to check if they should stay down
- if (!stance_damage && (lying || resting) && (life_tick % 4) == 0)
+ if (!stance_damage && (lying || resting) && (life_tick % 4) != 0)
return
stance_damage = 0
@@ -80,7 +80,7 @@
var/limb_pain
for(var/limb_tag in list("l_leg","r_leg","l_foot","r_foot"))
var/obj/item/organ/external/E = organs_by_name[limb_tag]
- if(!E || (E.status & (ORGAN_MUTATED|ORGAN_DEAD)) || E.is_stump()) //should just be !E.is_usable() here but dislocation screws that up.
+ if(!E || !E.is_usable())
stance_damage += 2 // let it fail even if just foot&leg
else if (E.is_malfunctioning())
//malfunctioning only happens intermittently so treat it as a missing limb when it procs
@@ -93,7 +93,7 @@
spark_system.start()
spawn(10)
qdel(spark_system)
- else if (E.is_broken() || !E.is_usable())
+ else if (E.is_broken())
stance_damage += 1
else if (E.is_dislocated())
stance_damage += 0.5
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index b669647ec9..4de9a1b9fe 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -32,7 +32,6 @@
var/temperature_alert = 0
var/in_stasis = 0
var/heartbeat = 0
- var/global/list/overlays_cache = null
/mob/living/carbon/human/Life()
set invisibility = 0
@@ -619,11 +618,11 @@
if(!istype(loc, /obj/machinery/atmospherics/unary/cryo_cell))
var/burn_dam = 0
switch(bodytemperature)
- if(-INFINITY to species.cold_level_3)
+ if(species.cold_level_1 to species.cold_level_2)
burn_dam = COLD_DAMAGE_LEVEL_1
- if(species.cold_level_3 to species.cold_level_2)
+ if(species.cold_level_2 to species.cold_level_3)
burn_dam = COLD_DAMAGE_LEVEL_2
- if(species.cold_level_2 to species.cold_level_1)
+ if(species.cold_level_3 to -INFINITY)
burn_dam = COLD_DAMAGE_LEVEL_3
take_overall_damage(burn=burn_dam, used_weapon = "Low Body Temperature")
fire_alert = max(fire_alert, 1)
@@ -847,7 +846,10 @@
if(!isSynthetic() && (species.flags & IS_PLANT) && (!light_organ || light_organ.is_broken()))
if(nutrition < 200)
take_overall_damage(2,0)
- traumatic_shock++
+
+ //traumatic_shock is updated every tick, incrementing that is pointless - shock_stage is the counter.
+ //Not that it matters much for diona, who have NO_PAIN.
+ shock_stage++
// TODO: stomach and bloodstream organ.
if(!isSynthetic())
@@ -1011,33 +1013,6 @@
return 1
/mob/living/carbon/human/handle_regular_hud_updates()
- if(!overlays_cache)
- overlays_cache = list()
- overlays_cache.len = 23
- overlays_cache[1] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage1")
- overlays_cache[2] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage2")
- overlays_cache[3] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage3")
- overlays_cache[4] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage4")
- overlays_cache[5] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage5")
- overlays_cache[6] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage6")
- overlays_cache[7] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage7")
- overlays_cache[8] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage8")
- overlays_cache[9] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage9")
- overlays_cache[10] = image('icons/mob/screen1_full.dmi', "icon_state" = "passage10")
- overlays_cache[11] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay1")
- overlays_cache[12] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay2")
- overlays_cache[13] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay3")
- overlays_cache[14] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay4")
- overlays_cache[15] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay5")
- overlays_cache[16] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay6")
- overlays_cache[17] = image('icons/mob/screen1_full.dmi', "icon_state" = "oxydamageoverlay7")
- overlays_cache[18] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay1")
- overlays_cache[19] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay2")
- overlays_cache[20] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay3")
- overlays_cache[21] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay4")
- overlays_cache[22] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay5")
- overlays_cache[23] = image('icons/mob/screen1_full.dmi', "icon_state" = "brutedamageoverlay6")
-
if(hud_updateflag) // update our mob's hud overlays, AKA what others see flaoting above our head
handle_hud_list()
@@ -1056,75 +1031,53 @@
var/obj/machinery/camera/cam = client.eye
client.screen |= cam.client_huds
- if(damageoverlay.overlays)
- damageoverlay.overlays = list()
-
- if(stat == UNCONSCIOUS)
+ if(stat == UNCONSCIOUS && health <= 0)
//Critical damage passage overlay
- if(health <= 0)
- var/image/I
- switch(health)
- if(-20 to -10)
- I = overlays_cache[1]
- if(-30 to -20)
- I = overlays_cache[2]
- if(-40 to -30)
- I = overlays_cache[3]
- if(-50 to -40)
- I = overlays_cache[4]
- if(-60 to -50)
- I = overlays_cache[5]
- if(-70 to -60)
- I = overlays_cache[6]
- if(-80 to -70)
- I = overlays_cache[7]
- if(-90 to -80)
- I = overlays_cache[8]
- if(-95 to -90)
- I = overlays_cache[9]
- if(-INFINITY to -95)
- I = overlays_cache[10]
- damageoverlay.overlays += I
+ var/severity = 0
+ switch(health)
+ if(-20 to -10) severity = 1
+ if(-30 to -20) severity = 2
+ if(-40 to -30) severity = 3
+ if(-50 to -40) severity = 4
+ if(-60 to -50) severity = 5
+ if(-70 to -60) severity = 6
+ if(-80 to -70) severity = 7
+ if(-90 to -80) severity = 8
+ if(-95 to -90) severity = 9
+ if(-INFINITY to -95) severity = 10
+ overlay_fullscreen("crit", /obj/screen/fullscreen/crit, severity)
else
+ clear_fullscreen("crit")
//Oxygen damage overlay
if(oxyloss)
- var/image/I
+ var/severity = 0
switch(oxyloss)
- if(10 to 20)
- I = overlays_cache[11]
- if(20 to 25)
- I = overlays_cache[12]
- if(25 to 30)
- I = overlays_cache[13]
- if(30 to 35)
- I = overlays_cache[14]
- if(35 to 40)
- I = overlays_cache[15]
- if(40 to 45)
- I = overlays_cache[16]
- if(45 to INFINITY)
- I = overlays_cache[17]
- damageoverlay.overlays += I
+ if(10 to 20) severity = 1
+ if(20 to 25) severity = 2
+ if(25 to 30) severity = 3
+ if(30 to 35) severity = 4
+ if(35 to 40) severity = 5
+ if(40 to 45) severity = 6
+ if(45 to INFINITY) severity = 7
+ overlay_fullscreen("oxy", /obj/screen/fullscreen/oxy, severity)
+ else
+ clear_fullscreen("oxy")
//Fire and Brute damage overlay (BSSR)
var/hurtdamage = src.getBruteLoss() + src.getFireLoss() + damageoverlaytemp
damageoverlaytemp = 0 // We do this so we can detect if someone hits us or not.
if(hurtdamage)
- var/image/I
+ var/severity = 0
switch(hurtdamage)
- if(10 to 25)
- I = overlays_cache[18]
- if(25 to 40)
- I = overlays_cache[19]
- if(40 to 55)
- I = overlays_cache[20]
- if(55 to 70)
- I = overlays_cache[21]
- if(70 to 85)
- I = overlays_cache[22]
- if(85 to INFINITY)
- I = overlays_cache[23]
- damageoverlay.overlays += I
+ if(10 to 25) severity = 1
+ if(25 to 40) severity = 2
+ if(40 to 55) severity = 3
+ if(55 to 70) severity = 4
+ if(70 to 85) severity = 5
+ if(85 to INFINITY) severity = 6
+ overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
+ else
+ clear_fullscreen("brute")
if( stat == DEAD )
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS|SEE_SELF
@@ -1268,20 +1221,20 @@
bodytemp.icon_state = "temp-1"
else
bodytemp.icon_state = "temp0"
- if(blind)
- if(blinded) blind.layer = 18
- else blind.layer = 0
+
+ if(blinded) overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
+ else clear_fullscreens()
if(disabilities & NEARSIGHTED) //this looks meh but saves a lot of memory by not requiring to add var/prescription
if(glasses) //to every /obj/item
var/obj/item/clothing/glasses/G = glasses
if(!G.prescription)
- client.screen += global_hud.vimpaired
+ set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
else
- client.screen += global_hud.vimpaired
+ set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
- if(eye_blurry) client.screen += global_hud.blurry
- if(druggy) client.screen += global_hud.druggy
+ set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
+ set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
if(config.welder_vision)
var/found_welder
@@ -1684,4 +1637,4 @@
..()
#undef HUMAN_MAX_OXYLOSS
-#undef HUMAN_CRIT_MAX_OXYLOSS
+#undef HUMAN_CRIT_MAX_OXYLOSS
\ No newline at end of file
diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm
index 25a8149e48..def9ae59f2 100644
--- a/code/modules/mob/living/carbon/human/species/species.dm
+++ b/code/modules/mob/living/carbon/human/species/species.dm
@@ -190,6 +190,7 @@
/datum/species/proc/create_organs(var/mob/living/carbon/human/H) //Handles creation of mob organs.
+ H.mob_size = mob_size
for(var/obj/item/organ/organ in H.contents)
if((organ in H.organs) || (organ in H.internal_organs))
qdel(organ)
@@ -249,7 +250,6 @@
H.mob_swap_flags = swap_flags
H.mob_push_flags = push_flags
H.pass_flags = pass_flags
- H.mob_size = mob_size
/datum/species/proc/handle_death(var/mob/living/carbon/human/H) //Handles any species-specific death events (such as dionaea nymph spawns).
return
diff --git a/code/modules/mob/living/carbon/shock.dm b/code/modules/mob/living/carbon/shock.dm
index 92eccc66df..370d3f89d2 100644
--- a/code/modules/mob/living/carbon/shock.dm
+++ b/code/modules/mob/living/carbon/shock.dm
@@ -23,8 +23,10 @@
if(istype(src,/mob/living/carbon/human))
var/mob/living/carbon/human/M = src
for(var/obj/item/organ/external/organ in M.organs)
- if(organ && (organ.is_broken() || organ.open))
+ if(organ.is_broken() || organ.open)
src.traumatic_shock += 30
+ else if(organ.is_dislocated())
+ src.traumatic_shock += 15
if(src.traumatic_shock < 0)
src.traumatic_shock = 0
diff --git a/code/modules/mob/living/death.dm b/code/modules/mob/living/death.dm
new file mode 100644
index 0000000000..d6c2bc0405
--- /dev/null
+++ b/code/modules/mob/living/death.dm
@@ -0,0 +1,3 @@
+/mob/living/death()
+ clear_fullscreens()
+ . = ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index 5caf660670..8206475655 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -467,6 +467,7 @@ default behaviour is:
BITSET(hud_updateflag, LIFE_HUD)
failed_last_breath = 0 //So mobs that died of oxyloss don't revive and have perpetual out of breath.
+ reload_fullscreen()
return
@@ -637,26 +638,9 @@ default behaviour is:
/mob/living/proc/resist_grab()
var/resisting = 0
- for(var/obj/O in requests)
- requests.Remove(O)
- qdel(O)
- resisting++
for(var/obj/item/weapon/grab/G in grabbed_by)
resisting++
- switch(G.state)
- if(GRAB_PASSIVE)
- qdel(G)
- if(GRAB_AGGRESSIVE)
- //Not standing up makes it much harder to break, so it is easier to cuff someone who is down without forcing them into unconsciousness.
- //Otherwise, it's the same chance of breaking the grab as disarm.
- if(incapacitated(INCAPACITATION_KNOCKDOWN)? prob(15) : prob(60))
- visible_message("[src] has broken free of [G.assailant]'s grip!")
- qdel(G)
- if(GRAB_NECK)
- //If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun.
- if (((world.time - G.assailant.l_move_time < 30 || !stunned) && prob(15)) || prob(3))
- visible_message("[src] has broken free of [G.assailant]'s headlock!")
- qdel(G)
+ G.handle_resist()
if(resisting)
visible_message("[src] resists!")
@@ -675,6 +659,15 @@ default behaviour is:
return 0
return ..()
+//called when the mob receives a bright flash
+/mob/living/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
+ if(override_blindness_check || !(disabilities & BLIND))
+ overlay_fullscreen("flash", type)
+ spawn(25)
+ if(src)
+ clear_fullscreen("flash", 25)
+ return 1
+
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn
if(stat)
src << "You must be conscious to do this!"
@@ -682,7 +675,6 @@ default behaviour is:
if(lying)
src << "You can't vent crawl while you're stunned!"
return
-
var/special_fail_msg = cannot_use_vents()
if(special_fail_msg)
src << "[special_fail_msg]"
diff --git a/code/modules/mob/living/silicon/ai/life.dm b/code/modules/mob/living/silicon/ai/life.dm
index b5ddfcedd9..5c6b617a7b 100644
--- a/code/modules/mob/living/silicon/ai/life.dm
+++ b/code/modules/mob/living/silicon/ai/life.dm
@@ -56,18 +56,18 @@
if (aiRestorePowerRoutine==2)
src << "Alert cancelled. Power has been restored without our assistance."
aiRestorePowerRoutine = 0
- src.blind.layer = 0
+ clear_fullscreen("blind")
updateicon()
return
else if (aiRestorePowerRoutine==3)
src << "Alert cancelled. Power has been restored."
aiRestorePowerRoutine = 0
- src.blind.layer = 0
+ clear_fullscreen("blind")
updateicon()
return
else if (APU_power)
aiRestorePowerRoutine = 0
- src.blind.layer = 0
+ clear_fullscreen("blind")
updateicon()
return
else
@@ -79,9 +79,7 @@
//Blind the AI
updateicon()
- src.blind.screen_loc = ui_entire_screen
- if (src.blind.layer!=18)
- src.blind.layer = 18
+ overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
src.sight = src.sight&~SEE_TURFS
src.sight = src.sight&~SEE_MOBS
src.sight = src.sight&~SEE_OBJS
@@ -99,7 +97,7 @@
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
aiRestorePowerRoutine = 0
- src.blind.layer = 0
+ clear_fullscreen("blind")
return
src << "Fault confirmed: missing external power. Shutting down main control system to save power."
sleep(20)
@@ -129,7 +127,7 @@
if (!istype(T, /turf/space))
src << "Alert cancelled. Power has been restored without our assistance."
aiRestorePowerRoutine = 0
- src.blind.layer = 0 //This, too, is a fix to issue 603
+ clear_fullscreen("blind") //This, too, is a fix to issue 603
return
switch(PRP)
if (1) src << "APC located. Optimizing route to APC to avoid needless power waste."
diff --git a/code/modules/mob/living/silicon/ai/login.dm b/code/modules/mob/living/silicon/ai/login.dm
index 76625cdc3d..fa06162c31 100644
--- a/code/modules/mob/living/silicon/ai/login.dm
+++ b/code/modules/mob/living/silicon/ai/login.dm
@@ -2,19 +2,6 @@
..()
for(var/obj/effect/rune/rune in rune_list)
client.images += rune.blood_image
- regenerate_icons()
- flash = new /obj/screen()
- flash.icon_state = "blank"
- flash.name = "flash"
- flash.screen_loc = ui_entire_screen
- flash.layer = 17
- blind = new /obj/screen()
- blind.icon_state = "black"
- blind.name = " "
- blind.screen_loc = ui_entire_screen
- blind.layer = 0
- client.screen.Add( blind, flash )
-
if(stat != DEAD)
for(var/obj/machinery/ai_status_display/O in machines) //change status
O.mode = 1
diff --git a/code/modules/mob/living/silicon/robot/drone/drone.dm b/code/modules/mob/living/silicon/robot/drone/drone.dm
index 8c0ec04900..89f7942cc4 100644
--- a/code/modules/mob/living/silicon/robot/drone/drone.dm
+++ b/code/modules/mob/living/silicon/robot/drone/drone.dm
@@ -240,7 +240,7 @@ var/list/mob_hat_cache = list()
//Drones killed by damage will gib.
/mob/living/silicon/robot/drone/handle_regular_status_updates()
var/turf/T = get_turf(src)
- if((!T || health <= -35 || (master_fabricator && T.z != master_fabricator.z)) && src.stat != DEAD)
+ if(!T || health <= -35 )
timeofdeath = world.time
death() //Possibly redundant, having trouble making death() cooperate.
gib()
diff --git a/code/modules/mob/living/silicon/robot/life.dm b/code/modules/mob/living/silicon/robot/life.dm
index a44be64253..26fe14d7d1 100644
--- a/code/modules/mob/living/silicon/robot/life.dm
+++ b/code/modules/mob/living/silicon/robot/life.dm
@@ -275,29 +275,21 @@
// if (src.oxygen) src.oxygen.icon_state = "oxy[src.oxygen_alert ? 1 : 0]"
// if (src.fire) src.fire.icon_state = "fire[src.fire_alert ? 1 : 0]"
- client.screen.Remove(global_hud.blurry,global_hud.druggy,global_hud.vimpaired)
-
- if ((src.blind && src.stat != 2))
- if(src.blinded)
- src.blind.layer = 18
+ if(stat != 2)
+ if(blinded)
+ overlay_fullscreen("blind", /obj/screen/fullscreen/blind)
else
- src.blind.layer = 0
- if (src.disabilities & NEARSIGHTED)
- src.client.screen += global_hud.vimpaired
+ clear_fullscreen("blind")
+ set_fullscreen(disabilities & NEARSIGHTED, "impaired", /obj/screen/fullscreen/impaired, 1)
+ set_fullscreen(eye_blurry, "blurry", /obj/screen/fullscreen/blurry)
+ set_fullscreen(druggy, "high", /obj/screen/fullscreen/high)
- if (src.eye_blurry)
- src.client.screen += global_hud.blurry
-
- if (src.druggy)
- src.client.screen += global_hud.druggy
-
- if (src.stat != 2)
- if (src.machine)
- if (src.machine.check_eye(src) < 0)
- src.reset_view(null)
- else
- if(client && !client.adminobs)
- reset_view(null)
+ if (src.machine)
+ if (src.machine.check_eye(src) < 0)
+ src.reset_view(null)
+ else
+ if(client && !client.adminobs)
+ reset_view(null)
return 1
diff --git a/code/modules/mob/living/silicon/robot/robot_modules.dm b/code/modules/mob/living/silicon/robot/robot_modules.dm
index cd02dd71f4..0f5aa631e9 100644
--- a/code/modules/mob/living/silicon/robot/robot_modules.dm
+++ b/code/modules/mob/living/silicon/robot/robot_modules.dm
@@ -684,7 +684,7 @@ var/global/list/robot_modules = list(
hide_on_manifest = 1
sprites = list("Combat Android" = "droid-combat")
-/obj/item/weapon/robot_module/combat/New()
+/obj/item/weapon/robot_module/security/combat/New()
src.modules += new /obj/item/device/flash(src)
src.modules += new /obj/item/borg/sight/thermal(src)
src.modules += new /obj/item/weapon/gun/energy/laser/mounted(src)
diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm
index 5a13c7bb79..8a8bd0a274 100644
--- a/code/modules/mob/living/silicon/silicon.dm
+++ b/code/modules/mob/living/silicon/silicon.dm
@@ -67,7 +67,7 @@
if(2)
src.take_organ_damage(0,10,emp=1)
confused = (min(confused + 2, 30))
- flick("noise", src.flash)
+ flash_eyes(affect_silicon = 1)
src << "*BZZZT*"
src << "Warning: Electromagnetic pulse detected."
..()
@@ -264,7 +264,7 @@
/mob/living/silicon/ex_act(severity)
if(!blinded)
- flick("flash", flash)
+ flash_eyes()
switch(severity)
if(1.0)
@@ -361,3 +361,7 @@
..()
if(cameraFollow)
cameraFollow = null
+
+/mob/living/silicon/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
+ if(affect_silicon)
+ return ..()
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index a9d0e7b925..fbfd585b1a 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -381,7 +381,7 @@
/mob/living/simple_animal/ex_act(severity)
if(!blinded)
- flick("flash", flash)
+ flash_eyes()
switch (severity)
if (1.0)
adjustBruteLoss(500)
diff --git a/code/modules/mob/login.dm b/code/modules/mob/login.dm
index 07bc431b77..9a0fa7ba9b 100644
--- a/code/modules/mob/login.dm
+++ b/code/modules/mob/login.dm
@@ -45,6 +45,7 @@
else
client.eye = src
client.perspective = MOB_PERSPECTIVE
-
+ reload_fullscreen() // Reload any fullscreen overlays this mob has.
+ add_click_catcher()
//set macro to normal incase it was overriden (like cyborg currently does)
winset(src, null, "mainwindow.macro=macro hotkey_toggle.is-checked=false input.focus=true input.background-color=#D3B5B5")
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 8e80f31d0b..dcda999875 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -4,6 +4,7 @@
living_mob_list -= src
unset_machine()
qdel(hud_used)
+ clear_fullscreen()
if(client)
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
qdel(spell_master)
@@ -17,8 +18,6 @@
..()
/mob/proc/remove_screen_obj_references()
- flash = null
- blind = null
hands = null
pullin = null
purged = null
@@ -33,7 +32,6 @@
throw_icon = null
nutrition_icon = null
pressure = null
- damageoverlay = null
pain = null
item_use_icon = null
gun_move_icon = null
@@ -361,8 +359,8 @@
var/deathtimeseconds = round((deathtime - deathtimeminutes * 600) / 10,1)
usr << "You have been dead for[pluralcheck] [deathtimeseconds] seconds."
- if (deathtime < 600)
- usr << "You must wait 1 minute to respawn!"
+ if (deathtime < (5 * 600))
+ usr << "You must wait 5 minutes to respawn!"
return
else
usr << "You can respawn now, enjoy your new life!"
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index 8fc166930e..41394cc8da 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -10,8 +10,6 @@
//Not in use yet
var/obj/effect/organstructure/organStructure = null
- var/obj/screen/flash = null
- var/obj/screen/blind = null
var/obj/screen/hands = null
var/obj/screen/pullin = null
var/obj/screen/purged = null
@@ -26,7 +24,6 @@
var/obj/screen/throw_icon = null
var/obj/screen/nutrition_icon = null
var/obj/screen/pressure = null
- var/obj/screen/damageoverlay = null
var/obj/screen/pain = null
var/obj/screen/gun/item/item_use_icon = null
var/obj/screen/gun/radio/radio_use_icon = null
@@ -124,7 +121,6 @@
var/datum/hud/hud_used = null
var/list/grabbed_by = list( )
- var/list/requests = list( )
var/list/mapobjs = list()
diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm
index 47e0584740..e40b14dffd 100644
--- a/code/modules/mob/mob_grab.dm
+++ b/code/modules/mob/mob_grab.dm
@@ -3,10 +3,15 @@
///Process_Grab()
///Called by client/Move()
-///Checks to see if you are grabbing anything and if moving will affect your grab.
+///Checks to see if you are grabbing or being grabbed by anything and if moving will affect your grab.
/client/proc/Process_Grab()
- if(istype(mob, /mob/living))
+ //if we are being grabbed
+ if(isliving(mob))
var/mob/living/L = mob
+ if(!L.canmove && L.grabbed_by.len)
+ L.resist() //shortcut for resisting grabs
+
+ //if we are grabbing someone
for(var/obj/item/weapon/grab/G in list(L.l_hand, L.r_hand))
G.reset_kill_state() //no wandering across the station/asteroid while choking someone
@@ -131,7 +136,7 @@
handle_eye_mouth_covering(affecting, assailant, assailant.zone_sel.selecting)
if(force_down)
- if(affecting.loc != assailant.loc)
+ if(affecting.loc != assailant.loc || size_difference(affecting, assailant) > 0)
force_down = 0
else
affecting.Weaken(2)
@@ -232,7 +237,7 @@
if(state < GRAB_AGGRESSIVE)
if(!allow_upgrade)
return
- if(!affecting.lying)
+ if(!affecting.lying || size_difference(affecting, assailant) > 0)
assailant.visible_message("[assailant] has grabbed [affecting] aggressively (now hands)!")
else
assailant.visible_message("[assailant] pins [affecting] down to the ground (now hands)!")
@@ -335,6 +340,40 @@
hud.icon_state = "kill"
state = GRAB_NECK
+/obj/item/weapon/grab/proc/handle_resist()
+ var/grab_name
+ var/break_strength = 1
+ var/list/break_chance_table = list(100)
+ switch(state)
+ //if(GRAB_PASSIVE)
+
+ if(GRAB_AGGRESSIVE)
+ grab_name = "grip"
+ //Being knocked down makes it harder to break a grab, so it is easier to cuff someone who is down without forcing them into unconsciousness.
+ if(!affecting.incapacitated(INCAPACITATION_KNOCKDOWN))
+ break_strength++
+ break_chance_table = list(15, 60, 100)
+
+ if(GRAB_NECK)
+ grab_name = "headlock"
+ //If the you move when grabbing someone then it's easier for them to break free. Same if the affected mob is immune to stun.
+ if(world.time - assailant.l_move_time < 30 || !affecting.stunned)
+ break_strength++
+ break_chance_table = list(3, 18, 45, 100)
+
+ //It's easier to break out of a grab by a smaller mob
+ break_strength += max(size_difference(affecting, assailant), 0)
+
+ var/break_chance = break_chance_table[Clamp(break_strength, 1, break_chance_table.len)]
+ if(prob(break_chance))
+ if(grab_name)
+ affecting.visible_message("[affecting] has broken free of [assailant]'s [grab_name]!")
+ qdel(src)
+
+//returns the number of size categories between affecting and assailant, rounded. Positive means A is larger than B
+/obj/item/weapon/grab/proc/size_difference(mob/A, mob/B)
+ return mob_size_difference(A.mob_size, B.mob_size)
+
/obj/item/weapon/grab
var/destroying = 0
diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm
index 5158a7f3d0..e7b75a2e5d 100644
--- a/code/modules/mob/mob_grab_specials.dm
+++ b/code/modules/mob/mob_grab_specials.dm
@@ -51,10 +51,16 @@
return
attacker.visible_message("[attacker] [pick("bent", "twisted")] [target]'s [organ.name] into a jointlock!")
+
+ if(target.species.flags & NO_PAIN)
+ return
+
var/armor = target.run_armor_check(target, "melee")
if(armor < 60)
target << "You feel extreme pain!"
- affecting.adjustHalLoss(Clamp(0, 60-affecting.halloss, 30)) //up to 60 halloss
+
+ var/max_halloss = round(target.species.total_health * 0.8) //up to 80% of passing out
+ affecting.adjustHalLoss(Clamp(0, max_halloss - affecting.halloss, 30))
/obj/item/weapon/grab/proc/attack_eye(mob/living/carbon/human/target, mob/living/carbon/human/attacker)
if(!istype(attacker))
@@ -125,6 +131,10 @@
return
if(force_down)
attacker << "You are already pinning [target] to the ground."
+ return
+ if(size_difference(affecting, assailant) > 0)
+ attacker << "You are too small to do that!"
+ return
attacker.visible_message("[attacker] starts forcing [target] to the ground!")
if(do_after(attacker, 20) && target)
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index 5271034d2b..2f788862f8 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -5,6 +5,9 @@
return L.mob_size <= MOB_SMALL
return 0
+//returns the number of size categories between two mob_sizes, rounded. Positive means A is larger than B
+/proc/mob_size_difference(var/mob_size_A, var/mob_size_B)
+ return round(log(2, mob_size_A/mob_size_B), 1)
/proc/istiny(A)
if(A && istype(A, /mob/living))
@@ -570,4 +573,7 @@ var/list/global/organ_rel_size = list(
"r_hand" = 10,
"l_foot" = 10,
"r_foot" = 10,
-)
\ No newline at end of file
+)
+
+/mob/proc/flash_eyes(intensity = FLASH_PROTECTION_MODERATE, override_blindness_check = FALSE, affect_silicon = FALSE, visual = FALSE, type = /obj/screen/fullscreen/flash)
+ return
\ No newline at end of file
diff --git a/code/modules/organs/organ.dm b/code/modules/organs/organ.dm
index 13eef2eaf4..14842cb4f1 100644
--- a/code/modules/organs/organ.dm
+++ b/code/modules/organs/organ.dm
@@ -50,6 +50,7 @@ var/list/organ_cache = list()
max_damage = min_broken_damage * 2
if(istype(holder))
src.owner = holder
+ src.w_class = max(src.w_class + mob_size_difference(holder.mob_size, MOB_MEDIUM), 1) //smaller mobs have smaller organs.
species = all_species["Human"]
if(holder.dna)
dna = holder.dna.Clone()
@@ -258,6 +259,9 @@ var/list/organ_cache = list()
min_bruised_damage = 15
min_broken_damage = 35
+/obj/item/organ/proc/digitize() //Used to make the circuit-brain. On this level in the event more circuit-organs are added/tweaks are wanted.
+ robotize()
+
/obj/item/organ/emp_act(severity)
if(!(robotic >= ORGAN_ROBOT))
return
diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm
index a1a31fad7c..d3b309fd84 100644
--- a/code/modules/organs/organ_external.dm
+++ b/code/modules/organs/organ_external.dm
@@ -60,7 +60,7 @@
var/cannot_gib // Impossible to gib, distinct from amputation.
var/joint = "joint" // Descriptive string used in dislocation.
var/amputation_point // Descriptive string used in amputation.
- var/dislocated = 0 // If you target a joint, you can dislocate the limb, causing temporary damage to the organ.
+ var/dislocated = 0 // If you target a joint, you can dislocate the limb, impairing it's usefulness and causing pain
var/encased // Needs to be opened with a saw to access the organs.
// Surgery vars.
@@ -156,32 +156,38 @@
/obj/item/organ/external/proc/is_dislocated()
if(dislocated > 0)
return 1
- if(parent)
- return parent.is_dislocated()
+ if(is_parent_dislocated())
+ return 1//if any parent is dislocated, we are considered dislocated as well
return 0
-/obj/item/organ/external/proc/dislocate(var/primary)
- if(dislocated != -1)
- if(primary)
- dislocated = 2
- else
- dislocated = 1
- owner.verbs |= /mob/living/carbon/human/proc/undislocate
- if(children && children.len)
- for(var/obj/item/organ/external/child in children)
- child.dislocate()
+/obj/item/organ/external/proc/is_parent_dislocated()
+ var/obj/item/organ/external/O = parent
+ while(O && O.dislocated != -1)
+ if(O.dislocated == 1)
+ return 1
+ O = O.parent
+ return 0
+
+
+/obj/item/organ/external/proc/dislocate()
+ if(dislocated == -1)
+ return
+
+ dislocated = 1
+ if(owner)
+ owner.verbs |= /mob/living/carbon/human/proc/undislocate
/obj/item/organ/external/proc/undislocate()
- if(dislocated != -1)
- dislocated = 0
- if(children && children.len)
- for(var/obj/item/organ/external/child in children)
- if(child.dislocated == 1)
- child.undislocate()
+ if(dislocated == -1)
+ return
+
+ dislocated = 0
if(owner)
owner.shock_stage += 20
+
+ //check to see if we still need the verb
for(var/obj/item/organ/external/limb in owner.organs)
- if(limb.dislocated == 2)
+ if(limb.dislocated == 1)
return
owner.verbs -= /mob/living/carbon/human/proc/undislocate
@@ -1085,7 +1091,7 @@ Note that amputating the affected organ does in fact remove the infection from t
return 0
/obj/item/organ/external/proc/is_usable()
- return !is_dislocated() && !(status & (ORGAN_MUTATED|ORGAN_DEAD))
+ return !(status & (ORGAN_MUTATED|ORGAN_DEAD))
/obj/item/organ/external/proc/is_malfunctioning()
return ((robotic >= ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam))
diff --git a/code/modules/organs/robolimbs.dm b/code/modules/organs/robolimbs.dm
index 5241747f12..e1dac6efe9 100644
--- a/code/modules/organs/robolimbs.dm
+++ b/code/modules/organs/robolimbs.dm
@@ -43,6 +43,11 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
var/list/monitor_styles //If empty, the model of limbs offers a head compatible with monitors.
var/parts = BP_ALL //Defines what parts said brand can replace on a body.
+/datum/robolimb/nanotrasen
+ company = "NanoTrasen"
+ desc = "A simple but efficient robotic limb, created by NanoTrasen."
+ icon = 'icons/mob/human_races/cyberlimbs/nanotrasen/nanotrasen_main.dmi'
+
/datum/robolimb/bishop
company = "Bishop"
desc = "This limb has a white polymer casing with blue holo-displays."
@@ -191,6 +196,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
zenghu
company = "Zeng-Hu"
+ nanotrasen
+ company = "NanoTrasen"
+
/obj/item/weapon/disk/limb/New(var/newloc)
..()
if(company)
diff --git a/code/modules/organs/subtypes/diona.dm b/code/modules/organs/subtypes/diona.dm
index ab5c436758..0776e318b4 100644
--- a/code/modules/organs/subtypes/diona.dm
+++ b/code/modules/organs/subtypes/diona.dm
@@ -206,4 +206,5 @@
amputation_point = "branch"
joint = "structural ligament"
dislocated = -1
- vital = 0
\ No newline at end of file
+ vital = 0
+ slot_flags = SLOT_BELT
diff --git a/code/modules/organs/subtypes/machine.dm b/code/modules/organs/subtypes/machine.dm
index fc668621f1..2a1764ae58 100644
--- a/code/modules/organs/subtypes/machine.dm
+++ b/code/modules/organs/subtypes/machine.dm
@@ -85,9 +85,18 @@
/obj/item/organ/internal/mmi_holder/posibrain
name = "positronic brain interface"
brain_type = /obj/item/device/mmi/digital/posibrain
-
+
/obj/item/organ/internal/mmi_holder/posibrain/update_from_mmi()
..()
stored_mmi.icon_state = "posibrain-occupied"
+ icon_state = stored_mmi.icon_state
+
+/obj/item/organ/internal/mmi_holder/robot
+ name = "digital brain interface"
+ brain_type = /obj/item/device/mmi/digital/robot
+
+/obj/item/organ/internal/mmi_holder/robot/update_from_mmi()
+ ..()
+ stored_mmi.icon_state = "mainboard"
icon_state = stored_mmi.icon_state
\ No newline at end of file
diff --git a/code/modules/organs/subtypes/standard.dm b/code/modules/organs/subtypes/standard.dm
index 36fc7ba677..e33a319f69 100644
--- a/code/modules/organs/subtypes/standard.dm
+++ b/code/modules/organs/subtypes/standard.dm
@@ -2,6 +2,8 @@
ORGAN DEFINES
****************************************************/
+//Make sure that w_class is set as if the parent mob was medium sized! This is because w_class is adjusted automatically for mob_size in New()
+
/obj/item/organ/external/chest
name = "upper body"
organ_tag = BP_TORSO
@@ -148,6 +150,7 @@
organ_tag = BP_HEAD
icon_name = "head"
name = "head"
+ slot_flags = SLOT_BELT
max_damage = 75
min_broken_damage = 35
w_class = 3
diff --git a/code/modules/paperwork/faxmachine.dm b/code/modules/paperwork/faxmachine.dm
index b99833670d..8c30f1d486 100644
--- a/code/modules/paperwork/faxmachine.dm
+++ b/code/modules/paperwork/faxmachine.dm
@@ -32,54 +32,37 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
/obj/machinery/photocopier/faxmachine/attack_hand(mob/user as mob)
user.set_machine(src)
- var/dat = "Fax Machine
"
+ ui_interact(user)
- var/scan_name
+/**
+ * Display the NanoUI window for the fax machine.
+ *
+ * See NanoUI documentation for details.
+ */
+/obj/machinery/photocopier/faxmachine/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
+
+ var/list/data = list()
if(scan)
- scan_name = scan.name
+ data["scanName"] = scan.name
else
- scan_name = "--------"
-
- dat += "Confirm Identity: [scan_name]
"
-
- if(authenticated)
- dat += "{Log Out}"
+ data["scanName"] = null
+ data["bossName"] = boss_name
+ data["authenticated"] = authenticated
+ data["copyItem"] = copyitem
+ if(copyitem)
+ data["copyItemName"] = copyitem.name
else
- dat += "{Log In}"
+ data["copyItemName"] = null
+ data["cooldown"] = sendcooldown
+ data["destination"] = destination
- dat += "
"
-
- if(authenticated)
- dat += "Logged in to: [boss_name] Quantum Entanglement Network
"
-
- if(copyitem)
- dat += "Remove Item
"
-
- if(sendcooldown)
- dat += "Transmitter arrays realigning. Please stand by.
"
-
- else
-
- dat += "Send
"
- dat += "Currently sending: [copyitem.name]
"
- dat += "Sending to: [destination]
"
-
- else
- if(sendcooldown)
- dat += "Please insert paper to send via secure connection.
"
- dat += "Transmitter arrays realigning. Please stand by.
"
- else
- dat += "Please insert paper to send via secure connection.
"
-
- else
- dat += "Proper authentication is required to use this device.
"
-
- if(copyitem)
- dat += "Remove Item
"
-
- user << browse(dat, "window=copier")
- onclose(user, "copier")
- return
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "fax.tmpl", src.name, 500, 500)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(10) //this machine is so unimportant let's not have it update that often.
/obj/machinery/photocopier/faxmachine/Topic(href, href_list)
if(href_list["send"])
@@ -99,7 +82,6 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
usr.put_in_hands(copyitem)
usr << "You take \the [copyitem] out of \the [src]."
copyitem = null
- updateUsrDialog()
if(href_list["scan"])
if (scan)
@@ -131,7 +113,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
if(href_list["logout"])
authenticated = 0
- updateUsrDialog()
+ nanomanager.update_uis(src)
/obj/machinery/photocopier/faxmachine/proc/sendfax(var/destination)
if(stat & (BROKEN|NOPOWER))
@@ -158,7 +140,7 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
return 0 //You can't send faxes to "Unknown"
flick("faxreceive", src)
- playsound(loc, "sound/items/polaroid1.ogg", 50, 1)
+ playsound(loc, "sound/effects/printer.ogg", 50, 1)
// give the sprite some time to flick
sleep(20)
@@ -216,3 +198,4 @@ var/list/adminfaxes = list() //cache for faxes that have been sent to admins
for(var/client/C in admins)
if(R_ADMIN & C.holder.rights)
C << msg
+ C << 'sound/effects/printer.ogg'
diff --git a/code/modules/paperwork/photocopier.dm b/code/modules/paperwork/photocopier.dm
index d122d42c2b..ec0d7acf19 100644
--- a/code/modules/paperwork/photocopier.dm
+++ b/code/modules/paperwork/photocopier.dm
@@ -30,24 +30,32 @@
/obj/machinery/photocopier/attack_hand(mob/user as mob)
user.set_machine(src)
- var/dat = "Photocopier
"
- if(copyitem)
- dat += "Remove Item
"
- if(toner)
- dat += "Copy
"
- dat += "Printing: [copies] copies."
- dat += "- "
- dat += "+
"
- else if(toner)
- dat += "Please insert something to copy.
"
+ ui_interact(user)
+
+/**
+ * Display the NanoUI window for the photocopier.
+ *
+ * See NanoUI documentation for details.
+ */
+/obj/machinery/photocopier/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
+
+ var/list/data = list()
+ data["copyItem"] = copyitem
+ data["toner"] = toner
+ data["copies"] = copies
+ data["maxCopies"] = maxcopies
if(istype(user,/mob/living/silicon))
- dat += "Print photo from database
"
- dat += "Current toner level: [toner]"
- if(!toner)
- dat +="
Please insert a new toner cartridge!"
- user << browse(dat, "window=copier")
- onclose(user, "copier")
- return
+ data["isSilicon"] = 1
+ else
+ data["isSilicon"] = null
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "photocopier.tmpl", src.name, 300, 250)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(10)
/obj/machinery/photocopier/Topic(href, href_list)
if(href_list["copy"])
@@ -72,22 +80,18 @@
break
use_power(active_power_usage)
- updateUsrDialog()
else if(href_list["remove"])
if(copyitem)
copyitem.loc = usr.loc
usr.put_in_hands(copyitem)
usr << "You take \the [copyitem] out of \the [src]."
copyitem = null
- updateUsrDialog()
else if(href_list["min"])
if(copies > 1)
copies--
- updateUsrDialog()
else if(href_list["add"])
if(copies < maxcopies)
copies++
- updateUsrDialog()
else if(href_list["aipic"])
if(!istype(usr,/mob/living/silicon)) return
if(stat & (BROKEN|NOPOWER)) return
@@ -109,7 +113,8 @@
p.desc += " - Copied by [tempAI.name]"
toner -= 5
sleep(15)
- updateUsrDialog()
+
+ nanomanager.update_uis(src)
/obj/machinery/photocopier/attackby(obj/item/O as obj, mob/user as mob)
if(istype(O, /obj/item/weapon/paper) || istype(O, /obj/item/weapon/photo) || istype(O, /obj/item/weapon/paper_bundle))
@@ -119,7 +124,6 @@
O.loc = src
user << "You insert \the [O] into \the [src]."
flick(insert_anim, src)
- updateUsrDialog()
else
user << "There is already something in \the [src]."
else if(istype(O, /obj/item/device/toner))
@@ -129,7 +133,6 @@
var/obj/item/device/toner/T = O
toner += T.toner_amount
qdel(O)
- updateUsrDialog()
else
user << "This cartridge is not yet ready for replacement! Use up the rest of the toner."
else if(istype(O, /obj/item/weapon/wrench))
diff --git a/code/modules/projectiles/guns/energy/laser.dm b/code/modules/projectiles/guns/energy/laser.dm
index 9d0ba4e736..b8479581ae 100644
--- a/code/modules/projectiles/guns/energy/laser.dm
+++ b/code/modules/projectiles/guns/energy/laser.dm
@@ -68,13 +68,14 @@ obj/item/weapon/gun/energy/retro
fire_sound = 'sound/weapons/lasercannonfire.ogg'
origin_tech = list(TECH_COMBAT = 4, TECH_MATERIAL = 3, TECH_POWER = 3)
slot_flags = SLOT_BELT|SLOT_BACK
- projectile_type = /obj/item/projectile/beam/heavylaser
- charge_cost = 400
- max_shots = 6
- fire_delay = 20
+ projectile_type = /obj/item/projectile/beam/heavylaser/cannon
+ max_shots = 1
+ fire_delay = 30
// requires_two_hands = 1
one_handed_penalty = 6 // The thing's heavy and huge.
- accuracy = 2
+ accuracy = 3
+ charge_cost = 400
+
/obj/item/weapon/gun/energy/lasercannon/mounted
name = "mounted laser cannon"
@@ -83,6 +84,10 @@ obj/item/weapon/gun/energy/retro
recharge_time = 10
accuracy = 0 // Mounted cannons are just fine the way they are.
requires_two_hands = 0 // Not sure if two-handing gets checked for mounted weapons, but better safe than sorry.
+ projectile_type = /obj/item/projectile/beam/heavylaser
+ charge_cost = 400
+ max_shots = 6
+ fire_delay = 20
/obj/item/weapon/gun/energy/xray
name = "xray laser gun"
diff --git a/code/modules/projectiles/guns/projectile/sniper.dm b/code/modules/projectiles/guns/projectile/sniper.dm
index d69a97f2f4..d37410c589 100644
--- a/code/modules/projectiles/guns/projectile/sniper.dm
+++ b/code/modules/projectiles/guns/projectile/sniper.dm
@@ -10,15 +10,14 @@
slot_flags = SLOT_BACK
origin_tech = list(TECH_COMBAT = 8, TECH_MATERIAL = 2, TECH_ILLEGAL = 8)
caliber = "14.5mm"
- recoil = 3 //extra kickback
+ recoil = 5 //extra kickback
fire_sound = 'sound/weapons/sniper.ogg' // extra boom
handle_casings = HOLD_CASINGS
load_method = SINGLE_CASING
max_shells = 1
ammo_type = /obj/item/ammo_casing/a145
- //+2 accuracy over the LWAP because only one shot
- accuracy = -1
- scoped_accuracy = 2
+ accuracy = -5
+ scoped_accuracy = 5
var/bolt_open = 0
/obj/item/weapon/gun/projectile/heavysniper/update_icon()
diff --git a/code/modules/projectiles/projectile/beams.dm b/code/modules/projectiles/projectile/beams.dm
index f564b399ad..1049f5f70d 100644
--- a/code/modules/projectiles/projectile/beams.dm
+++ b/code/modules/projectiles/projectile/beams.dm
@@ -42,6 +42,10 @@
tracer_type = /obj/effect/projectile/laser_heavy/tracer
impact_type = /obj/effect/projectile/laser_heavy/impact
+/obj/item/projectile/beam/heavylaser/cannon
+ damage = 90
+ armor_penetration = 100
+
/obj/item/projectile/beam/xray
name = "xray beam"
icon_state = "xray"
diff --git a/code/modules/projectiles/projectile/energy.dm b/code/modules/projectiles/projectile/energy.dm
index 66155da7ea..80112690b3 100644
--- a/code/modules/projectiles/projectile/energy.dm
+++ b/code/modules/projectiles/projectile/energy.dm
@@ -23,7 +23,7 @@
//blind adjacent people
for (var/mob/living/carbon/M in viewers(T, flash_range))
if(M.eyecheck() < 1)
- flick("e_flash", M.flash)
+ M.flash_eyes()
//snap pop
playsound(src, 'sound/effects/snap.ogg', 50, 1)
@@ -80,7 +80,8 @@
icon_state = "toxin"
damage = 5
damage_type = TOX
- weaken = 5
+ agony = 120
+ check_armour = "energy"
/obj/item/projectile/energy/bolt
diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm
index 5c4dc8c169..38f558721e 100644
--- a/code/modules/reagents/Chemistry-Machinery.dm
+++ b/code/modules/reagents/Chemistry-Machinery.dm
@@ -2,7 +2,6 @@
#define LIQUID 2
#define GAS 3
-#define BOTTLE_SPRITES list("bottle-1", "bottle-2", "bottle-3", "bottle-4") //list of available bottle sprites
#define REAGENTS_PER_SHEET 20
@@ -23,10 +22,11 @@
var/condi = 0
var/useramount = 15 // Last used amount
var/pillamount = 10
- var/bottlesprite = "bottle-1" //yes, strings
+ var/bottlesprite = "1"
var/pillsprite = "1"
- var/client/has_sprites = list()
var/max_pill_count = 20
+ var/tab = "home"
+ var/analyze_data[0]
flags = OPENCONTAINER
/obj/machinery/chem_master/New()
@@ -56,7 +56,6 @@
user.drop_item()
B.loc = src
user << "You add the beaker to the machine!"
- src.updateUsrDialog()
icon_state = "mixer1"
else if(istype(B, /obj/item/weapon/storage/pill_bottle))
@@ -69,9 +68,74 @@
user.drop_item()
B.loc = src
user << "You add the pill bottle into the dispenser slot!"
- src.updateUsrDialog()
return
+/obj/machinery/chem_master/attack_hand(mob/user as mob)
+ if(stat & BROKEN)
+ return
+ user.set_machine(src)
+ ui_interact(user)
+
+/**
+ * Display the NanoUI window for the chem master.
+ *
+ * See NanoUI documentation for details.
+ */
+/obj/machinery/chem_master/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
+ user.set_machine(src)
+
+ var/list/data = list()
+ data["tab"] = tab
+ data["condi"] = condi
+
+ if(loaded_pill_bottle)
+ data["pillBottle"] = list("total" = loaded_pill_bottle.contents.len, "max" = loaded_pill_bottle.max_storage_space)
+ else
+ data["pillBottle"] = null
+
+ if(beaker)
+ var/datum/reagents/R = beaker:reagents
+ var/ui_reagent_beaker_list[0]
+ for(var/datum/reagent/G in R.reagent_list)
+ ui_reagent_beaker_list[++ui_reagent_beaker_list.len] = list("name" = G.name, "volume" = G.volume, "description" = G.description, "id" = G.id)
+
+ data["beaker"] = list("total_volume" = R.total_volume, "reagent_list" = ui_reagent_beaker_list)
+ else
+ data["beaker"] = null
+
+ if(reagents.total_volume)
+ var/ui_reagent_list[0]
+ for(var/datum/reagent/N in reagents.reagent_list)
+ ui_reagent_list[++ui_reagent_list.len] = list("name" = N.name, "volume" = N.volume, "description" = N.description, "id" = N.id)
+
+ data["reagents"] = list("total_volume" = reagents.total_volume, "reagent_list" = ui_reagent_list)
+ else
+ data["reagents"] = null
+
+ data["mode"] = mode
+
+ if(analyze_data)
+ data["analyzeData"] = list("name" = analyze_data["name"], "desc" = analyze_data["desc"], "blood_type" = analyze_data["blood_type"], "blood_DNA" = analyze_data["blood_DNA"])
+ else
+ data["analyzeData"] = null
+
+ data["pillSprite"] = pillsprite
+ data["bottleSprite"] = bottlesprite
+
+ var/P[20] //how many pill sprites there are. Sprites are taken from chemical.dmi and can be found in nano/images/pill.png
+ for(var/i = 1 to P.len)
+ P[i] = i
+ data["pillSpritesAmount"] = P
+
+ data["bottleSpritesAmount"] = list(1, 2, 3, 4) //how many bottle sprites there are. Sprites are taken from chemical.dmi and can be found in nano/images/pill.png
+
+ ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
+ if (!ui)
+ ui = new(user, src, ui_key, "chem_master.tmpl", src.name, 575, 400)
+ ui.set_initial_data(data)
+ ui.open()
+ ui.set_auto_update(5)
+
/obj/machinery/chem_master/Topic(href, href_list)
if(stat & (BROKEN|NOPOWER)) return
if(usr.stat || usr.restrained()) return
@@ -80,20 +144,19 @@
src.add_fingerprint(usr)
usr.set_machine(src)
+ if(href_list["tab_select"])
+ tab = href_list["tab_select"]
if (href_list["ejectp"])
if(loaded_pill_bottle)
loaded_pill_bottle.loc = src.loc
loaded_pill_bottle = null
- else if(href_list["close"])
- usr << browse(null, "window=chemmaster")
- usr.unset_machine()
- return
if(beaker)
var/datum/reagents/R = beaker:reagents
- if (href_list["analyze"])
- var/dat = ""
+ if (tab == "analyze")
+ analyze_data["name"] = href_list["name"]
+ analyze_data["desc"] = href_list["desc"]
if(!condi)
if(href_list["name"] == "Blood")
var/datum/reagent/blood/G
@@ -101,16 +164,9 @@
if(F.name == href_list["name"])
G = F
break
- var/A = G.name
- var/B = G.data["blood_type"]
- var/C = G.data["blood_DNA"]
- dat += "Chemmaster 3000Chemical infos:
Name:
[A]
Description:
Blood Type: [B]
DNA: [C]
(Back)"
- else
- dat += "Chemmaster 3000Chemical infos:
Name:
[href_list["name"]]
Description:
[href_list["desc"]]
(Back)"
- else
- dat += "Condimaster 3000Condiment infos:
Name:
[href_list["name"]]
Description:
[href_list["desc"]]
(Back)"
- usr << browse(dat, "window=chem_master;size=575x400")
- return
+ analyze_data["name"] = G.name
+ analyze_data["blood_type"] = G.data["blood_type"]
+ analyze_data["blood_DNA"] = G.data["blood_DNA"]
else if (href_list["add"])
@@ -147,9 +203,6 @@
else if (href_list["toggle"])
mode = !mode
- else if (href_list["main"])
- attack_hand(usr)
- return
else if (href_list["eject"])
if(beaker)
beaker:loc = src.loc
@@ -185,9 +238,8 @@
P.icon_state = "pill"+pillsprite
reagents.trans_to_obj(P,amount_per_pill)
if(src.loaded_pill_bottle)
- if(loaded_pill_bottle.contents.len < loaded_pill_bottle.storage_slots)
+ if(loaded_pill_bottle.contents.len < loaded_pill_bottle.max_storage_space)
P.loc = loaded_pill_bottle
- src.updateUsrDialog()
else if (href_list["createbottle"])
if(!condi)
@@ -197,106 +249,23 @@
P.name = "[name] bottle"
P.pixel_x = rand(-7, 7) //random position
P.pixel_y = rand(-7, 7)
- P.icon_state = bottlesprite
+ P.icon_state = "bottle-"+bottlesprite
reagents.trans_to_obj(P,60)
P.update_icon()
else
var/obj/item/weapon/reagent_containers/food/condiment/P = new/obj/item/weapon/reagent_containers/food/condiment(src.loc)
reagents.trans_to_obj(P,50)
- else if(href_list["change_pill"])
- #define MAX_PILL_SPRITE 20 //max icon state of the pill sprites
- var/dat = ""
- for(var/i = 1 to MAX_PILL_SPRITE)
- dat += " |
"
- dat += "
"
- usr << browse(dat, "window=chem_master")
- return
- else if(href_list["change_bottle"])
- var/dat = ""
- for(var/sprite in BOTTLE_SPRITES)
- dat += " |
"
- dat += "
"
- usr << browse(dat, "window=chem_master")
- return
+
else if(href_list["pill_sprite"])
pillsprite = href_list["pill_sprite"]
else if(href_list["bottle_sprite"])
bottlesprite = href_list["bottle_sprite"]
- src.updateUsrDialog()
- return
+ nanomanager.update_uis(src)
/obj/machinery/chem_master/attack_ai(mob/user as mob)
return src.attack_hand(user)
-/obj/machinery/chem_master/attack_hand(mob/user as mob)
- if(stat & BROKEN)
- return
- user.set_machine(src)
- if(!(user.client in has_sprites))
- spawn()
- has_sprites += user.client
- for(var/i = 1 to MAX_PILL_SPRITE)
- usr << browse_rsc(icon('icons/obj/chemical.dmi', "pill" + num2text(i)), "pill[i].png")
- for(var/sprite in BOTTLE_SPRITES)
- usr << browse_rsc(icon('icons/obj/chemical.dmi', sprite), "[sprite].png")
- var/dat = ""
- if(!beaker)
- dat = "Please insert beaker.
"
- if(src.loaded_pill_bottle)
- dat += "Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]
"
- else
- dat += "No pill bottle inserted.
"
- dat += "Close"
- else
- var/datum/reagents/R = beaker:reagents
- dat += "Eject beaker and Clear Buffer
"
- if(src.loaded_pill_bottle)
- dat += "Eject Pill Bottle \[[loaded_pill_bottle.contents.len]/[loaded_pill_bottle.storage_slots]\]
"
- else
- dat += "No pill bottle inserted.
"
- if(!R.total_volume)
- dat += "Beaker is empty."
- else
- dat += "Add to buffer:
"
- for(var/datum/reagent/G in R.reagent_list)
- dat += "[G.name] , [G.volume] Units - "
- dat += "(Analyze) "
- dat += "(1) "
- dat += "(5) "
- dat += "(10) "
- dat += "(30) "
- dat += "(60) "
- dat += "(All) "
- dat += "(Custom)
"
-
- dat += "
Transfer to [(!mode ? "disposal" : "beaker")]:
"
- if(reagents.total_volume)
- for(var/datum/reagent/N in reagents.reagent_list)
- dat += "[N.name] , [N.volume] Units - "
- dat += "(Analyze) "
- dat += "(1) "
- dat += "(5) "
- dat += "(10) "
- dat += "(30) "
- dat += "(60) "
- dat += "(All) "
- dat += "(Custom)
"
- else
- dat += "Empty
"
- if(!condi)
- dat += "
Create pill (60 units max)
"
- dat += "Create multiple pills
"
- dat += "Create bottle (60 units max)
"
- else
- dat += "Create bottle (50 units max)"
- if(!condi)
- user << browse("Chemmaster 3000Chemmaster menu:
[dat]", "window=chem_master;size=575x400")
- else
- user << browse("Condimaster 3000Condimaster menu:
[dat]", "window=chem_master;size=575x400")
- onclose(user, "chem_master")
- return
-
/obj/machinery/chem_master/condimaster
name = "CondiMaster 3000"
condi = 1
diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm
index e9c3df5098..a2938bb56d 100644
--- a/code/modules/reagents/Chemistry-Recipes.dm
+++ b/code/modules/reagents/Chemistry-Recipes.dm
@@ -622,7 +622,7 @@
if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses))
continue
- flick("e_flash", M.flash)
+ M.flash_eyes()
M.Weaken(15)
if(4 to 5)
@@ -630,7 +630,7 @@
if(istype(M:glasses, /obj/item/clothing/glasses/sunglasses))
continue
- flick("e_flash", M.flash)
+ M.flash_eyes()
M.Stun(5)
/datum/chemical_reaction/emp_pulse
@@ -1003,7 +1003,7 @@
if(holder.my_atom && istype(holder.my_atom, required))
return ..()
return 0
-
+
/datum/chemical_reaction/slime/golem
name = "Prometheans"
id = "m_promethean"
@@ -1016,7 +1016,7 @@
var/location = get_turf(holder.my_atom)
new /obj/item/slime_cube(location)
qdel(holder.my_atom)
-
+
/* Food */
/datum/chemical_reaction/tofu
@@ -1499,7 +1499,7 @@
name = "Allies Cocktail"
id = "alliescocktail"
result = "alliescocktail"
- required_reagents = list("classicmartini" = 1, "vodka" = 1)
+ required_reagents = list("martini" = 1, "vodka" = 1)
result_amount = 2
/datum/chemical_reaction/demonsblood
diff --git a/code/modules/reagents/reagent_containers/dropper.dm b/code/modules/reagents/reagent_containers/dropper.dm
index 36a8b40fef..ba671cdb50 100644
--- a/code/modules/reagents/reagent_containers/dropper.dm
+++ b/code/modules/reagents/reagent_containers/dropper.dm
@@ -12,8 +12,15 @@
slot_flags = SLOT_EARS
volume = 5
-/obj/item/weapon/reagent_containers/dropper/afterattack(var/obj/target, var/mob/user, var/flag)
- if(!target.reagents || !flag) return
+
+/obj/item/weapon/reagent_containers/dropper/do_surgery(mob/living/carbon/M, mob/living/user)
+ if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
+ return ..()
+ afterattack(M, user, 1)
+ return 1
+
+/obj/item/weapon/reagent_containers/dropper/afterattack(var/obj/target, var/mob/user, var/proximity)
+ if(!target.reagents || !proximity) return
if(reagents.total_volume)
diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm
index d189d194a7..e751d35d70 100644
--- a/code/modules/reagents/reagent_containers/food/snacks.dm
+++ b/code/modules/reagents/reagent_containers/food/snacks.dm
@@ -11,8 +11,14 @@
var/slices_num
var/dried_type = null
var/dry = 0
+ var/nutriment_amt = 0
center_of_mass = list("x"=16, "y"=16)
w_class = 2
+
+/obj/item/weapon/reagent_containers/food/snacks/New()
+ ..()
+ if(nutriment_amt)
+ reagents.add_reagent("nutriment", nutriment_amt)
//Placeholder for effect that trigger on eating that aren't tied to reagents.
/obj/item/weapon/reagent_containers/food/snacks/proc/On_Consume(var/mob/M)
diff --git a/code/modules/reagents/reagent_containers/glass.dm b/code/modules/reagents/reagent_containers/glass.dm
index 4eb927444e..d131cdf9c9 100644
--- a/code/modules/reagents/reagent_containers/glass.dm
+++ b/code/modules/reagents/reagent_containers/glass.dm
@@ -69,8 +69,15 @@
flags |= OPENCONTAINER
update_icon()
-/obj/item/weapon/reagent_containers/glass/afterattack(var/obj/target, var/mob/user, var/flag)
- if(!is_open_container() || !flag)
+/obj/item/weapon/reagent_containers/glass/do_surgery(mob/living/carbon/M, mob/living/user)
+ if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
+ return ..()
+ afterattack(M, user, 1)
+ return 1
+
+/obj/item/weapon/reagent_containers/glass/afterattack(var/obj/target, var/mob/user, var/proximity)
+
+ if(!is_open_container() || !proximity)
return
for(var/type in can_be_placed_into)
diff --git a/code/modules/reagents/reagent_containers/hypospray.dm b/code/modules/reagents/reagent_containers/hypospray.dm
index 884afc5ed8..771ce4cc27 100644
--- a/code/modules/reagents/reagent_containers/hypospray.dm
+++ b/code/modules/reagents/reagent_containers/hypospray.dm
@@ -20,6 +20,12 @@
// reagents.add_reagent("tricordrazine", 30)
// return
+/obj/item/weapon/reagent_containers/hypospray/do_surgery(mob/living/carbon/M, mob/living/user)
+ if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
+ return ..()
+ attack(M, user)
+ return 1
+
/obj/item/weapon/reagent_containers/hypospray/attack(mob/living/M as mob, mob/user as mob)
if(!reagents.total_volume)
user << "[src] is empty."
diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm
index 09ae98eb90..87b5311be2 100644
--- a/code/modules/reagents/reagent_containers/syringes.dm
+++ b/code/modules/reagents/reagent_containers/syringes.dm
@@ -52,6 +52,14 @@
/obj/item/weapon/reagent_containers/syringe/attackby(obj/item/I as obj, mob/user as mob)
return
+/obj/item/weapon/reagent_containers/syringe/do_surgery(mob/living/carbon/M, mob/living/user)
+ if(user.a_intent == I_HURT)
+ return 0
+ if(user.a_intent != I_HELP) //in case it is ever used as a surgery tool
+ return ..()
+ afterattack(M, user, 1)
+ return 1
+
/obj/item/weapon/reagent_containers/syringe/afterattack(obj/target, mob/user, proximity)
if(!proximity || !target.reagents)
return
@@ -66,7 +74,6 @@
syringestab(target, user)
return
-
switch(mode)
if(SYRINGE_DRAW)
diff --git a/code/modules/spells/targeted/equip/horsemask.dm b/code/modules/spells/targeted/equip/horsemask.dm
index 92b85fdb36..c52f75acee 100644
--- a/code/modules/spells/targeted/equip/horsemask.dm
+++ b/code/modules/spells/targeted/equip/horsemask.dm
@@ -26,7 +26,7 @@
for(var/mob/living/target in targets)
target.visible_message( "[target]'s face lights up in fire, and after the event a horse's head takes its place!", \
"Your face burns up, and shortly after the fire you realise you have the face of a horse!")
- flick("e_flash", target.flash)
+ target.flash_eyes()
/spell/targeted/equip_item/horsemask/summon_item(var/new_type)
var/obj/item/new_item = new new_type
diff --git a/code/modules/surgery/other.dm b/code/modules/surgery/other.dm
index 82c6ad543c..d0ba959111 100644
--- a/code/modules/surgery/other.dm
+++ b/code/modules/surgery/other.dm
@@ -149,6 +149,7 @@
if(container.reagents.has_reagent("peridaxon"))
affected.status &= ~ORGAN_DEAD
+ affected.owner.update_body(1)
user.visible_message("\blue [user] applies [trans] units of the solution to affected tissue in [target]'s [affected.name]", \
"\blue You apply [trans] units of the solution to affected tissue in [target]'s [affected.name] with \the [tool].")
diff --git a/code/modules/surgery/robotics.dm b/code/modules/surgery/robotics.dm
index 6635753ed9..bede5263e2 100644
--- a/code/modules/surgery/robotics.dm
+++ b/code/modules/surgery/robotics.dm
@@ -166,15 +166,18 @@
if(..())
var/obj/item/stack/cable_coil/C = tool
var/obj/item/organ/external/affected = target.get_organ(target_zone)
- var/limb_can_operate = ((affected && affected.open >= 3) && (affected.disfigured || affected.burn_dam > 0) && target_zone != O_MOUTH)
- if(limb_can_operate)
- if(istype(C))
- if(!C.get_amount() >= 3)
- user << "You need three or more cable pieces to repair this damage."
- return SURGERY_FAILURE
- C.use(3)
- return 1
- return SURGERY_FAILURE
+
+ var/limb_can_operate = (affected && affected.open == 2 && affected.burn_dam > 0 && target_zone != "mouth")
+
+ if(!limb_can_operate)
+ return 0
+
+ if(istype(C))
+ if(!C.can_use(10))
+ user << "You need ten or more cable pieces to repair this damage." //usage amount made more consistent with regular cable repair
+ return SURGERY_FAILURE
+ C.use(10)
+ return 1
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
var/obj/item/organ/external/affected = target.get_organ(target_zone)
diff --git a/code/modules/surgery/surgery.dm b/code/modules/surgery/surgery.dm
index cc56b311b5..109da96b69 100644
--- a/code/modules/surgery/surgery.dm
+++ b/code/modules/surgery/surgery.dm
@@ -68,7 +68,7 @@
proc/fail_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
return null
-proc/spread_germs_to_organ(var/obj/item/organ/external/E, var/mob/living/carbon/human/user)
+/proc/spread_germs_to_organ(var/obj/item/organ/external/E, var/mob/living/carbon/human/user)
if(!istype(user) || !istype(E)) return
var/germ_level = user.germ_level
@@ -77,7 +77,7 @@ proc/spread_germs_to_organ(var/obj/item/organ/external/E, var/mob/living/carbon/
E.germ_level = max(germ_level,E.germ_level) //as funny as scrubbing microbes out with clean gloves is - no.
-proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
+/obj/item/proc/do_surgery(mob/living/carbon/M, mob/living/user)
if(!istype(M))
return 0
if (user.a_intent == I_HURT) //check for Hippocratic Oath
@@ -88,18 +88,18 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
return 1
for(var/datum/surgery_step/S in surgery_steps)
//check if tool is right or close enough and if this step is possible
- if(S.tool_quality(tool))
- var/step_is_valid = S.can_use(user, M, zone, tool)
+ if(S.tool_quality(src))
+ var/step_is_valid = S.can_use(user, M, zone, src)
if(step_is_valid && S.is_valid_target(M))
if(step_is_valid == SURGERY_FAILURE) // This is a failure that already has a message for failing.
return 1
M.op_stage.in_progress += zone
- S.begin_step(user, M, zone, tool) //start on it
+ S.begin_step(user, M, zone, src) //start on it
//We had proper tools! (or RNG smiled.) and user did not move or change hands.
- if(prob(S.tool_quality(tool)) && do_mob(user, M, rand(S.min_duration, S.max_duration)))
- S.end_step(user, M, zone, tool) //finish successfully
- else if ((tool in user.contents) && user.Adjacent(M)) //or
- S.fail_step(user, M, zone, tool) //malpractice~
+ if(prob(S.tool_quality(src)) && do_mob(user, M, rand(S.min_duration, S.max_duration)))
+ S.end_step(user, M, zone, src) //finish successfully
+ else if ((src in user.contents) && user.Adjacent(M)) //or
+ S.fail_step(user, M, zone, src) //malpractice~
else // This failing silently was a pain.
user << "You must remain close to your patient to conduct surgery."
M.op_stage.in_progress -= zone // Clear the in-progress flag.
@@ -109,11 +109,11 @@ proc/do_surgery(mob/living/carbon/M, mob/living/user, obj/item/tool)
return 1 //don't want to do weapony things after surgery
if (user.a_intent == I_HELP)
- user << "You can't see any useful way to use [tool] on [M]."
+ user << "You can't see any useful way to use [src] on [M]."
return 1
return 0
-proc/sort_surgeries()
+/proc/sort_surgeries()
var/gap = surgery_steps.len
var/swapped = 1
while (gap > 1 || swapped)
diff --git a/code/world.dm b/code/world.dm
index a6d27a8850..e0cb55b849 100644
--- a/code/world.dm
+++ b/code/world.dm
@@ -24,6 +24,8 @@ var/global/datum/global_init/init = new ()
qdel(src) //we're done
+/datum/global_init/Destroy()
+ return 1
/world
mob = /mob/new_player
diff --git a/config/example/config.txt b/config/example/config.txt
index ae99ec3d19..7c79624ef8 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -76,6 +76,8 @@ SQL_ENABLED
## disconnect players who did nothing during the set amount of minutes
# KICK_INACTIVE 10
+##Show developers on staffwho
+SHOW_DEVS
##Show mods on staffwho
SHOW_MODS
diff --git a/html/changelog.html b/html/changelog.html
index d292d520ff..60e522a07a 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -53,6 +53,58 @@
-->
+
01 July 2016
+
Aztectornado updated:
+
+ - Clicking a stack of sheets (Metal, phoron...) in your other hand now asks how many you want to split off the stack, courtesy of Baycode
+
+
Datraen updated:
+
+ - Antagonistic factions can now be set and viewed on the uplink. Visibilities can be set for these as well, to help identify sympathizers/potential aids, or to hide the information from those outside of your faction.
+
+
Yosh updated:
+
+ - Increases max records and book length to ridiculous levels.
+
+
Yoshax updated:
+
+ - The PTR Sniper is now more accurate when scoped, but less accurate when unscoped. In addition it now has more recoil.
+ - The Laser Cannon no longer holds multiple shots. It holds charge for one shot at a time. This is because the beams it fires now do 90 damage with 100 armor penetration. Furthermore, it is now considerably more accurate. Lastly, to counteract it only holding one shot at a time, it now autorecharges, which takes 60 seconds.
+
+
Zuhayr updated:
+
+ - Ports/adapted several kitchen machines from Apollo Station.
+
+
+
27 June 2016
+
Sin4 updated:
+
+ - Added NanoUI for Advanced Body Scanners, Arcade, Atmospherics Control Computer, Chemmaster, Cloning Console, Fax Machines, Guestpass Console, Holodeck Computer, Laptop Vendors, Operating Computer, and Photocopiers.
+ - Fixes chemmaster not putting pills in pill bottles.
+
+
+
21 June 2016
+
HarpyEagle updated:
+
+ - Fixes disarm-attack dislocation chances being so low that you were very likely to break the targeted limb before it would dislocate.
+ - It is now possible to disarm-attack with stunbatons like with other melee weapons. Note that this means that using a stunbaton on disarm intent will hurt people.
+ - Trying to move while being grabbed will now automatically resist.
+ - Small mobs are no longer able to pin larger mobs.
+ - Resisting a smaller mob's grab is more likely to be successful.
+ - Fixed being able to climb onto a larger mob while restrained, weakened, unconscious, or dead.
+
+
JerTheAce updated:
+
+ - CentCom Fax, Admin Prayer, and CentCom emergency messages now prompt admins with a pleasing sound effect.
+ - Fax machines now sound like fax machines and not polaroid cameras.
+
+
+
15 June 2016
+
Yoshax updated:
+
+ - The categories for items in the cargo ordering console have been reworked. Items shoulw now be in more sensible categories. If you cannot find something, try the sensible category.
+
+
14 June 2016
Arokha updated:
diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml
index 0ab77df4c5..b619283220 100644
--- a/html/changelogs/.all_changelog.yml
+++ b/html/changelogs/.all_changelog.yml
@@ -2419,3 +2419,50 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py.
it be fizzy or have ice floating in it.
Yoshax:
- tweak: Everything produced in Robotics is now 25% cheaper to produce.
+2016-06-15:
+ Yoshax:
+ - tweak: The categories for items in the cargo ordering console have been reworked.
+ Items shoulw now be in more sensible categories. If you cannot find something,
+ try the sensible category.
+2016-06-21:
+ HarpyEagle:
+ - bugfix: Fixes disarm-attack dislocation chances being so low that you were very
+ likely to break the targeted limb before it would dislocate.
+ - bugfix: It is now possible to disarm-attack with stunbatons like with other melee
+ weapons. Note that this means that using a stunbaton on disarm intent will hurt
+ people.
+ - rscadd: Trying to move while being grabbed will now automatically resist.
+ - tweak: Small mobs are no longer able to pin larger mobs.
+ - tweak: Resisting a smaller mob's grab is more likely to be successful.
+ - bugfix: Fixed being able to climb onto a larger mob while restrained, weakened,
+ unconscious, or dead.
+ JerTheAce:
+ - rscadd: CentCom Fax, Admin Prayer, and CentCom emergency messages now prompt admins
+ with a pleasing sound effect.
+ - tweak: Fax machines now sound like fax machines and not polaroid cameras.
+2016-06-27:
+ Sin4:
+ - rscadd: Added NanoUI for Advanced Body Scanners, Arcade, Atmospherics Control
+ Computer, Chemmaster, Cloning Console, Fax Machines, Guestpass Console, Holodeck
+ Computer, Laptop Vendors, Operating Computer, and Photocopiers.
+ - bugfix: Fixes chemmaster not putting pills in pill bottles.
+2016-07-01:
+ Aztectornado:
+ - tweak: Clicking a stack of sheets (Metal, phoron...) in your other hand now asks
+ how many you want to split off the stack, courtesy of Baycode
+ Datraen:
+ - rscadd: Antagonistic factions can now be set and viewed on the uplink. Visibilities
+ can be set for these as well, to help identify sympathizers/potential aids,
+ or to hide the information from those outside of your faction.
+ Yosh:
+ - tweaks: Increases max records and book length to ridiculous levels.
+ Yoshax:
+ - tweak: The PTR Sniper is now more accurate when scoped, but less accurate when
+ unscoped. In addition it now has more recoil.
+ - tweak: The Laser Cannon no longer holds multiple shots. It holds charge for one
+ shot at a time. This is because the beams it fires now do 90 damage with 100
+ armor penetration. Furthermore, it is now considerably more accurate. Lastly,
+ to counteract it only holding one shot at a time, it now autorecharges, which
+ takes 60 seconds.
+ Zuhayr:
+ - rscadd: Ports/adapted several kitchen machines from Apollo Station.
diff --git a/html/changelogs/Yoshax - supply.txt b/html/changelogs/Yoshax - supply.txt
deleted file mode 100644
index 93d5a9df08..0000000000
--- a/html/changelogs/Yoshax - supply.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-################################
-# Example Changelog File
-#
-# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
-#
-# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
-# When it is, any changes listed below will disappear.
-#
-# Valid Prefixes:
-# bugfix
-# wip (For works in progress)
-# tweak
-# soundadd
-# sounddel
-# rscadd (general adding of nice things)
-# rscdel (general deleting of nice things)
-# imageadd
-# imagedel
-# maptweak
-# spellcheck (typo fixes)
-# experiment
-#################################
-
-# Your name.
-author: Yoshax
-
-# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
-delete-after: True
-
-# Any changes you've made. See valid prefix list above.
-# INDENT WITH TWO SPACES. NOT TABS. SPACES.
-# SCREW THIS UP AND IT WON'T WORK.
-# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
-# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
-changes:
- - tweak: "The categories for items in the cargo ordering console have been reworked. Items shoulw now be in more sensible categories. If you cannot find something, try the sensible category."
diff --git a/icons/misc/buildmode.dmi b/icons/misc/buildmode.dmi
index a9374db340..c294178f91 100644
Binary files a/icons/misc/buildmode.dmi and b/icons/misc/buildmode.dmi differ
diff --git a/icons/mob/hands.dmi b/icons/mob/hands.dmi
index 0fbebc0d3d..5d9dbd7ca9 100644
Binary files a/icons/mob/hands.dmi and b/icons/mob/hands.dmi differ
diff --git a/icons/mob/human_races/cyberlimbs/morpheus/morpheus_main.dmi b/icons/mob/human_races/cyberlimbs/morpheus/morpheus_main.dmi
index e1e948f5b5..5c466d63ed 100644
Binary files a/icons/mob/human_races/cyberlimbs/morpheus/morpheus_main.dmi and b/icons/mob/human_races/cyberlimbs/morpheus/morpheus_main.dmi differ
diff --git a/icons/mob/human_races/cyberlimbs/nanotrasen/nanotrasen_main.dmi b/icons/mob/human_races/cyberlimbs/nanotrasen/nanotrasen_main.dmi
new file mode 100644
index 0000000000..66a871d1b0
Binary files /dev/null and b/icons/mob/human_races/cyberlimbs/nanotrasen/nanotrasen_main.dmi differ
diff --git a/icons/mob/screen1_robot.dmi b/icons/mob/screen1_robot.dmi
index ad0ac4fd77..ef3965f8ee 100644
Binary files a/icons/mob/screen1_robot.dmi and b/icons/mob/screen1_robot.dmi differ
diff --git a/icons/mob/screen_full.dmi b/icons/mob/screen_full.dmi
new file mode 100644
index 0000000000..e84b054695
Binary files /dev/null and b/icons/mob/screen_full.dmi differ
diff --git a/icons/mob/screen_gen.dmi b/icons/mob/screen_gen.dmi
new file mode 100644
index 0000000000..cf74d73796
Binary files /dev/null and b/icons/mob/screen_gen.dmi differ
diff --git a/icons/mob/species/seromi/head.dmi b/icons/mob/species/seromi/head.dmi
index 7305a6e216..57c4f11713 100644
Binary files a/icons/mob/species/seromi/head.dmi and b/icons/mob/species/seromi/head.dmi differ
diff --git a/icons/mob/species/seromi/suit.dmi b/icons/mob/species/seromi/suit.dmi
index 693565171c..f74326df98 100644
Binary files a/icons/mob/species/seromi/suit.dmi and b/icons/mob/species/seromi/suit.dmi differ
diff --git a/icons/mob/species/seromi/ties.dmi b/icons/mob/species/seromi/ties.dmi
new file mode 100644
index 0000000000..de7bc664e8
Binary files /dev/null and b/icons/mob/species/seromi/ties.dmi differ
diff --git a/icons/obj/clothing/gloves.dmi b/icons/obj/clothing/gloves.dmi
index fa521d772d..fe78cc348d 100644
Binary files a/icons/obj/clothing/gloves.dmi and b/icons/obj/clothing/gloves.dmi differ
diff --git a/icons/obj/cooking_machines.dmi b/icons/obj/cooking_machines.dmi
new file mode 100644
index 0000000000..666a31b9d0
Binary files /dev/null and b/icons/obj/cooking_machines.dmi differ
diff --git a/icons/obj/dice.dmi b/icons/obj/dice.dmi
index 669ad215c5..f6a209b468 100644
Binary files a/icons/obj/dice.dmi and b/icons/obj/dice.dmi differ
diff --git a/icons/obj/food.dmi b/icons/obj/food.dmi
index 7354bd311b..23a94746ac 100644
Binary files a/icons/obj/food.dmi and b/icons/obj/food.dmi differ
diff --git a/icons/obj/food_custom.dmi b/icons/obj/food_custom.dmi
new file mode 100644
index 0000000000..39491d65f5
Binary files /dev/null and b/icons/obj/food_custom.dmi differ
diff --git a/icons/obj/kitchen.dmi b/icons/obj/kitchen.dmi
index 1a9d80bb13..c3d5491a7c 100644
Binary files a/icons/obj/kitchen.dmi and b/icons/obj/kitchen.dmi differ
diff --git a/icons/turf/overlays.dmi b/icons/turf/overlays.dmi
index a96f6b14bc..d4dae7101a 100644
Binary files a/icons/turf/overlays.dmi and b/icons/turf/overlays.dmi differ
diff --git a/icons/turf/snow.dmi b/icons/turf/snow.dmi
index 5871cbdfc6..8f13ef9107 100644
Binary files a/icons/turf/snow.dmi and b/icons/turf/snow.dmi differ
diff --git a/icons/turf/snow_new.dmi b/icons/turf/snow_new.dmi
new file mode 100644
index 0000000000..8a95c14bed
Binary files /dev/null and b/icons/turf/snow_new.dmi differ
diff --git a/maps/polaris-1.dmm b/maps/polaris-1.dmm
index fe5ad28a22..3a22e5f4ff 100644
--- a/maps/polaris-1.dmm
+++ b/maps/polaris-1.dmm
@@ -1257,7 +1257,7 @@
"ayi" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/machinery/camera/network/northern_star{c_tag = "Hall - Chapel Access Port"; dir = 2},/turf/simulated/floor/tiled,/area/hallway/secondary/chapel_hallway)
"ayj" = (/obj/structure/closet/secure_closet/medical3,/obj/effect/floor_decal/corner/paleblue{dir = 5},/obj/item/weapon/soap/nanotrasen,/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage)
"ayk" = (/obj/structure/closet/secure_closet/medical3,/obj/structure/extinguisher_cabinet{pixel_x = -5; pixel_y = 30},/obj/effect/floor_decal/corner/paleblue/full{dir = 1},/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/obj/item/weapon/soap/nanotrasen,/turf/simulated/floor/tiled/white,/area/medical/medbay_primary_storage)
-"ayl" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/packageWrap,/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/dropper,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
+"ayl" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/reagentgrinder,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"aym" = (/turf/simulated/floor/tiled,/area/hallway/secondary/chapel_hallway)
"ayn" = (/obj/structure/closet/chefcloset,/obj/item/glass_jar,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/device/retail_scanner/civilian,/obj/item/weapon/soap/nanotrasen,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"ayo" = (/obj/structure/table/standard,/obj/item/weapon/soap/nanotrasen,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_5)
@@ -1328,6 +1328,8 @@
"azB" = (/obj/structure/table/standard,/obj/item/weapon/soap/nanotrasen,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_7)
"azC" = (/obj/structure/table/standard,/obj/item/weapon/soap/nanotrasen,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_8)
"azD" = (/obj/machinery/light_switch{pixel_x = 0; pixel_y = -27},/obj/machinery/light_switch{pixel_x = 0; pixel_y = -27},/obj/structure/table/standard,/obj/structure/bedsheetbin,/obj/machinery/light{icon_state = "tube1"; dir = 8},/obj/item/weapon/soap/nanotrasen,/turf/simulated/floor/tiled/freezer,/area/crew_quarters/sleep/engi_wash)
+"azE" = (/obj/structure/bed/double/padded,/obj/item/weapon/bedsheet/doublebrown,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
+"azF" = (/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/obj/structure/bed/double/padded,/obj/item/weapon/bedsheet/doublebrown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_6)
"azG" = (/turf/space,/area/syndicate_station/northwest)
"azH" = (/turf/simulated/floor/tiled,/area/security/security_equiptment_storage)
"azI" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/tiled,/area/security/security_equiptment_storage)
@@ -1351,6 +1353,7 @@
"aAa" = (/obj/machinery/atmospherics/valve,/turf/simulated/floor,/area/security/riot_control)
"aAb" = (/turf/simulated/floor,/area/security/riot_control)
"aAc" = (/obj/effect/floor_decal/industrial/warning{dir = 6},/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/turf/simulated/floor,/area/security/riot_control)
+"aAd" = (/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/obj/structure/bed/double/padded,/obj/item/weapon/bedsheet/doublebrown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_11)
"aAe" = (/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "security_lockdown"; name = "Security Blast Door"; opacity = 0},/turf/simulated/floor,/area/maintenance/security_starboard)
"aAf" = (/obj/effect/floor_decal/industrial/warning{dir = 8},/turf/simulated/floor,/area/maintenance/security_starboard)
"aAg" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor,/area/maintenance/security_starboard)
@@ -1376,7 +1379,14 @@
"aAA" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/chapel_hallway)
"aAB" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/light,/turf/simulated/floor/tiled,/area/hallway/secondary/chapel_hallway)
"aAC" = (/obj/structure/disposalpipe/segment{dir = 4},/obj/machinery/alarm{dir = 1; pixel_y = -22},/turf/simulated/floor/tiled,/area/hallway/secondary/chapel_hallway)
+"aAD" = (/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/obj/structure/bed/double/padded,/obj/item/weapon/bedsheet/doublebrown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_12)
+"aAE" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
+"aAF" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_6)
+"aAG" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_11)
+"aAH" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_12)
+"aAI" = (/obj/machinery/camera/network/civilian{c_tag = "CIV - Visitor Room 5"; dir = 1},/obj/structure/bed/chair/comfy/beige{dir = 8},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"aAJ" = (/obj/effect/decal/cleanable/dirt,/turf/simulated/floor,/area/maintenance/chapel)
+"aAK" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = 0; pixel_y = -32},/obj/structure/table/standard,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"aAL" = (/turf/simulated/wall/r_wall,/area/security/armoury)
"aAM" = (/obj/structure/closet/bombclosetsecurity,/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced,/turf/simulated/floor/tiled,/area/security/security_equiptment_storage)
"aAN" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/security_equiptment_storage)
@@ -1583,6 +1593,7 @@
"aEG" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/obj/structure/disposalpipe/segment{dir = 1; icon_state = "pipe-c"},/obj/effect/floor_decal/industrial/warning/corner{dir = 4},/turf/simulated/floor/tiled,/area/hallway/secondary/escape/medical_escape_pod_hallway)
"aEH" = (/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/table/rack,/obj/machinery/door/window/brigdoor/northleft{name = "Weapons locker"; req_access = list(2)},/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/window/reinforced{dir = 8},/obj/item/weapon/gun/projectile/colt/detective,/obj/item/weapon/gun/projectile/colt/detective,/obj/item/weapon/gun/projectile/colt/detective,/obj/item/weapon/gun/projectile/colt/detective,/turf/simulated/floor/tiled,/area/security/security_equiptment_storage)
"aEI" = (/obj/machinery/disposal,/obj/machinery/alarm{dir = 4; icon_state = "alarm0"; pixel_x = -22},/obj/structure/disposalpipe/trunk,/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled/dark,/area/security/warden)
+"aEJ" = (/obj/structure/table/standard,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3)
"aEK" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/plating,/area/security/security_equiptment_storage)
"aEL" = (/obj/machinery/computer/security{pixel_y = 0},/obj/effect/floor_decal/industrial/outline/grey,/turf/simulated/floor/tiled/dark,/area/security/warden)
"aEM" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/warden)
@@ -1622,7 +1633,9 @@
"aFu" = (/obj/structure/flora/pottedplant{icon_state = "plant-22"},/turf/simulated/floor/carpet,/area/crew_quarters/recreation_area)
"aFv" = (/obj/item/device/radio/intercom{dir = 1; name = "Station Intercom (General)"; pixel_y = 21},/turf/simulated/floor/carpet,/area/crew_quarters/recreation_area)
"aFw" = (/obj/machinery/computer/arcade,/turf/simulated/floor/carpet,/area/crew_quarters/recreation_area)
+"aFx" = (/obj/structure/table/standard,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_4)
"aFy" = (/obj/structure/table/woodentable,/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/item/device/paicard,/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/turf/simulated/floor/carpet,/area/crew_quarters/recreation_area)
+"aFz" = (/obj/structure/table/standard,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_9)
"aFA" = (/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/carpet,/area/crew_quarters/recreation_area)
"aFB" = (/obj/structure/closet/athletic_mixed,/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool)
"aFC" = (/obj/item/weapon/stool/padded,/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool)
@@ -1640,6 +1653,7 @@
"aFO" = (/obj/machinery/door/blast/regular{id = "Armoury"; name = "Emergency Access"},/turf/simulated/floor/tiled,/area/security/armoury)
"aFP" = (/obj/effect/floor_decal/industrial/warning{dir = 5},/turf/simulated/floor/tiled,/area/security/brig)
"aFQ" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled,/area/security/brig)
+"aFR" = (/obj/structure/table/standard,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_10)
"aFS" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/door/firedoor/border_only,/obj/structure/disposalpipe/segment,/turf/simulated/floor/plating,/area/security/warden)
"aFT" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/security/warden)
"aFU" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/glass_security{name = "Warden's Office"; req_access = list(3)},/obj/structure/cable/green{d1 = 2; d2 = 8; icon_state = "2-8"},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/dark,/area/security/warden)
@@ -1671,6 +1685,7 @@
"aGu" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor,/area/maintenance/security_starboard)
"aGv" = (/obj/machinery/power/apc{dir = 1; name = "north bump"; pixel_x = 0; pixel_y = 24},/obj/structure/cable/green{d2 = 2; icon_state = "0-2"},/obj/structure/closet/l3closet/janitor,/turf/simulated/floor/tiled,/area/janitor)
"aGw" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/security/brig)
+"aGx" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3)
"aGy" = (/obj/structure/disposalpipe/segment,/obj/machinery/power/apc{dir = 4; name = "east bump"; pixel_x = 24},/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/turf/simulated/floor/tiled,/area/crew_quarters/recreation_area_hallway)
"aGz" = (/obj/structure/disposalpipe/segment,/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/turf/simulated/floor/tiled,/area/hallway/secondary/civilian_hallway_aft)
"aGA" = (/obj/structure/table/reinforced,/obj/item/weapon/clipboard,/obj/item/weapon/clipboard,/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled/dark,/area/lawoffice)
@@ -1737,7 +1752,9 @@
"aHJ" = (/obj/machinery/flasher{id = "Cell 3"; pixel_x = -28; pixel_y = 0},/obj/structure/bed/padded,/turf/simulated/floor/tiled,/area/security/prison)
"aHK" = (/obj/structure/closet/secure_closet/brig{id = "Cell 3"; name = "Cell 3 Locker"},/obj/machinery/camera/network/prison{c_tag = "SEC - Brig Cell 3"; dir = 8},/obj/effect/floor_decal/corner/red{dir = 10},/turf/simulated/floor/tiled,/area/security/prison)
"aHL" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 4},/obj/effect/floor_decal/industrial/warning{dir = 1},/turf/simulated/floor,/area/maintenance/security_starboard)
+"aHM" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3)
"aHN" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/structure/disposalpipe/segment,/turf/simulated/floor,/area/maintenance/security_starboard)
+"aHO" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_4)
"aHP" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/janitor)
"aHQ" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled,/area/janitor)
"aHR" = (/obj/machinery/light_switch{pixel_x = 34; pixel_y = 1},/obj/machinery/button/remote/blast_door{id = "janitor_blast"; name = "Privacy Shutters"; pixel_x = 26; pixel_y = 0},/obj/machinery/camera/network/civilian{c_tag = "CIV - Custodial Closet"; dir = 9},/turf/simulated/floor/tiled,/area/janitor)
@@ -1801,6 +1818,7 @@
"aIX" = (/obj/machinery/door/blast/regular{dir = 1; id = "Cell 3"; name = "Cell Door"},/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled,/area/security/prison)
"aIY" = (/obj/machinery/atmospherics/pipe/tank/air{dir = 4},/obj/effect/floor_decal/industrial/warning,/turf/simulated/floor,/area/maintenance/security_starboard)
"aIZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/cyan{dir = 9; icon_state = "intact"; tag = "icon-intact-f (NORTHWEST)"},/obj/effect/floor_decal/industrial/warning{dir = 6},/turf/simulated/floor,/area/maintenance/security_starboard)
+"aJa" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_4)
"aJb" = (/turf/simulated/floor/tiled,/area/janitor)
"aJc" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/hologram/holopad,/turf/simulated/floor/tiled,/area/janitor)
"aJd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 5},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/janitor)
@@ -1834,6 +1852,7 @@
"aJF" = (/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/effect/floor_decal/corner/red{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/machinery/computer/cryopod{density = 0; layer = 3.3; pixel_y = 32},/turf/simulated/floor/tiled,/area/security/security_cell_hallway)
"aJG" = (/obj/machinery/hologram/holopad,/turf/simulated/floor/tiled/dark,/area/security/armoury)
"aJH" = (/obj/effect/floor_decal/corner/red{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden{tag = "icon-intact (EAST)"; icon_state = "intact"; dir = 4},/obj/item/device/radio/intercom{broadcasting = 0; dir = 1; frequency = 1475; icon_state = "intercom"; listening = 1; name = "Station Intercom (Security)"; pixel_x = 0; pixel_y = 21},/turf/simulated/floor/tiled,/area/security/security_cell_hallway)
+"aJI" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_9)
"aJJ" = (/turf/simulated/wall/r_wall,/area/security/range)
"aJK" = (/turf/simulated/wall,/area/security/range)
"aJL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/plating,/area/security/range)
@@ -1852,6 +1871,7 @@
"aJY" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock{id_tag = "visitdoor"; name = "Visitation Area"; req_access = list(63)},/turf/simulated/floor/tiled,/area/security/prison)
"aJZ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_security{id_tag = "prisonexit"; name = "Brig Exit"; req_access = list(2)},/turf/simulated/floor/tiled,/area/security/prison)
"aKa" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_security{id_tag = "prisonexit"; name = "Brig Exit"; req_access = list(2)},/turf/simulated/floor/tiled,/area/security/prison)
+"aKb" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_9)
"aKc" = (/obj/structure/cable/green{d1 = 1; d2 = 4; icon_state = "1-4"},/obj/machinery/computer/arcade,/turf/simulated/floor/tiled,/area/security/prison)
"aKd" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled,/area/security/prison)
"aKe" = (/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/security/prison)
@@ -1863,7 +1883,10 @@
"aKk" = (/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/tiled,/area/security/prison)
"aKl" = (/obj/structure/reagent_dispensers/watertank,/turf/simulated/floor,/area/maintenance/security_starboard)
"aKm" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "Janitor"},/obj/structure/plasticflaps{opacity = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/janitor)
+"aKn" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_10)
"aKo" = (/obj/structure/janitorialcart,/turf/simulated/floor/tiled,/area/janitor)
+"aKp" = (/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_10)
+"aKq" = (/obj/machinery/newscaster{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3)
"aKr" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/blast/shutters{density = 0; dir = 8; icon_state = "shutter0"; id = "lawyer_blast"; name = "Privacy Shutters"; opacity = 0},/obj/structure/window/reinforced,/turf/simulated/floor/plating,/area/lawoffice)
"aKs" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/dark,/area/lawoffice)
"aKt" = (/obj/structure/table/reinforced,/obj/item/weapon/pen/blue{pixel_x = -5; pixel_y = -1},/obj/item/weapon/pen/red{pixel_x = -1; pixel_y = 3},/obj/item/weapon/material/ashtray/plastic{pixel_x = 4; pixel_y = 6},/obj/item/weapon/paper_bin{pixel_x = -3; pixel_y = 7},/turf/simulated/floor/tiled/dark,/area/lawoffice)
@@ -1878,6 +1901,9 @@
"aKC" = (/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/crew_quarters/pool)
"aKD" = (/obj/effect/floor_decal/spline/plain{dir = 4},/turf/simulated/floor/beach/water{icon_state = "seadeep"},/area/crew_quarters/pool)
"aKE" = (/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool)
+"aKF" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3)
+"aKG" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_4)
+"aKH" = (/obj/machinery/newscaster{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_4)
"aKI" = (/turf/simulated/floor/tiled,/area/security/range)
"aKJ" = (/obj/machinery/alarm{pixel_y = 22},/turf/simulated/floor/tiled,/area/security/range)
"aKK" = (/obj/machinery/light{dir = 1},/turf/simulated/floor/tiled,/area/security/range)
@@ -1915,7 +1941,11 @@
"aLq" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/maintenance/security_starboard)
"aLr" = (/obj/machinery/door/firedoor/border_only,/obj/machinery/door/airlock/maintenance{name = "Custodial Maintenance"; req_access = list(26)},/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor,/area/janitor)
"aLs" = (/obj/structure/disposalpipe/segment{dir = 4},/turf/simulated/floor/tiled,/area/janitor)
+"aLt" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_9)
+"aLu" = (/obj/machinery/newscaster{pixel_x = -32; pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_9)
+"aLv" = (/obj/machinery/newscaster{pixel_x = 32; pixel_y = 0},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_10)
"aLw" = (/obj/item/weapon/stool/padded,/obj/effect/landmark/start{name = "Janitor"},/turf/simulated/floor/tiled,/area/janitor)
+"aLx" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_10)
"aLy" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled,/area/hallway/secondary/civilian_hallway_aft)
"aLz" = (/obj/machinery/button/remote/blast_door{id = "lawyer_blast"; name = "Privacy Shutters"; pixel_x = -26; pixel_y = 0},/obj/machinery/light_switch{pixel_x = -34; pixel_y = 0},/obj/machinery/camera/network/civilian{c_tag = "CIV - Internal Affairs"; dir = 5},/turf/simulated/floor/tiled/dark,/area/lawoffice)
"aLA" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/dark,/area/lawoffice)
@@ -1936,6 +1966,8 @@
"aLP" = (/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 8},/turf/simulated/floor/tiled,/area/crew_quarters/recreation_area)
"aLQ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/pool)
"aLR" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool)
+"aLS" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/candy,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
+"aLT" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/oven,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"aLU" = (/obj/effect/floor_decal/industrial/hatch/yellow,/obj/structure/target_stake,/turf/simulated/floor/tiled,/area/security/range)
"aLV" = (/obj/effect/floor_decal/industrial/hatch/yellow,/turf/simulated/floor/tiled,/area/security/range)
"aLW" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled,/area/security/range)
@@ -1955,6 +1987,7 @@
"aMk" = (/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/flasher{id = "permentryflash"; name = "Floor mounted flash"; pixel_x = 0},/obj/machinery/power/apc{dir = 8; name = "west bump"; pixel_x = -24},/obj/effect/floor_decal/industrial/outline/yellow,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/turf/simulated/floor/tiled,/area/security/prison)
"aMl" = (/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/camera/network/prison{c_tag = "SEC - Common Brig Enterance"; dir = 8},/obj/structure/cable/green{d1 = 1; d2 = 8; icon_state = "1-8"},/turf/simulated/floor/tiled,/area/security/prison)
"aMm" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d2 = 4; icon_state = "0-4"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Communal Brig Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison)
+"aMn" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/reagent_containers/food/snacks/mint,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/obj/item/weapon/reagent_containers/food/condiment/enzyme{layer = 5},/obj/item/weapon/packageWrap,/obj/item/weapon/reagent_containers/dropper,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"aMo" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/structure/table/steel,/obj/machinery/camera/network/prison{c_tag = "SEC - Brig Observation"; dir = 1},/turf/simulated/floor/tiled,/area/security/prison)
"aMp" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced{dir = 8},/obj/structure/cable/green,/obj/machinery/door/firedoor/border_only,/obj/structure/cable/green{d2 = 8; icon_state = "0-8"},/obj/machinery/door/blast/regular{density = 0; icon_state = "pdoor0"; id = "Prison Gate"; name = "Communal Brig Blast Door"; opacity = 0},/turf/simulated/floor/plating,/area/security/prison)
"aMq" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled,/area/security/prison)
@@ -1989,6 +2022,11 @@
"aMT" = (/obj/effect/floor_decal/spline/plain{dir = 1},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool)
"aMU" = (/obj/effect/floor_decal/spline/plain{dir = 5},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool)
"aMV" = (/obj/structure/table/glass,/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/pool)
+"aMW" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/light{dir = 8},/obj/machinery/newscaster{pixel_x = -31; pixel_y = 0},/obj/machinery/cooker/cereal,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
+"aMX" = (/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/grill,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
+"aMY" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/cooker/fryer,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
+"aMZ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/table/marble,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/item/weapon/book/manual/chef_recipes,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
+"aNa" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/obj/machinery/icecream_vat,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"aNc" = (/obj/machinery/light{icon_state = "tube1"; dir = 8},/turf/simulated/floor/tiled,/area/security/range)
"aNd" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/tiled,/area/security/range)
"aNe" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled,/area/security/range)
@@ -4277,9 +4315,7 @@
"bFF" = (/obj/machinery/chem_master/condimaster{name = "CondiMaster Neo"; pixel_x = -5},/obj/structure/window/reinforced{dir = 8},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/kitchen)
"bFG" = (/obj/machinery/camera/network/civilian{c_tag = "CIV - Kitchen Cold Room"; dir = 2},/obj/structure/closet/secure_closet/freezer/meat,/turf/simulated/floor/tiled/freezer,/area/crew_quarters/kitchen)
"bFH" = (/obj/structure/table/marble,/obj/machinery/chemical_dispenser/bar_soft/full,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
-"bFI" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/book/manual/chef_recipes,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bFJ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
-"bFK" = (/obj/structure/table/standard,/obj/machinery/reagentgrinder,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bFL" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 8},/obj/structure/window/reinforced{dir = 4},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/crew_quarters/kitchen)
"bFM" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/structure/disposalpipe/segment,/obj/effect/floor_decal/corner/lime/full{dir = 8},/turf/simulated/floor/tiled,/area/hydroponics)
"bFN" = (/obj/structure/closet/secure_closet/hydroponics,/obj/effect/floor_decal/corner/lime{dir = 5},/turf/simulated/floor/tiled,/area/hydroponics)
@@ -4363,7 +4399,6 @@
"bHn" = (/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/freezer,/area/crew_quarters/kitchen)
"bHo" = (/turf/simulated/floor/tiled/freezer,/area/crew_quarters/kitchen)
"bHp" = (/obj/item/device/radio/intercom{dir = 4; name = "Station Intercom (General)"; pixel_x = 21},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/kitchen)
-"bHq" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/reagent_containers/food/snacks/mint,/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bHr" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bHs" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bHt" = (/obj/machinery/door/airlock/glass{name = "Hydroponics"; req_access = list(28)},/obj/machinery/door/firedoor/glass,/obj/structure/cable/green{d1 = 4; d2 = 8; icon_state = "4-8"},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
@@ -4443,7 +4478,6 @@
"bIR" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/freezer,/area/crew_quarters/kitchen)
"bIS" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/kitchen)
"bIT" = (/obj/structure/closet/crate/freezer,/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled/freezer,/area/crew_quarters/kitchen)
-"bIU" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/effect/decal/cleanable/flour,/obj/structure/table/marble,/obj/machinery/light{dir = 8},/obj/machinery/newscaster{pixel_x = -31; pixel_y = 0},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bIV" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bIW" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/material/knife/butch,/obj/item/weapon/material/kitchen/rollingpin,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bIX" = (/obj/machinery/smartfridge,/turf/simulated/wall,/area/crew_quarters/kitchen)
@@ -4690,7 +4724,6 @@
"bNE" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment{dir = 2; icon_state = "pipe-c"},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bNG" = (/obj/structure/table/woodentable,/obj/machinery/light,/obj/item/weapon/reagent_containers/food/condiment/small/sugar,/obj/effect/floor_decal/corner/brown{dir = 10},/turf/simulated/floor/tiled/white,/area/crew_quarters/coffee_shop)
"bNH" = (/obj/structure/sink/kitchen{pixel_y = 28},/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/atmospherics/unary/vent_scrubber/on,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
-"bNI" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/structure/table/marble,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bNJ" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/camera/network/civilian{c_tag = "CIV - Kitchen Starboard"; dir = 8},/obj/structure/closet/secure_closet/freezer/meat,/obj/machinery/light{icon_state = "tube1"; dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bNK" = (/obj/effect/floor_decal/corner/lime/full,/obj/item/weapon/reagent_containers/glass/bucket,/obj/structure/table/standard{name = "plastic table frame"},/obj/item/device/radio/intercom{dir = 8; name = "Station Intercom (General)"; pixel_x = -21},/turf/simulated/floor/tiled,/area/hydroponics)
"bNL" = (/obj/effect/floor_decal/corner/lime{dir = 8},/obj/machinery/disposal,/obj/structure/disposalpipe/trunk{dir = 1},/turf/simulated/floor/tiled,/area/hydroponics)
@@ -4792,7 +4825,6 @@
"bPD" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{dir = 8},/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 8},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bPE" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bPF" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 1},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
-"bPG" = (/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 9; pixel_y = 0},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 9},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bPH" = (/obj/structure/closet/secure_closet/freezer/kitchen,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bPI" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 8},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hydroponics)
"bPJ" = (/obj/structure/grille,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced,/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/hydroponics)
@@ -4838,7 +4870,6 @@
"bQx" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/effect/floor_decal/industrial/warning{icon_state = "warning"; dir = 8},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/structure/disposalpipe/segment,/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/medical/virologyaccess)
"bQy" = (/obj/structure/sign/securearea{desc = "A warning sign which reads 'HIGH VOLTAGE'"; icon_state = "shock"; name = "HIGH VOLTAGE"; pixel_y = -32},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 1},/obj/machinery/camera/network/medbay{c_tag = "MED - Virology Access"; dir = 1},/turf/simulated/floor/tiled,/area/medical/virologyaccess)
"bQz" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/lime{dir = 6},/obj/machinery/light{dir = 4; icon_state = "tube1"; pixel_x = 0},/turf/simulated/floor/tiled,/area/medical/virologyaccess)
-"bQA" = (/obj/structure/table/marble,/obj/effect/floor_decal/corner/grey/diagonal{dir = 4},/obj/item/weapon/reagent_containers/food/condiment/small/saltshaker{pixel_x = -3; pixel_y = 0},/obj/item/weapon/reagent_containers/food/condiment/small/peppermill{pixel_x = 3},/obj/machinery/status_display{density = 0; layer = 4; pixel_x = 0; pixel_y = 32},/turf/simulated/floor/tiled/white,/area/crew_quarters/kitchen)
"bQB" = (/obj/machinery/power/apc{dir = 2; name = "south bump"; pixel_y = -24},/obj/structure/cable/green,/turf/simulated/floor/tiled,/area/medical/virologyaccess)
"bQD" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/turf/simulated/floor/tiled,/area/medical/virologyaccess)
"bQE" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/yellow,/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/medical/virologyaccess)
@@ -6361,7 +6392,6 @@
"cus" = (/obj/effect/floor_decal/corner/white/diagonal{tag = "icon-corner_white_diagonal (EAST)"; icon_state = "corner_white_diagonal"; dir = 4},/obj/effect/floor_decal/corner/blue{dir = 1},/obj/structure/flora/pottedplant{icon_state = "plant-22"},/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
"cut" = (/obj/effect/floor_decal/corner/white{dir = 4},/obj/effect/floor_decal/corner/blue{dir = 1},/obj/machinery/atm{pixel_y = 30},/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
"cuu" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
-"cuv" = (/obj/structure/table/standard,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"cux" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_5)
"cuy" = (/obj/effect/floor_decal/corner/lime{dir = 9},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/smartfridge/drying_rack,/turf/simulated/floor/tiled,/area/hydroponics)
"cuz" = (/obj/effect/floor_decal/corner/white{dir = 8},/obj/effect/floor_decal/corner/blue{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
@@ -6370,9 +6400,7 @@
"cuC" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_6)
"cuD" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_6)
"cuE" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_6)
-"cuF" = (/obj/structure/table/standard,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_6)
"cuG" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_11)
-"cuH" = (/obj/structure/table/standard,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_11)
"cuI" = (/obj/item/frame/light,/obj/structure/table/reinforced,/turf/simulated/floor/tiled,/area/vacant/vacant_shop)
"cuJ" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 10},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 6},/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_11)
"cuL" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/white{dir = 8},/obj/effect/floor_decal/corner/blue{dir = 1},/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
@@ -6381,7 +6409,6 @@
"cuO" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply{dir = 6},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 10},/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_12)
"cuP" = (/obj/machinery/alarm{dir = 8; icon_state = "alarm0"; pixel_x = 24},/obj/machinery/atmospherics/unary/vent_pump/on{dir = 8},/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_12)
"cuQ" = (/obj/structure/closet/secure_closet/personal,/obj/item/clothing/head/kitty,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_12)
-"cuR" = (/obj/structure/table/standard,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_12)
"cuS" = (/turf/simulated/wall,/area/quartermaster/storage)
"cuT" = (/obj/structure/curtain/open/shower,/obj/machinery/door/window/southright{name = "Shower"},/obj/structure/window/reinforced{dir = 8},/obj/machinery/shower{pixel_y = 3},/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_12)
"cuU" = (/obj/structure/grille,/obj/structure/window/reinforced,/obj/structure/window/reinforced{dir = 1},/obj/structure/window/reinforced{dir = 4},/obj/machinery/door/firedoor/border_only,/turf/simulated/floor/plating,/area/quartermaster/storage)
@@ -6412,20 +6439,16 @@
"cvt" = (/obj/machinery/atm{pixel_x = 0; pixel_y = -32},/turf/simulated/floor/lino,/area/hallway/secondary/entry/docking_lounge)
"cvu" = (/obj/structure/bed/chair/wood/wings,/turf/simulated/floor/wood,/area/crew_quarters/bar)
"cvv" = (/obj/machinery/door/firedoor/glass,/obj/machinery/door/airlock/glass_engineeringatmos{name = "Engineering Break Room"; req_one_access = list(10)},/turf/simulated/floor/tiled,/area/engineering/break_room)
-"cvw" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"cvx" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"cvy" = (/obj/machinery/door/airlock{name = "Restroom"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_5)
"cvA" = (/obj/effect/floor_decal/corner/white{dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
"cvB" = (/obj/machinery/door/airlock{name = "Restroom"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_6)
-"cvC" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_6)
"cvD" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_6)
-"cvE" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_11)
"cvF" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_11)
"cvG" = (/obj/machinery/door/airlock{name = "Restroom"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_11)
"cvH" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/blue{dir = 1},/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
"cvI" = (/obj/effect/floor_decal/corner/white{dir = 4},/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
"cvJ" = (/obj/machinery/door/airlock{name = "Restroom"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_12)
-"cvK" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_12)
"cvL" = (/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_12)
"cvM" = (/turf/space,/area/supply/station)
"cvN" = (/obj/item/device/radio/intercom{name = "Station Intercom (General)"; pixel_y = -21},/obj/machinery/camera/network/northern_star{c_tag = "Hall - Port Primary 1"; dir = 4},/turf/simulated/floor/tiled/dark,/area/hallway/primary/port)
@@ -6541,7 +6564,6 @@
"cxU" = (/obj/structure/table/reinforced,/turf/simulated/floor/tiled,/area/vacant/vacant_shop)
"cxV" = (/obj/structure/bed/chair/comfy/beige{dir = 4},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"cxW" = (/obj/machinery/door/airlock/glass_medical{name = "First-Aid Station"; req_one_access = list(5,10,63)},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled/white,/area/medical/first_aid_station)
-"cxX" = (/obj/structure/bed/chair/comfy/beige{dir = 8},/obj/machinery/camera/network/civilian{c_tag = "CIV - Visitor Room 5"; dir = 1},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"cxY" = (/obj/structure/table/standard,/obj/item/weapon/storage/box/donkpockets{pixel_x = 3; pixel_y = 2},/obj/machinery/light,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"cxZ" = (/obj/structure/table/standard,/obj/machinery/microwave,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"cya" = (/obj/structure/cable/green{d1 = 2; d2 = 4; icon_state = "2-4"},/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers,/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/obj/structure/disposalpipe/segment{dir = 4; icon_state = "pipe-c"},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_11)
@@ -6747,24 +6769,16 @@
"cBW" = (/obj/machinery/atmospherics/pipe/tank/air,/obj/effect/floor_decal/industrial/warning{dir = 4},/turf/simulated/floor,/area/maintenance/bar)
"cBX" = (/obj/structure/table/rack{dir = 4},/obj/item/clothing/mask/gas,/turf/simulated/floor/plating,/area/maintenance/bar)
"cBY" = (/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{dir = 4},/obj/structure/disposalpipe/segment{dir = 4},/obj/effect/floor_decal/corner/lime{dir = 10},/obj/machinery/atmospherics/pipe/manifold/hidden/supply,/turf/simulated/floor/tiled/white,/area/medical/virology)
-"cBZ" = (/obj/structure/table/standard,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3)
-"cCa" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3)
"cCb" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_3)
"cCc" = (/obj/structure/toilet,/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_4)
"cCd" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/blue{dir = 1},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
"cCe" = (/obj/machinery/door/airlock{name = "Restroom"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_4)
"cCf" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_4)
-"cCg" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_4)
-"cCh" = (/obj/structure/table/standard,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_4)
-"cCi" = (/obj/structure/table/standard,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_9)
-"cCj" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_9)
"cCk" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_9)
"cCl" = (/obj/structure/toilet,/obj/machinery/light{dir = 1},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_9)
"cCm" = (/obj/structure/cable/green{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/effect/floor_decal/corner/white{dir = 4},/obj/effect/floor_decal/corner/blue,/obj/machinery/atmospherics/pipe/manifold/hidden/supply{dir = 4},/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/light{icon_state = "tube1"; dir = 4},/obj/structure/disposalpipe/segment,/turf/simulated/floor/tiled,/area/crew_quarters/visitor_lodging)
"cCn" = (/obj/machinery/door/airlock{name = "Restroom"},/obj/machinery/atmospherics/pipe/simple/hidden/supply,/turf/simulated/floor/tiled/white,/area/crew_quarters/sleep/vistor_room_10)
"cCo" = (/obj/structure/closet/secure_closet/personal,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_10)
-"cCp" = (/obj/structure/bed/padded,/obj/item/weapon/bedsheet/brown,/obj/machinery/atmospherics/unary/vent_pump/on,/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_10)
-"cCq" = (/obj/structure/table/standard,/obj/machinery/newscaster{pixel_x = 0; pixel_y = 32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_10)
"cCr" = (/obj/effect/floor_decal/industrial/warning{dir = 10},/turf/simulated/floor/tiled,/area/quartermaster/storage)
"cCs" = (/obj/effect/floor_decal/industrial/outline/yellow,/obj/vehicle/train/cargo/trolley,/obj/machinery/camera/network/cargo{c_tag = "CRG - Cargo Bay Starboard"; dir = 8; name = "security camera"},/turf/simulated/floor/tiled,/area/quartermaster/storage)
"cCt" = (/turf/simulated/wall,/area/quartermaster/warehouse)
@@ -9532,7 +9546,6 @@
"dEJ" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #1"},/obj/effect/floor_decal/industrial/outline/yellow,/mob/living/bot/mulebot,/turf/simulated/floor/tiled,/area/quartermaster/storage)
"dEK" = (/obj/machinery/navbeacon{codes_txt = "delivery;dir=8"; freq = 1400; location = "QM #2"},/obj/effect/floor_decal/industrial/outline/yellow,/mob/living/bot/mulebot,/turf/simulated/floor/tiled,/area/quartermaster/storage)
"dEL" = (/turf/simulated/mineral,/area/mine/explored/upper_level)
-"dEM" = (/obj/structure/table/standard,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_5)
"dEN" = (/obj/structure/table/standard,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_6)
"dEO" = (/turf/simulated/wall,/area/medical/first_aid_station_starboard)
"dEP" = (/obj/structure/table/standard,/obj/machinery/atmospherics/unary/vent_scrubber/on{dir = 1},/obj/machinery/computer/security/telescreen/entertainment{icon_state = "frame"; pixel_x = 0; pixel_y = -32},/turf/simulated/floor/wood,/area/crew_quarters/sleep/vistor_room_11)
@@ -9652,7 +9665,7 @@
"dHz" = (/obj/machinery/computer/cryopod/robot{pixel_x = 30; pixel_y = 0},/obj/effect/floor_decal/industrial/warning/corner,/obj/machinery/camera/network/research{c_tag = "SCI - Mech Bay Starboard"; dir = 8},/turf/simulated/floor/tiled,/area/assembly/chargebay)
"dHA" = (/obj/machinery/atmospherics/pipe/simple/hidden/supply,/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,/obj/machinery/door/firedoor/glass,/turf/simulated/floor/tiled,/area/hallway/primary/central_four)
"dHB" = (/obj/structure/disposalpipe/segment,/obj/machinery/door/firedoor/glass,/turf/simulated/floor/tiled,/area/hallway/primary/central_four)
-
+
(1,1,1) = {"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -9803,13 +9816,13 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAacAacAaadaaabtEbvcbtGaaabtEbvcbtGaaabtEbvcbtGaaabtEbvcbtGaaaaadaaaaaaaaaaaaaadbzmbznbznbznbznbzobtHbtHbtLbzpbzqbzrbzsawybtLaahaahaahaahahyahyahyahyahyahyaahaahaahaahaahbwMbzubzvbzwbzxbzybzzbzAbzBbzCbzDbzEbzFbzGbzHbzIbzJbzKbzLbzMbzNbzObzPbzQbzRbzSbzPbzTbzUbzVbzWbzXbzYbecbajbhqbhrbzZaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaahaahaahbxaaahaahaZdaZdaZdaZdaZdaZdbAabAbbAcbAdaZGaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdaZdbAebAfbAgbAhaUvbAibAjbAkbvSbAlbvSbAmbxgbAnbAobuCbApbAqbArbAsbAtbAubuCbAvbAwbqmbAxbAxbAybtfbAzbwibAAbABbACbADbAEbAFbySbAGbAHbAIbyWbyWbAJbySbAKaZmaahaahaahaahaahbgmbgmdkRbAMbANbAObAPcBYbARbASbATbAUbAVbAWbAXbgmaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAaaaaadaaaaaaaadaivaadaaaaadaivaadaaaaadaivaadaaaaadaivaadaaaaadaaaaaaaaabAZbBabBbbBcbBdbBebBfbBgbBhbBibtLbBjbBkbBlbBmbztbtLaahaahaahaahaahahyahyahyahyaahaahaahaahaahaahbwMbBnbzwbBobBpbBqbBrbBsbBrbBtbBubBvbBwbBxbjJbBybjJbBzbjJbjJbBAbBBbBCbBDbBEbBFbBGbBHbBIbBJbBKbBLbBMbBNbBObBPbBQbBRbBSbBTbBUbBUbBUbBUbBVbBUbBWaZdaZdaZdaZdbBXaZdaZdaZdbBYbBZbBZbBZbBZbBZbCabCbbCcbCdbCdbCdbCdbCdbCdbCdbCebCdbCdbCdbCfbCgbCgbCgbCgbCgbCgbCgbCgbChbCgbCibCjbCkbClbCmbbRbCnbCobCpbCqbCrbvQbCsbvSbCtbCubwabCvbCwbCxbCzbyDbCybwabCBbCCbCDbCEbCEbCFbCGbwhbxtbCHbCIbCJbCKbIcbySbySbCMbCNbCObCPbyWbAJbySbAKaZmaahaahaahaahaahaahbgmbgmbgmbJJbCRbgmbgmbgmbgmbgmbgmbCSbCTbgmbgmaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAaadbCUbCVbCVbCVbAYbCVbCVbCVbAYbCVbCVbCVbAYbCVbCVbCVbAYbCVbCVbCVbCVbCVbCZbDabDbbDcbDdbDebDfbDgbDhbDibDjbtLbtLbDkbtLbtLbDlbtLaahaahaahaahaahaahaahahyahyaahaahaahaahaahaahbwMbDmbDnbDobDpbDqbDrbDsbDtbwMbDubDvbDwbDxbDybDzbDAbDBbDCbDDbDEbDFbyhbDGbDHbDIbDJbDKbDLbzVbzWbzXbzYbecbecbDMbDNbDOaZdbDPbDQbDRbDSbDTbDUbDVbDWbDXbDYbDZbEabEbbBUbBUbBUbEcaZdaZdaZdaZdaZGbEdbEebEfbEgbEgbEgbEgbEgbEgbEgbEhbEgbEgbEgbEibEjbEjbEjbEjbEjbEjbEjbEkbiDbjYaZdbElaYGbetbEmaVlbEnbEobEpbEqbErbEsbEtbEubEvbEwbsXbsYbsZbExbsYbEybsZbsXbEzbtbbyFbyGbyHbEAbtfbEBbuKbECbEDbuKbySbySbySdBabEFbEGbEHbEIbyWbAJbySbAKaZmaahaahaahaahaahaahaahbgmbEJbEKbELbgmaahaahaahaahbgmbgmbgmbgmaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAaaaaadaaaaaaaadaivaadaaaaadaivaadaaaaadaivaadaaaaadaivaadaaaaadaaaaaaaaabAZbBabENbEObEPbEQbznbERbESbETbEUbEUbEVbEWbtHbEXbtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbwMbEYbEZbFabFbbFcbFdbFebFfbwMbFgbfubFhbFibFjbFkbFlbFmbFibFnbFobFnbyhbyhbyhbyhbyhbrDbFqbFrbyhbfzbeebFsbecbcnbFtbboaZdbFubFubFubFubFubFubFvbFwaZdbFxbFybFxaZdbFzbFAbFBbFCaZdaahaahaZdaZdaZGaZHaZGbFDbFEbFFbFGbEgbFHbFIbFJbFJbFKbFLbFMbFObFNbFPbFNbHvbHubEjbFQbEjaZdaZdaTobFRbgJaUvbFSaTobypbyqbFTbAlbFUbFVbFWbFXbEqbFYbFZbGabGbbGcbGdbGebGfbGgbGhbGibGjbGjbGkbGlbtbbGmbGnbGobGpbySbGqbGrbGsbGtbGubGvbGwbyWbAJbySaZWaZmaZmaahaahaahaahaahaahbgmbxzbGybGzbgmaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAacAacAaadaadbtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaaaadaaaaaaaaaaaaaaabGBbznbznbznbznbtHbtHbGCbGDbDibGEbGFbGGbGHbtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbwMbwMbwMbGIbGJbGJbGJbwMbwMbwMbGKbGLbyfbGMbGNbGObGPbGQbFibGSbGUbGTbGWbGVbIsbGXbGYbFnbGZbFnbGYahybeebeebHabcnbecbHbbHcbFubHdbyObHfbHgbFubFubFubFuawzbHibHhbHjbHjbHkbHlbHjbHmaahaahaahaZdaZdaZHbEgbEgbHnbHobHpbEgbHqbHrbHsbHsbHsbHtbHwbHybHxbHxbHzbKBbJbbHAbHBbEjahyahyaToaZjblDbHCaToaToahybxcbHDbHEbCqbHFbHGbHHbCqbHIbHJbHKbHLbHMbHNbHMbHObHPbHPbHQbHPbHPbHRbHSbHTbHUbHVbHWdBkbySbHYbHZbIabGtbGubGvbIbbyWbAJbySbbbbJraZmaahaahaahaahaahaahbgmbHebIedGPbgmaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaaaadaaaaaaaaaaahaahaahaahaahaahaahaahbtHbtHbtHbtHbtHbIgbIhbIibtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbwMbIjbGJbGIbGJbGJbGJbGJbIkbwMbIlbfubImbInbIobIpbIqbIrbFibItbIAbIybIubIubIwbIubJXbJWbIzbJYbKcahyahybIBbecbRQbecbICbHcbIDbIEbIFbIFbIGbIHbIIbIJbFuaxjaxibIMbHjbINbIObIPbHjaahaahaahaahaZdaZGaZHbEgbIQbIRbISbITbEgbIUbIVbIWbFJbFJbIXbIYbIZbJabJabJabJabJabJbbJcbJdahyahybJeaYGbRSaUvbpPahyahybuobosbvSbvSbJfbJgbvSbvSbJhbJibJjbJkbxqbJlbJmbJnbthbJobJpbJqbKLbJsbJtbJubJvbJwbJxbJybJzbJAbJBbJCbJDbJEbJFbJGbJHbJIbySbglbfpaZmaahaahaahaahaahaahbgmbgmbLDbJKbgmaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAaaaaadaaaaaaaadaivaadaaaaadaivaadaaaaadaivaadaaaaadaivaadaaaaadaaaaaaaaabAZbBabENbEObEPbEQbznbERbESbETbEUbEUbEVbEWbtHbEXbtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbwMbEYbEZbFabFbbFcbFdbFebFfbwMbFgbfubFhbFibFjbFkbFlbFmbFibFnbFobFnbyhbyhbyhbyhbyhbrDbFqbFrbyhbfzbeebFsbecbcnbFtbboaZdbFubFubFubFubFubFubFvbFwaZdbFxbFybFxaZdbFzbFAbFBbFCaZdaahaahaZdaZdaZGaZHaZGbFDbFEbFFbFGbEgbFHaylbFJaLTaLSbFLbFMbFObFNbFPbFNbHvbHubEjbFQbEjaZdaZdaTobFRbgJaUvbFSaTobypbyqbFTbAlbFUbFVbFWbFXbEqbFYbFZbGabGbbGcbGdbGebGfbGgbGhbGibGjbGjbGkbGlbtbbGmbGnbGobGpbySbGqbGrbGsbGtbGubGvbGwbyWbAJbySaZWaZmaZmaahaahaahaahaahaahbgmbxzbGybGzbgmaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAacAacAaadaadbtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaaaadaaaaaaaaaaaaaaabGBbznbznbznbznbtHbtHbGCbGDbDibGEbGFbGGbGHbtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbwMbwMbwMbGIbGJbGJbGJbwMbwMbwMbGKbGLbyfbGMbGNbGObGPbGQbFibGSbGUbGTbGWbGVbIsbGXbGYbFnbGZbFnbGYahybeebeebHabcnbecbHbbHcbFubHdbyObHfbHgbFubFubFubFuawzbHibHhbHjbHjbHkbHlbHjbHmaahaahaahaZdaZdaZHbEgbEgbHnbHobHpbEgaMnbHrbHsbHsbHsbHtbHwbHybHxbHxbHzbKBbJbbHAbHBbEjahyahyaToaZjblDbHCaToaToahybxcbHDbHEbCqbHFbHGbHHbCqbHIbHJbHKbHLbHMbHNbHMbHObHPbHPbHQbHPbHPbHRbHSbHTbHUbHVbHWdBkbySbHYbHZbIabGtbGubGvbIbbyWbAJbySbbbbJraZmaahaahaahaahaahaahbgmbHebIedGPbgmaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaaaadaaaaaaaaaaahaahaahaahaahaahaahaahbtHbtHbtHbtHbtHbIgbIhbIibtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbwMbIjbGJbGIbGJbGJbGJbGJbIkbwMbIlbfubImbInbIobIpbIqbIrbFibItbIAbIybIubIubIwbIubJXbJWbIzbJYbKcahyahybIBbecbRQbecbICbHcbIDbIEbIFbIFbIGbIHbIIbIJbFuaxjaxibIMbHjbINbIObIPbHjaahaahaahaahaZdaZGaZHbEgbIQbIRbISbITbEgaMWbIVbIWbFJbFJbIXbIYbIZbJabJabJabJabJabJbbJcbJdahyahybJeaYGbRSaUvbpPahyahybuobosbvSbvSbJfbJgbvSbvSbJhbJibJjbJkbxqbJlbJmbJnbthbJobJpbJqbKLbJsbJtbJubJvbJwbJxbJybJzbJAbJBbJCbJDbJEbJFbJGbJHbJIbySbglbfpaZmaahaahaahaahaahaahbgmbgmbLDbJKbgmaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaaabtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaabtEbGAbtGaaaacAaaaaaaaahaahahyahyahyahyahyahyahyahyaahaahaahbtHbtHbJLbIibtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbwMbJMbGJbJNbJObGJbGJbGJbIkbwMbJPbtUbJQbJRbJSbIdbJUbJVbFibGYbKabJZbIubIubIubIubKbbIubIubLzbLAahyahybKdbecbcnbecbKebHcbKfbKgbKhbKibKjbKhbKhbKkbFubKlbILbKmbHjbKnbKobKpbHjaahaahaahaahaZdbKqaZHbEgbIQbKrbKsbKtbEgbKubKvbKwbFJbKxbKycuybKAbJabJabJabJabJabKBbKCbKDahyahybrGbKEbynbKFbrGahyahybvObsDbKHbKHbKIbKKbMHaGMbKNbKNbKObKPbKQbKRbKNbKSbKTbKUbKVbKSbKWbKWbKWbKWbKWbKXbKYbKZbLabySbySbySbySbySbySbySbySbySbySbLbbLcaZmbLdbLebLebLebLdbLdbLfbLgbLhbLibLfbLdaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAaadbtEbGAbtGaadbtEbGAbtGaadbtEbGAbtGaadbtEbGAbtGaadacAaaabLjaahbLkbLkbLlbkQbkQbkQbLmbLkbLkahyaahaahaahbtHbLnbIibtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahbwMbLobLpbLqbGJbLrbGJbLsbwMbwMbLtbfubImbFibLubLvbLwbLxbLybGYbLCbLBbIvbIubIubIubKbbIvbIubLEbLAahyahybKdbLGbhqbecbKebHcbLHbLIbKhbLJbLKbLLbLMbLNbLObLPbLQbLRbLSbLTbLUbLVbHjaahaahaahaahaZdaZdaZHbEgbEgbLWbEgbEgbEgbLXbLYcAgbMabKxbMbcuBbMdbMebMfbMgbMhbKBbKBbMibKDahyahybvNbMjbgJaUvbvNahyahybMkbMlbMmbKJbOcbMkbMkbMkbMkaPubMqbMrbMsbMtbMsbKSbMubMvbMwbMxbKWbMybMzbMAbMBbMCbMDbMEbMFbMGbOdbMIbMJbRXbMLbMMdFecbabUSbMQbMRbMSbMTbMUbMVbMWbMXbMYbMZbNabNbbNabNcbLdaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOaaabtEbNdbtGaaabtEbNdbtGaaabtEbNdbtGaaabtEbNdbtGaaaaadaadbLjaahbLkbNebNfbNgbNfbNgbNfbNebLkahyahyaahaahbtHbNhbIibtHbtHaahaahaahaahaahaahaahaahaahaahaahbtHbtHbtHbwMbwMbwMbwMbwMbwMbwMbwMbwMbNibNjbfubyfbGMbNkbNlbNmbLxbNnbGYbPkbNsbRfbPnaxraxUbRibRfbRkbRjbLFahyahybKdbecbDMbDNbKebNtbFubNubKhbNvbNwbNxbKhbNybFubNzbNAaGUbNCbNCbNCbNCbNCbNCbNCbNCaahaahaZdaZHbEgbNDbNEaylbQAbNHbFJbFJbNIbFJbNJbEgbNKbNLbNMbNNbNObKBbNPbNQbNRbNSahyahyaTobNTbetbNUaToahyahybMkbNVbNWbNXbNYbSkbUXbMnbMobNBbMqbMrbOebOfbOgbKSbOhbOibOjbOkbKWbOlbOmbOnbOobOpbOqbOrbOsbOtbOtbOubOvbOqbOtbOwbOtbOxbOybOzbOAbOBbOCbODbOEbOEbOFbOEbOGbOHbOIbOJbOKbLdaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAaaaaadaaaaaaaaaaadaadaadaaaaaaaaaaaaaaaaaaaaaaadaaaaadaadaahaahaahbOLbOMbONbOObOPbOQbOLbORahyahyaahaahbtHbOSbIibOTbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbOUbOVbOWbOXbOYbOZbzHbPabPbbPcbPdbPebPfbPgbImbInbIobPhbPibLxbPjbGYbSRbSQbSSbNqbNqbNrbNpbSSbRlbSTbGYahyahybKdbecbcnbecbPobHcbFubPpbKhbPqbPrbPsbKhbPtbFubPubPvbPwbNCbPxbPybPzbPAbNCbPBbNCbNCaahaZdaZHbEgbPCbPDbPEbPEbPFbPEbPEbPGbFJbPHbEgbPIbPJbPKbPLbPMbPNbPIbPJbPKbEjbPObPPaToaZjblDbHCaToaToahybMkbPQbPRbPSbPTbPUbPVbPWbPXbPYbPZbQabQbbQcbQdbKSbQebQfbQgbQhbKWbQibQjbQkbMBbQlbQmbQnbQobQpbQqbQrbQsbQtbQpbQubQvdGRbMPbMQbQxbQybQzbMUbMVbWWbQBbOJanDbQDbQEbOJcAfbLdaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacOaaabtEbNdbtGaaabtEbNdbtGaaabtEbNdbtGaaabtEbNdbtGaaaaadaadbLjaahbLkbNebNfbNgbNfbNgbNfbNebLkahyahyaahaahbtHbNhbIibtHbtHaahaahaahaahaahaahaahaahaahaahaahbtHbtHbtHbwMbwMbwMbwMbwMbwMbwMbwMbwMbNibNjbfubyfbGMbNkbNlbNmbLxbNnbGYbPkbNsbRfbPnaxraxUbRibRfbRkbRjbLFahyahybKdbecbDMbDNbKebNtbFubNubKhbNvbNwbNxbKhbNybFubNzbNAaGUbNCbNCbNCbNCbNCbNCbNCbNCaahaahaZdaZHbEgbNDbNEaMYaMXbNHbFJbFJaMZbFJbNJbEgbNKbNLbNMbNNbNObKBbNPbNQbNRbNSahyahyaTobNTbetbNUaToahyahybMkbNVbNWbNXbNYbSkbUXbMnbMobNBbMqbMrbOebOfbOgbKSbOhbOibOjbOkbKWbOlbOmbOnbOobOpbOqbOrbOsbOtbOtbOubOvbOqbOtbOwbOtbOxbOybOzbOAbOBbOCbODbOEbOEbOFbOEbOGbOHbOIbOJbOKbLdaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacAaaaaadaaaaaaaaaaadaadaadaaaaaaaaaaaaaaaaaaaaaaadaaaaadaadaahaahaahbOLbOMbONbOObOPbOQbOLbORahyahyaahaahbtHbOSbIibOTbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbOUbOVbOWbOXbOYbOZbzHbPabPbbPcbPdbPebPfbPgbImbInbIobPhbPibLxbPjbGYbSRbSQbSSbNqbNqbNrbNpbSSbRlbSTbGYahyahybKdbecbcnbecbPobHcbFubPpbKhbPqbPrbPsbKhbPtbFubPubPvbPwbNCbPxbPybPzbPAbNCbPBbNCbNCaahaZdaZHbEgbPCbPDbPEbPEbPFbPEbPEaNabFJbPHbEgbPIbPJbPKbPLbPMbPNbPIbPJbPKbEjbPObPPaToaZjblDbHCaToaToahybMkbPQbPRbPSbPTbPUbPVbPWbPXbPYbPZbQabQbbQcbQdbKSbQebQfbQgbQhbKWbQibQjbQkbMBbQlbQmbQnbQobQpbQqbQrbQsbQtbQpbQubQvdGRbMPbMQbQxbQybQzbMUbMVbWWbQBbOJanDbQDbQEbOJcAfbLdaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaczaczacAaczaczacOacAaadaadaadaadaaaaaaaaaaadaadaadacOaadaaaaahaahaahbNgbQFbQGbQHbQHbQIbNgahyahyahyaahaahbtHbQJbQKbQLbQLbQLbQLbQLbQLbQLbQLbQLbQLbQLbQLbQLbQLbQMbQNbQObQPbQQbQRbQSbQTbQUbQVbQWbQXbQYbQZbyfbJRbRabRbbRcbRdbRebGYbNobNpbNpbNpbNpbNpbNpbNpbRlbSUbGYahyahybKdbecbcnbRmbRnbRobRpbRqbRrbRsbRtbRubRvbRwbFubRxbPvbRybNCbRzbRAbRBbRBbRCbRDbREbNCaahaZdaZHbEgaynbRGbFJbRHbRIbFJbFJbFJbFJbRJbEgbupbTlbTkbRNbRObRPbRObRPbvEbRTbRUbRUbRVbRWbetaUvbvFaToahybMkbRYbRZbSabNWbSbbScbSdbSebSfbSgbShbSibMpbvIbKSbXibQfbSlbSmbKWbKWbKWbKWbKWbSnbSobSpbSpbSpbSpbSpbSqbSrbSqbSqbSqbSqbSqbSsbStbSubSvbSwbSwbSwbLdbLdbSxbSycNtbSxbLdbLdaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahbOLbSAbQGbQHbQHbSBbOLbORahyahyaahaahbtHbSCbIibSDbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbtHbSEbSEbSFbSGbSEbSHbSIbSJbSKbSLbSMbSNbSObSPbSLbSLbSLbSLbSLbGYbUDbPlbPmbNpbNpbSzcpCcpubRlbXTbGYahyahybKdbecbcnbSVbbobbobFubFubFubFubFubFubSWbFubFubSXbSYbSZbNCbTabTbbTcbTdbNCbTebTfbNCaahaZdaZHbEgbFLbvJbEgbEgbThbTibTibTibTibEgbEgbTjbTkbTlbTmbTnbTkbTlbTkbTobTpaUvaUvaUvaUvbTqbTrbTsaToahybMkbGxbTubTvbTubTtbScbTxbTybVhbTAbTBbTCbTDbTEbKSbTFbTGbTHbTIbTJbTKbTLbTMbTNbTObTPbTQbTRbTSbTTbSpbTUbTVbTWbOabTXbTZbSqbUabUbbSubUcbUdbUebSuaahaahbSxbUfbUgbSxaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaahaahaahaahbLkbNebNfbNgbUhbNgbNfbNebLkahyahyaahaahbtHbtHbIibtHbtHaahaahaahaahaahaahaahaahaahaahaahaahaahaahbSEbUibUjbUkbUlbSEbUmbUnbUnbUobUpbUqbUrbUsbUtbUubUvbUwbUxbGYbXUbRgbYYbNpbNpcbIbRgcGibRlcGQbGYahyahybKdbecbcnaZzbUFahybUGbUHbUIbUJbUKbULbULbUMbUGbUNbUObUPbNCbNCbUQbNCbNCbNCbNCbNCbNCaahaZdaZHaZdbvMbUTbUUbUVbUWbUWbUWbUWbUWbYobUYbTkbTlbUZbVabVbbVcbTkbTlbVdbVeaUvaUvbVfbVgbdvaUvbvPaToahybMkbVibVjbVkbVlbVmbVnbVobVpbVqbVrbVsdGSbKNbKNbKSbKSbKSbKSbKSbTJbVtbVubVvbVwbVxbVybVzbVAbVBbVCbSpbVDbVEbVFbVGbVGbVHbSqbVIbVJbSubVKbVLbVMbSuaahaahbSxbVNcAhbSxaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
@@ -9835,14 +9848,14 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaahaahaahcjgcpKcpLcpMcpNcpOcqecpQcoacpRcoacpSchYcqzcpUcqzcpVcpWchZchYcpXcpXcpXcpXcpXcpXamYamYarsauQaruauRarvamYamYcmjcpYcmjcmjcpXcpXcpjcpjcFucFrcqdcpjdElcxWcyjdElcrIcqfcqfcqgcjzcjzcjzcjzcqhcjzcjzcjzcjzcrIcqfcqfcqfcqgcpjcqicqjcqkcqlcqmcpjcpjahyahyahyahyahycovcqncqocqpcqqcqrcqscrJcpBcqucovahyahyahyahycqvcqwcqxcqycqvahyahyahyahyczZcuIarwcxUcEvcEvcEVcEVcEVcIFczZahyahyahyahyahyahyahycrNckicqAcqBciFaahaahaahaahahOahOahOahOahOaahaahaahaahaahaahbZMcqCcgnbZMbZMaahaahaahaahaahaahaahaahaahaahaahbZMbZMcgncqDbZMaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaahaahaahcjgctxckncqFcqGcqHcqIcqJcqJcqKcqLcqMcqNcqOcqOcqPcqQcqRcqScqTcqUcqVcqWcqXcqYcqYcqZcqOarxcracqYcqYcqYcqYarycqOcrdarzcrfcrgcrhcricrjcMIcMjcrmcrncrocOZcrudBNcrscrtcrucrucrvcrucricrwcrxcrycrzcrAcrBcrAcrCcrAcrDcrAcrzcrAcrEcrFcrGcrucrHcrRahyahyahyahyahycrWcqtcrKcrLcrLcrMcrLcrLcpBcqtcrWahyahyahyahycsKcrOcrPcqycsKahyahyahyahycIHcEVcEVcEVcEVcEVcEVcEVcEVcJKcrQcrQcrQcsLcrScrTcrUcrQcrQctccsNctccrQcrQcrQcrQaahaahaahaahaahaahaahcrXcrXcrXcrXcrXbZMcrYcrZcrZcrZcrZcrZaahaahaahaahaahaahaahcsacsacsacsacsacsbbZMcsccsccsccsccscaahaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaaaaaaaahaahcjgcsdcknckncsecsfcsgcshcshcsicshcsjcskcslcsmcsncsncsncsocspcsqcsrcsqcsqcsqcsscsqcsqcsqcstcsqcsqcsqcsscsqcsqcsqcstcsqcsqcsucsvcswcsxcsycswcswcsvdBPcswcswcszcsAcsBcrucrucrucricrucsCcswcsDcswcsEcswcswcswcsFcswcsvcswcsGcsHcsIcrucsJcsRahyahyahyahyahyctmcqtcrKcrLcsMcsMcsMcrLcpBcqtctmahyahyahyctucsOcrOcsPcsQcumcsSahyahyahycMYcEVcEVcDncEVcEVcEVcEVcFecrQcrQcwtctdcsXcwtcwvcsXcsYcwwctbcsYctbctecxOcwxcrQcrQaahaahcrXcrXcrXcrXcrXctfctgayocrXctictjcrZayqctlcurcrZcrZcrZcrZcrZcsacsacsacsactnctoayscsactqctrcscayvcttcuTcsccsccsccsccscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaaaaaaaaabLjbLjcjgctvctwcALctycmacjgbRMctActBctCctDctEctFctGctHcrfcrfcrfctIctJctKcrfctLctMctNcrfctFctOcrfcrfctPctQctRctSctTctQctQctUctVctWcrocrpctXctYctZcuacubdCbcuadCfcuacuccudcuacuacuacubcuecufcuacubcuacugcuacuhcuicuacuacubcuacujcrucukcruculcuYahyahyahyahyahyctmcuncuocrLcsMcupcsMcrLcuqcunctmahyahyahycvacqycrOcrPcqycqycvaahyahyahycMYcJacEVcLvcEVcQdcEVcEVcEVcrQcxScsYcwrcwscwscwscwscwscwsczmczlczoczncPbcPbcBjcrQaahaahcrXcuucuvcuucrXcNfcuxdGMcrXcuzcuAcrZcuNcuCcuDcrZcuEcuFcuEcrZcuGcuHcuGcsacOScuJdHccsacuLcuMcsccwEcuOcuPcsccuQcuRcuQcscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadcuScuScvgcuUcuScuVcuWcuScuScuScuXcvocuZcuXcvrcvbcuXcvccvdcvecvfcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpjcvNcvhcrFcvicvjcpjcpjcpjcpjcrIcqfcqfcqfcqfcqgcpjbRRcvlcqdcpjcrIcqfcqgcpjcrIcqfcqgcpjcvmcrucrucrGcvncpjcpjahyahyahyahyahycwjcvpcuocrLcrLcrLcrLcrLcuqcvqcwjahyahyahycqvcwqcrOcrPcqycvscqvahyahyahycRUcWRcEVcEVcEVcEVcEVcEVcWRcrQcBkcsYcsYcsYcvucvucvucvucvuctbcDpcwzcsYcsYcsYcducrQaahaahcrXcvwcvxcvwcrXcrXcvycrXcrXcwFcwGcrZcrZcvBcrZcrZcvCcvDcvCcrZcvEcvFcvEcsacsacvGcsacsacvHcvIcsccsccvJcsccsccvKcvLcvKcscaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaaaaaaaaaaaaaaabLjbLjcjgctvctwcALctycmacjgbRMctActBctCctDctEctFctGctHcrfcrfcrfctIctJctKcrfctLctMctNcrfctFctOcrfcrfctPctQctRctSctTctQctQctUctVctWcrocrpctXctYctZcuacubdCbcuadCfcuacuccudcuacuacuacubcuecufcuacubcuacugcuacuhcuicuacuacubcuacujcrucukcruculcuYahyahyahyahyahyctmcuncuocrLcsMcupcsMcrLcuqcunctmahyahyahycvacqycrOcrPcqycqycvaahyahyahycMYcJacEVcLvcEVcQdcEVcEVcEVcrQcxScsYcwrcwscwscwscwscwscwsczmczlczoczncPbcPbcBjcrQaahaahcrXcuuazEcuucrXcNfcuxdGMcrXcuzcuAcrZcuNcuCcuDcrZcuEazFcuEcrZcuGaAdcuGcsacOScuJdHccsacuLcuMcsccwEcuOcuPcsccuQaADcuQcscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadaadaadaadaadaadaadaadaadaadcuScuScvgcuUcuScuVcuWcuScuScuScuXcvocuZcuXcvrcvbcuXcvccvdcvecvfcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpXcpjcvNcvhcrFcvicvjcpjcpjcpjcpjcrIcqfcqfcqfcqfcqgcpjbRRcvlcqdcpjcrIcqfcqgcpjcrIcqfcqgcpjcvmcrucrucrGcvncpjcpjahyahyahyahyahycwjcvpcuocrLcrLcrLcrLcrLcuqcvqcwjahyahyahycqvcwqcrOcrPcqycvscqvahyahyahycRUcWRcEVcEVcEVcEVcEVcEVcWRcrQcBkcsYcsYcsYcvucvucvucvucvuctbcDpcwzcsYcsYcsYcducrQaahaahcrXaAEcvxaAEcrXcrXcvycrXcrXcwFcwGcrZcrZcvBcrZcrZaAFcvDaAFcrZaAGcvFaAGcsacsacvGcsacsacvHcvIcsccsccvJcsccscaAHcvLaAHcscaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMaadaaacxfcvOcvPcvQcvRcvScvTcvUdEKdEJcvXcvYcvZcwacwbcwccuXcpXcpXcpXcpXcpXaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahaahcpjcwdcwecwfcwgcwdcpjdELdELdELahyahyahyahyahyahycpjcwhcwicwhcpjahyahyahyahyahyahyahycxAcqicqicqicwkcqicxAahyahyahyahyahyahycovcuncwlcwmcwncwocuncuncuqcwpcovahyahyahycsKcqycrOcrPcqycqycsKahyahyahyczZcPicEVcEVcEvcPocEVcEVcEVcrQcvucvucsYcsYcBicDqdBUcxPbdUctbcxRcsYcFdcFdcFdcFdcrQaahaahcrXcwBcwCcwDcPvcwDcwJcwHcwLcwKcwUcwTcwXcwVcwMcwNcwMcwOcwPcrZcwQcwRcwScPBcwScyacyecybcyqcyfcwYcwZcxacxbcxccxbcxdcxecscaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMaadaaacxNcxgcxgcxgcxgcvScvTcxhcxhcxicuXcxjcxkcxlcxmcxncuXcxocxpcxqcxraahaahaahaahaahcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxscxtcxucxvcxwcwhcwhcwhcwhcwhcwhcwhcwhcwhcwhcwhcxxcxycwhahyahyahyahyahyahyahyahycxzcyBcxBczkcxDcyBcxzahyahyahyahyahyahycovcovdHdcxFcxGcxHcxIcxJdHecovcovahyahyahycumcsScxLcxMcqyctucsOahyahyahyczZczZcEVcTdcQncUncEVcEVddacrQcEFcxPcsYcsYcxQcxQcxQcxQcxQctbcxRcsYcFdcFdcFdcFbcrQaahaahcrXcxVdEMcxXcxYcxZcytcyrcrXcyccydcrZcAkcyucygcyhcyidENcykcrZcyldEPcyncyocypcAqcAucsacyscAxcBocBncyvcywcyxcyydEQcyAcscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMaadaaacxNcxgcxgcxgcxgcvScvTcxhcxhcxicuXcxjcxkcxlcxmcxncuXcxocxpcxqcxraahaahaahaahaahcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxrcxscxtcxucxvcxwcwhcwhcwhcwhcwhcwhcwhcwhcwhcwhcwhcxxcxycwhahyahyahyahyahyahyahyahycxzcyBcxBczkcxDcyBcxzahyahyahyahyahyahycovcovdHdcxFcxGcxHcxIcxJdHecovcovahyahyahycumcsScxLcxMcqyctucsOahyahyahyczZczZcEVcTdcQncUncEVcEVddacrQcEFcxPcsYcsYcxQcxQcxQcxQcxQctbcxRcsYcFdcFdcFdcFbcrQaahaahcrXcxVaAKaAIcxYcxZcytcyrcrXcyccydcrZcAkcyucygcyhcyidENcykcrZcyldEPcyncyocypcAqcAucsacyscAxcBocBncyvcywcyxcyydEQcyAcscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMczTcyCcyDcyEcyFcxgcxgcvScyGcyHcyIcyJcyKcyLcyMaGXcyOcyPcuXcxqcxqcxqcxrcxrcxrcxrcxrcxrcxrcyQcyRcyScyScyScyScyScyScyScyScyScyScyScyTcyScyUcyVcyWcyXcyYcyVcyZczaczbczaczaczaczaczaczaczaczaczaczccwhahyahyahyahyahycxzcxzcxzcxzczdczebTgczgczhcxzcxzcxzcxzahyahyahyahycovcovcovcziczjczicovcovcovahyahyahyahyahycvacrOcrPcqycvaahyahyahyahyahyczZczZczZczZddeczZczZczZcrQcxQcxQcDocwycwycwycFccHvcHrcJzcHxcsYcFdcFdcFdcFdcrQaahaahcrXcrXcrXcrXcrXcrXcBqcrXcrXczpcuAcrZcrZcBrcrZcrZcrZcrZcrZcrZcsacsacsacsacsacBucsacsacuLcBvcsccsccsccsccsccsccsccsccscaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMczrczsczrczscztczuczvczwczxczyczzcxgcArczBczCczDczEcuXcuXczFczGczGczGczGczGczGczGczGczGczGczHcxqcxrcxrcxrcxrcxrczIczIczJcxrcOHczKcxqcxrczLczMczNczOczPcwhczQczQddgddmddkczQczQcwhcwhcwhcwhczRcwhahyahyahyahyahycxzczSczScABczUczVczWczXczYcAIcAacAacxzaahahyahyahyahyaahaahczicAbcziaahaahaahahyahyahyahyahycqvcAccAdcAecqvahyahyahyahyahyahyahyahycBgcWQcBgahyaahcrQcJNcxTcKMcxTcxTcFacFacKNcxTcxTcMecDrcFdcFdcFdcmYcrQaahaahaahaahaahaahcAicAjcBxaywcAicAmcAncAoayEcCccBbcAoaahaahaahaahaahaahaahcAscAtcClazxcAscAwcCmcAyazycAAcBAcAyaahaahaahaahaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcACcADcACcAEcAFcxgcxgcvScvTcAGczzcAHcBTcAJcAKcMdbWMcuXcxqcANcxqcxqcxrcxrcxrcxrcxrcxrcxrcxrcAOcxrcxraahaahaahcxrcAPcAPcAPcxrcxrcxrcxrcwdcwdcAQcARcAScwdcwdcwhcwhcwhcwhcwhczQcwhcwhaahaahcwhczRcwhaahahyahyahyahycxzcATczecAUcAVczeczeczgcAWcAXczecAYcxzaahahyahyaahaahaahaahczicAZcziaahaahaahcBacCScBccBacqvcqvcBdcBecBfcqvcBgcBgcBgcBgcBgahyahyahycBgcWQcBgaahaahcrQcvucvucMXcGzcGAcGAcGAcNJcGAcGzcNMcsYcNVcNVcNWcNXcrQaahaahcAicAicAicAicAicBmcDydHfcAiczpcBpcAocDDcDCcBscAocAocAocAocAocAscAscAscAscBtcDMdHgcAscBwcBvcAycFkcBycBzcAycAycAycAycAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcEBcyCcBBcBCcxgcxgcxgcBDcvTcAGczzcBEcuXcvrcvbcuXcuXcuXcxrcANcBFcxrcxraahaahaahaahaahaahcxrcBGcBHcxraahaahaahcBIcBIcBJcBIcBIaahaahaahaahcwdcBKcxucxvcwdaahaahaahaahaahcwhczQcwhaahaahaahcwhczRcwhaahaahaahahyahycxzcxzcxzcxzcBLcBMcBNcBOcbocxzcxzcxzcxzaahaahaahaahaahaahaahczicAbczicziczicBacBacymcBRcBacBScEIcrOcrPcqycBUcBgcBVcBWcBXcBgcBgahyahycBgcWQcBgaTWaahcrQcNRcxPcMXcGzcHscHtcHucNUdFccGzcNMcsYcPccPccPccOVcrQaahaahcAicBZcCacCbcAicAicFlcAicAicCdcvAcAocFmcCecAocAocCfcCgcChcAocCicCjcCkcAscAscFncAscAscvHcFycAycAycCncAycAycCocCpcCqcAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMczrczsczrczscztczuczvczwczxczyczzcxgcArczBczCczDczEcuXcuXczFczGczGczGczGczGczGczGczGczGczGczHcxqcxrcxrcxrcxrcxrczIczIczJcxrcOHczKcxqcxrczLczMczNczOczPcwhczQczQddgddmddkczQczQcwhcwhcwhcwhczRcwhahyahyahyahyahycxzczSczScABczUczVczWczXczYcAIcAacAacxzaahahyahyahyahyaahaahczicAbcziaahaahaahahyahyahyahyahycqvcAccAdcAecqvahyahyahyahyahyahyahyahycBgcWQcBgahyaahcrQcJNcxTcKMcxTcxTcFacFacKNcxTcxTcMecDrcFdcFdcFdcmYcrQaahaahcAicCbaEJcCbcAicAjcBxaywcAicAmcAncAoayEcCccBbcAocCfaFxcCfcAocCkaFzcCkcAscAtcClazxcAscAwcCmcAyazycAAcBAcAycCoaFRcCocAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaacaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcACcADcACcAEcAFcxgcxgcvScvTcAGczzcAHcBTcAJcAKcMdbWMcuXcxqcANcxqcxqcxrcxrcxrcxrcxrcxrcxrcxrcAOcxrcxraahaahaahcxrcAPcAPcAPcxrcxrcxrcxrcwdcwdcAQcARcAScwdcwdcwhcwhcwhcwhcwhczQcwhcwhaahaahcwhczRcwhaahahyahyahyahycxzcATczecAUcAVczeczeczgcAWcAXczecAYcxzaahahyahyaahaahaahaahczicAZcziaahaahaahcBacCScBccBacqvcqvcBdcBecBfcqvcBgcBgcBgcBgcBgahyahyahycBgcWQcBgaahaahcrQcvucvucMXcGzcGAcGAcGAcNJcGAcGzcNMcsYcNVcNVcNWcNXcrQaahaahcAiaGxaHMaGxcAicBmcDydHfcAiczpcBpcAocDDcDCcBscAoaJaaHOaJacAoaKbaJIaKbcAscBtcDMdHgcAscBwcBvcAycFkcBycBzcAyaKnaKpaKncAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcEBcyCcBBcBCcxgcxgcxgcBDcvTcAGczzcBEcuXcvrcvbcuXcuXcuXcxrcANcBFcxrcxraahaahaahaahaahaahcxrcBGcBHcxraahaahaahcBIcBIcBJcBIcBIaahaahaahaahcwdcBKcxucxvcwdaahaahaahaahaahcwhczQcwhaahaahaahcwhczRcwhaahaahaahahyahycxzcxzcxzcxzcBLcBMcBNcBOcbocxzcxzcxzcxzaahaahaahaahaahaahaahczicAbczicziczicBacBacymcBRcBacBScEIcrOcrPcqycBUcBgcBVcBWcBXcBgcBgahyahycBgcWQcBgaTWaahcrQcNRcxPcMXcGzcHscHtcHucNUdFccGzcNMcsYcPccPccPccOVcrQaahaahcAiaKqaKFaHMcAicAicFlcAicAicCdcvAcAocFmcCecAocAoaHOaKGaKHcAoaLuaLtaJIcAscAscFncAscAscvHcFycAycAycCncAycAyaKpaLxaLvcAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcACcADcACcCrcyFcxgcxgcvScvTcAGczzcCscCtcCucCvcCwcCxcCycCzcCAcxrcxraahaahaahaahaahaahaahcxrcCBcCCcxrcxraahaahcBIcBQcCEcCDcBIcCGcCGcCGaahcwdcCHcCIcCJcCKcCKcCKcCKcCKcCKcCKcCLcCKcCKaahahycwhczRcwhaahaahaahaahahycxzcCMcCNcABcCOczVcCPcCQcCRcEKcCTcCUcxzaahaahaahaahaahaahaahczicCVcCWcCXcCXcCYcCZcDacDbcDccDdcDecDfcDgcDhcDicBgcDjcDkcDlcDmcBgcBgcBgcBgcWQcQzcBgcBgcrQclXcxQcMXcGzcHscHtcIGcOYcHwcGzcNMcsYcQHcQHdERcPacrQaahaahcAicDtcDucDvcDwcDvcFAcFzcDzcDAcwIcDBcHFcHAcDEcDFcDEcDGcDHcAocDIcDJcDKcDLcDKcHGcHKcDOcwWcHNcDPcDQcDRcDScDTcDScDUcDVcAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcDWcDXcDWcDYcDZcEacEbcEccEdcEeczzcEfcCtcEgcEhcEicEjcEkcCtcxrcxraahaahaahaahaahaahaahaahcxrcElcEmcxqcxraahaahcBIcBQcCEcCDcBIcEncEocCGcCGcwdcEpcEqcErcCKcEscEtcEuddpcEwcEwcEwcExcCKahyahycwhczRcwhaahaahaahaahaahcxzcATczecEycAVczecEzczgcEAcFHczeczecxzaahaahaahaahaahaahaahczicECcEDcEEcEDcBackacEGcEHcFXcEJcGfcELcEMcENcEOcEPcEQcERcERcEScETcEUcEUcQecZMcEXcQfcEYcEZcxTcxTcQgcQhcHscJLcJMcQFcHwcGzcNMcQIcQGcQGcQGcQGcQGaahaahcAicFfdEScFhcFicFjcIKcIJcAicyccydcAocIPcILcFocFpcFqdEUcFscAocFtdEVcFvcFwcFxcIQcIRcAscyscAxcKacJRcFBcFCcFDcFEdEWcFGcAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaadcvMcvMcvMcvMcvMcvMcvMcGjcFIcFJcFKcDZcxgcxgcvScFLcyHcFMcFNcFOcFPcFQcFRcFScFTcCtaahaahaahaahaahaahaahaahaahaahcxrcElcFUcxqcxraahaahcBIcCFcCEcCDcBIcFWcGpcFYcFZcwdcGacGbcGccCKcGdcGecEwcEwcEwcEwcEwcEwcCKahyahycwhczRcwhaahaahaahaahaahcxzcxzcxzcxzcGqczecGgcGhcOIcGBczecGkcxzaahaahaahaahaahaahaahczicECcGlcziczicBacGmcGncGocGScEJcHccGrcrPcqycGscBgcGtcGucGvcGwcBgcBgcBgcGxcXdcERcERddqcrQcrQcrQcrQcrQcKJcKKcKLdhfcHwcGzcNMcQGcQGdkBdkBdlCcQGaahaahcAicAicAicAicAicAicKbcAicAiczpcuAcAocAocFmcAocAocAocAocAocAocAscAscAscAscAscKScAscAscuLcBvcAycAycAycAycAycAycAycAycAyaahaahaahaahaahaahaahaahaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
diff --git a/nano/css/icons.css b/nano/css/icons.css
index a6bec0f0d0..b2eacc0ab8 100644
--- a/nano/css/icons.css
+++ b/nano/css/icons.css
@@ -245,6 +245,32 @@
.uiIcon16.icon-note64 { background-image: url(uiIcons64.png); background-position: -64px -64px; width: 64px; height: 64px; }
.uiIcon16.icon-close64 { background-image: url(uiIcons64.png); background-position: -128px -64px; width: 64px; height: 64px; }
+.uiIcon16.icon-pill { background-image: url(pills32.png); width: 32px; height: 32px;}
+.uiIcon16.icon-pill.pill1 { background-position: 0 0; }
+.uiIcon16.icon-pill.pill2 { background-position: -32px 0; }
+.uiIcon16.icon-pill.pill3 { background-position: -64px 0; }
+.uiIcon16.icon-pill.pill4 { background-position: -96px 0; }
+.uiIcon16.icon-pill.pill5 { background-position: -128px 0; }
+.uiIcon16.icon-pill.pill6 { background-position: 0 -32px; }
+.uiIcon16.icon-pill.pill7 { background-position: -32px -32px; }
+.uiIcon16.icon-pill.pill8 { background-position: -64px -32px; }
+.uiIcon16.icon-pill.pill9 { background-position: -96px -32px; }
+.uiIcon16.icon-pill.pill10 { background-position: -128px -32px; }
+.uiIcon16.icon-pill.pill11 { background-position: 0 -64px; }
+.uiIcon16.icon-pill.pill12 { background-position: -32px -64px; }
+.uiIcon16.icon-pill.pill13 { background-position: -64px -64px; }
+.uiIcon16.icon-pill.pill14 { background-position: -96px -64px; }
+.uiIcon16.icon-pill.pill15 { background-position: -128px -64px; }
+.uiIcon16.icon-pill.pill16 { background-position: 0 -96px; }
+.uiIcon16.icon-pill.pill17 { background-position: -32px -96px; }
+.uiIcon16.icon-pill.pill18 { background-position: -64px -96px; }
+.uiIcon16.icon-pill.pill19 { background-position: -96px -96px; }
+.uiIcon16.icon-pill.pill20 { background-position: -128px -96px; }
+.uiIcon16.icon-pill.bottle1 { background-position: 0 -128px; }
+.uiIcon16.icon-pill.bottle2 { background-position: -32px -128px; }
+.uiIcon16.icon-pill.bottle3 { background-position: -64px -128px; }
+.uiIcon16.icon-pill.bottle4 { background-position: -96px -128px; }
+
.mapIcon16 {
position: absolute;
width: 16px;
diff --git a/nano/css/shared.css b/nano/css/shared.css
index a50f96a3c7..8728102b08 100644
--- a/nano/css/shared.css
+++ b/nano/css/shared.css
@@ -45,6 +45,19 @@ hr {
white-space: nowrap;
}
+.link32 {
+ float: left;
+ min-width: 15px;
+ max-width: 31px;
+ height: 31px;
+ text-align: center;
+ text-decoration: none;
+ background: #40628a;
+ border: 1px solid #161616;
+ margin: 0 2px 2px 0;
+ cursor: default;
+}
+
.hasIcon {
padding: 0px 4px 4px 0px;
}
@@ -249,7 +262,7 @@ div.notice {
overflow: auto;
}
-.itemContentNarrow, .itemContent {
+.itemContentNarrow, .itemContent, .itemContentWide, .itemContentSmall, .itemContentMedium {
float: left;
}
@@ -287,17 +300,14 @@ div.notice {
}
.itemContentWide {
- float: left;
width: 79%;
}
.itemContentSmall {
- float: left;
width: 33%;
}
.itemContentMedium {
- float: left;
width: 55%;
}
@@ -649,7 +659,7 @@ th.misc {
}
.oxyloss {
- color: blue;
+ color: #4444FF;
}
/* 75px width used in power monitoring console buttons */
diff --git a/nano/images/pills32.png b/nano/images/pills32.png
new file mode 100644
index 0000000000..61459093c1
Binary files /dev/null and b/nano/images/pills32.png differ
diff --git a/nano/templates/adv_med.tmpl b/nano/templates/adv_med.tmpl
new file mode 100644
index 0000000000..7f7e931caf
--- /dev/null
+++ b/nano/templates/adv_med.tmpl
@@ -0,0 +1,244 @@
+
+{{if !data.occupied}}
+ No occupant detected.
+{{else}}
+ Occupant Data:
+
+
+ Name:
+
+
+ {{:data.occupant.name}}
+
+
+
+
+ Health:
+
+ {{:helper.displayBar(data.occupant.health, 0, 100, (data.occupant.health >= 50) ? 'good' : (data.occupant.health >= 25) ? 'average' : 'bad')}}
+
+ {{:helper.round(data.occupant.health*10)/10}}%
+
+
+
+ Status:
+
+
+ {{if data.occupant.stat==0}}
+ Stable
+ {{else data.occupant.stat==1}}
+ Non-Responsive
+ {{else}}
+ Dead
+ {{/if}}
+
+
+ {{:helper.link('Print', 'document', {'print_p' : 1, 'name' : data.occupant.name})}}
+
Damage:
+
+
+ | Brute: |
+ {{:data.occupant.bruteLoss}} |
+ Brain: |
+ {{:data.occupant.brainLoss}} |
+
+
+ | Burn: |
+ {{:data.occupant.fireLoss}} |
+ Radiation: |
+ {{:data.occupant.radLoss}} |
+
+
+ | Oxygen: |
+ {{:data.occupant.oxyLoss}} |
+ Genetic: |
+ {{:data.occupant.cloneLoss}} |
+
+
+ | Toxins: |
+ {{:data.occupant.toxLoss}} |
+ Paralysis: |
+ {{:data.occupant.paralysis}}% ({{:data.occupant.paralysisSeconds}} seconds left!) |
+
+
+ | Body Temperature: |
+ {{:helper.round(data.occupant.bodyTempC*10)/10}}°C, {{:helper.round(data.occupant.bodyTempF*10)/10}}°F |
+
+
+
+ {{if data.occupant.hasVirus}}
+
+ Viral pathogen detected in blood stream.
+
+ {{/if}}
+ {{if data.occupant.hasBorer}}
+
+ Large growth detected in frontal lobe, possibly cancerous. Surgical removal is recommended.
+
+ {{/if}}
+ {{if data.occupant.blind}}
+ Pupils unresponsive.
+ {{/if}}
+ {{if data.occupant.nearsighted}}
+ Retinal Misalignment Detected
+ {{/if}}
+ Blood
+
+
+ | Volume: |
+ {{:data.occupant.blood.volume}} |
+ Percent: |
+ {{:data.occupant.blood.percent}}% |
+
+
+ Reagents
+ {{if data.occupant.reagents}}
+
+ {{for data.occupant.reagents}}
+
+ | {{:value.name}}: |
+ {{:value.amount}} |
+
+ {{/for}}
+
+ {{else}}
+ No reagents detected.
+ {{/if}}
+ External Organs
+
+ {{for data.occupant.extOrgan}}
+
+ {{if value.status.destroyed}}
+
+ {{:value.name}} - DESTROYED
+
+ {{else}}
+
+
+ {{if value.status.broken}}
+ {{:value.status.broken}}
+ {{else value.status.splinted}}
+ Splinted
+ {{else value.status.robotic}}
+ Robotic
+ {{/if}}
+
+
+ Brute/Burn
+
+
+ {{:value.bruteLoss}}/{{:value.fireLoss}}
+
+
+ Injuries
+
+
+ {{if !value.status.bleeding}}
+ {{if !value.status.internalBleeding}}
+ No Injuries Detected
+ {{else}}
+
Internal Bleeding Detected
+ {{/if}}
+ {{else}}
+ {{if value.status.internalBleeding}}
+
Internal Bleeding Detected. External Bleeding Detected.
+ {{else}}
+
External Bleeding Detected
+ {{/if}}
+ {{/if}}
+
+ {{if value.germ_level > 100}}
+
+ Infection
+
+
+ {{if value.germ_level < 300}}
+ Mild Infection
+ {{else value.germ_level < 400}}
+ Mild Infection+
+ {{else value.germ_level < 500}}
+ Mild Infection++
+ {{else value.germ_level < 700}}
+ Acute Infection
+ {{else value.germ_level < 800}}
+ Acute Infection+
+ {{else value.germ_level < 900}}
+ Acute Infection++
+ {{else value.germ_level >= 900}}
+ Septic
+ {{/if}}
+
+ {{/if}}
+ {{if value.open}}
+
+ Operation Status
+
+
+ Open Incision
+
+ {{/if}}
+ {{if value.implants_len}}
+
+ Implants
+
+ {{for value.implants :impValue:impindex}}
+
+ {{:impValue.known ? impValue.name : "Unknown"}}
+
+ {{/for}}
+ {{/if}}
+ {{/if}}
+
+ {{/for}}
+
+ Internal Organs
+
+ {{for data.occupant.intOrgan}}
+
+
+ {{:value.name}}
+
+
+ {{:value.desc != null ? value.desc : ""}}
+
+
+
+ {{if value.germ_level > 100}}
+
+ Infection
+
+
+ {{if value.germ_level < 300}}
+ Mild Infection
+ {{else value.germ_level < 400}}
+ Mild Infection+
+ {{else value.germ_level < 500}}
+ Mild Infection++
+ {{else value.germ_level < 700}}
+ Acute Infection
+ {{else value.germ_level < 800}}
+ Acute Infection+
+ {{else value.germ_level < 900}}
+ Acute Infection++
+ {{else value.germ_level >= 900}}
+ Septic
+ {{/if}}
+
+ {{/if}}
+
+ Damage
+
+
+ {{:value.damage}}
+
+
+ {{/for}}
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/arcade_battle.tmpl b/nano/templates/arcade_battle.tmpl
new file mode 100644
index 0000000000..7725698634
--- /dev/null
+++ b/nano/templates/arcade_battle.tmpl
@@ -0,0 +1,30 @@
+
+
+{{:data.enemyName}}
+{{if data.gameOver}}
+ {{:data.temp}}
+{{else}}
+ {{:data.temp}}
+ {{:data.enemyAction}}
+{{/if}}
+
+
Health:
+
{{:data.playerHP}}
+
Magic:
+
{{:data.playerMP}}
+
Enemy Health:
+
{{:data.enemyHP}}
+
+
+{{if data.gameOver}}
+ {{:helper.link('New Game', null, {'newgame' : 1})}}
+{{else}}
+
+ {{:helper.link('Attack', null, {'attack' : 1})}}
+ {{:helper.link('Heal', null, {'heal' : 1})}}
+ {{:helper.link('Recharge Power', null, {'charge' : 1})}}
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/atmo_control.tmpl b/nano/templates/atmo_control.tmpl
new file mode 100644
index 0000000000..5e68b8cd66
--- /dev/null
+++ b/nano/templates/atmo_control.tmpl
@@ -0,0 +1,224 @@
+
+{{if data.sensors}}
+ {{for data.sensors}}
+ {{if value.sensor_data}}
+
+
{{:value.long_name}}
+ {{if value.sensor_data.pressure}}
+
+
Pressure:
+
{{:value.sensor_data.pressure}} kPa
+
+ {{/if}}
+ {{if value.sensor_data.temperature}}
+
+
Temperature:
+
{{:value.sensor_data.temperature}} kPa
+
+ {{/if}}
+ {{if value.sensor_data.oxygen || value.sensor_data.nitrogen || value.sensor_data.carbon_dioxide || value.sensor_data.phoron}}
+
+
Gas Composition:
+ {{if value.sensor_data.oxygen}}
+
{{:value.sensor_data.oxygen}}% O2
+ {{/if}}
+ {{if value.sensor_data.nitrogen}}
+
{{:value.sensor_data.nitrogen}}% N
+ {{/if}}
+ {{if value.sensor_data.carbon_dioxide}}
+
{{:value.sensor_data.carbon_dioxide}}% CO2
+ {{/if}}
+ {{if value.sensor_data.phoron}}
+
{{:value.sensor_data.phoron}}% TX
+ {{/if}}
+
+ {{/if}}
+
+ {{else}}
+
+
{{:value.long_name}} can not be found!
+
+ {{/if}}
+ {{/for}}
+{{else}}
+
+ No sensors connected.
+
+{{/if}}
+
+{{if data.tanks || data.core}}
+
+ {{if data.tanks}}
+ Tank Control System
+ {{else data.core}}
+ Core Cooling Control System
+ {{/if}}
+
+
+ {{if data.input_info}}
+
+
+ {{if data.tanks}}
+ Input:
+ {{else data.core}}
+ Coolant Input:
+ {{/if}}
+
+
+ {{if data.input_info.power}}
+ Injecting
+ {{else}}
+ On Hold
+ {{/if}}
+
+
+
+
Flow Rate Limit:
+
{{:data.input_info.volume_rate}} L/s
+
+
+
Command:
+ {{:helper.link('Toggle Power', 'power', {'in_toggle_injector' : 1})}}
+ {{:helper.link('Set Flow Rate', 'pencil', {'in_set_flowrate' : 1})}}
+ {{:helper.link('Refresh', 'refresh', {'in_refresh_status' : 1})}}
+
+ {{else}}
+
+
ERROR: Can not find input port
+ {{:helper.link('Search', 'search', {'in_refresh_status' : 1})}}
+
+ {{/if}}
+
+
+ Flow Rate Limit:
+
+
+ {{:helper.link('100', 'minus', {'adj_input_flow_rate' : -100})}}
+ {{:helper.link('10', 'minus', {'adj_input_flow_rate' : -10})}}
+ {{:helper.link('1', 'minus', {'adj_input_flow_rate' : -1})}}
+ {{:helper.link('0.1', 'minus', {'adj_input_flow_rate' : -0.1})}}
+
{{:data.input_flow_setting}} L/s
+ {{:helper.link('0.1', 'plus', {'adj_input_flow_rate' : 0.1})}}
+ {{:helper.link('1', 'plus', {'adj_input_flow_rate' : 1})}}
+ {{:helper.link('10', 'plus', {'adj_input_flow_rate' : 10})}}
+ {{:helper.link('100', 'plus', {'adj_input_flow_rate' : 100})}}
+
+
+
+ {{if data.output_info}}
+
+
+ {{if data.tanks}}
+ Output:
+ {{else data.core}}
+ Core Outpump:
+ {{/if}}
+
+
+ {{if data.output_info.power}}
+ Open
+ {{else}}
+ On Hold
+ {{/if}}
+
+
+
+ {{if data.tanks}}
+
Max Output Pressure:
+
{{:data.output_info.output_pressure}} kPa
+ {{else data.core}}
+
Min Core Pressure:
+
{{:data.output_info.pressure_limit}} kPa
+ {{/if}}
+
+
+
Command:
+ {{:helper.link('Toggle Power', 'power', {'out_toggle_power' : 1})}}
+ {{:helper.link('Set Pressure', 'pencil', {'out_set_pressure' : 1})}}
+ {{:helper.link('Refresh', 'refresh', {'out_refresh_status' : 1})}}
+
+ {{else}}
+
+
ERROR: Can not find output port
+ {{:helper.link('Search', 'search', {'out_refresh_status' : 1})}}
+
+ {{/if}}
+
+
+ {{if data.tanks}}
+
+ Max Output Pressure Set:
+
+
+ {{:helper.link('1000', 'minus', {'adj_pressure' : -1000})}}
+ {{:helper.link('100', 'minus', {'adj_pressure' : -100})}}
+ {{:helper.link('10', 'minus', {'adj_pressure' : -10})}}
+ {{:helper.link('1', 'minus', {'adj_pressure' : -1})}}
+
{{:data.pressure_setting}} kPa
+ {{:helper.link('1', 'plus', {'adj_pressure' : 1})}}
+ {{:helper.link('10', 'plus', {'adj_pressure' : 10})}}
+ {{:helper.link('100', 'plus', {'adj_pressure' : 100})}}
+ {{:helper.link('1000', 'plus', {'adj_pressure' : 1000})}}
+
+ {{else data.core}}
+
+ Min Core Pressure Set:
+
+
+ {{:helper.link('100', 'minus', {'adj_pressure' : -100})}}
+ {{:helper.link('50', 'minus', {'adj_pressure' : -50})}}
+ {{:helper.link('10', 'minus', {'adj_pressure' : -10})}}
+ {{:helper.link('1', 'minus', {'adj_pressure' : -1})}}
+
{{:data.pressure_setting}} kPa
+ {{:helper.link('1', 'plus', {'adj_pressure' : 1})}}
+ {{:helper.link('10', 'plus', {'adj_pressure' : 10})}}
+ {{:helper.link('50', 'plus', {'adj_pressure' : 50})}}
+ {{:helper.link('100', 'plus', {'adj_pressure' : 100})}}
+
+ {{/if}}
+
+{{/if}}
+
+{{if data.fuel}}
+ Fuel Injection System
+
+ {{if data.device_info}}
+
+
+ Status:
+
+
+ {{if data.device_info.power}}
+ Injecting
+ {{else}}
+ On Hold
+ {{/if}}
+
{{:helper.link('Refresh', 'refresh', {'refresh_status' : 1})}}
+
+
+
+
Rate:
+
{{:data.device_info.volume_rate}} L/s
+
+
+
Automated Fuel Injection:
+ {{if data.automation}}
+ {{:helper.link('Engaged', 'check', {'toggle_automation' : 1})}}
+
Injector Controls Locked Out
+ {{else}}
+ {{:helper.link('Disengaged', 'close', {'toggle_automation' : 1})}}
+
Injector:
+ {{:helper.link('Toggle Power', 'power', {'toggle_injector' : 1})}}
+ {{:helper.link('Inject (1 Cycle)', 'syringe', {'injection' : 1})}}
+ {{/if}}
+
+ {{else}}
+
+
ERROR: Can not find device
+ {{:helper.link('Search', 'search', {'refresh_status' : 1})}}
+
+ {{/if}}
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/chem_master.tmpl b/nano/templates/chem_master.tmpl
new file mode 100644
index 0000000000..1b8315154a
--- /dev/null
+++ b/nano/templates/chem_master.tmpl
@@ -0,0 +1,116 @@
+
+{{if data.tab == 'home'}}
+
+
{{:helper.link(data.pillBottle ? 'Eject Pill Bottle' : 'No pill bottle inserted', 'eject', {'ejectp' : 1}, data.pillBottle ? null : 'linkOff')}}
+
+ {{if data.pillBottle}}
+
{{:data.pillBottle.total}} / {{:data.pillBottle.max}}
+ {{/if}}
+
+ {{:helper.link(data.beaker ? 'Eject Beaker and Clear Buffer' : 'Please insert beaker', 'eject', {'eject' : 1}, data.beaker ? null : 'linkOff')}}
+
+ {{if data.beaker}}
+ {{if data.beaker.total_volume}}
+ Add to buffer:
+ {{for data.beaker.reagent_list}}
+
+
{{:value.name}}
+
{{:value.volume}} Units
+
+
+ {{:helper.link('Analyze', 'signal-diag', {'tab_select' : 'analyze', 'desc' : value.description, 'name' : value.name})}}
+ {{:helper.link('1', 'plus', {'add' : value.id, 'amount' : 1})}}
+ {{:helper.link('5', 'plus', {'add' : value.id, 'amount' : 5})}}
+ {{:helper.link('10', 'plus', {'add' : value.id, 'amount' : 10})}}
+ {{:helper.link('30', 'plus', {'add' : value.id, 'amount' : 30})}}
+ {{:helper.link('60', 'plus', {'add' : value.id, 'amount' : 60})}}
+ {{:helper.link('All', 'plus', {'add' : value.id, 'amount' : value.volume})}}
+ {{:helper.link('Custom', 'plus', {'addcustom' : value.id})}}
+
+ {{/for}}
+ {{else}}
+ Beaker is empty.
+ {{/if}}
+
+
+
Transfer to
+ {{:helper.link(!data.mode ? 'disposal' : 'beaker', null, {'toggle' : 1})}}
+
+ {{if data.reagents}}
+ {{if data.reagents.total_volume}}
+ {{for data.reagents.reagent_list}}
+
+
{{:value.name}}
+
{{:value.volume}} Units
+
+
+ {{:helper.link('Analyze', 'signal-diag', {'tab_select' : 'analyze', 'desc' : value.description, 'name' : value.name})}}
+ {{:helper.link('1', 'minus', {'remove' : value.id, 'amount' : 1})}}
+ {{:helper.link('5', 'minus', {'remove' : value.id, 'amount' : 5})}}
+ {{:helper.link('10', 'minus', {'remove' : value.id, 'amount' : 10})}}
+ {{:helper.link('30', 'minus', {'remove' : value.id, 'amount' : 30})}}
+ {{:helper.link('60', 'minus', {'remove' : value.id, 'amount' : 60})}}
+ {{:helper.link('All', 'minus', {'remove' : value.id, 'amount' : value.volume})}}
+ {{:helper.link('Custom', 'minus', {'removecustom' : value.id})}}
+
+ {{/for}}
+ {{/if}}
+ {{else}}
+ Empty
+ {{/if}}
+ {{if !data.condi}}
+
+
+ {{:helper.link('Create pill (60 units max)', null, {'createpill' : 1})}}
+ {{:helper.link('Create multiple pills', null, {'createpill_multiple' : 1})}}
+ {{:helper.link('Create bottle (60 units max)', null, {'createbottle' : 1})}}
+
+
+ {{:helper.link('', 'pill pill' + data.pillSprite, {'tab_select' : 'pill'}, null, 'link32')}}
+ {{:helper.link('', 'pill bottle' + data.bottleSprite, {'tab_select' : 'bottle'}, null, 'link32')}}
+
+ {{/if}}
+ {{/if}}
+
+{{else data.tab == 'analyze'}}
+ {{if !data.condi}}
+ Chemical Info:
+ {{else}}
+ Condiment Info:
+ {{/if}}
+
+
Name:
+
{{:data.analyzeData.name}}
+
+ {{if data.analyzeData.name == 'Blood'}}
+
+
Blood Type:
+
{{:data.analyzeData.blood_type}}
+
+
+
DNA:
+
{{:data.analyzeData.blood_DNA}}
+
+ {{else}}
+
+
Description:
+
{{:data.analyzeData.desc}}
+
+ {{/if}}
+ {{:helper.link('Back', 'arrowreturn-1-w', {'tab_select' : 'home'})}}
+
+{{else data.tab == 'pill'}}
+ {{for data.pillSpritesAmount}}
+ {{:helper.link('', 'pill pill' + value, {'pill_sprite' : value}, null, data.pillSprite == value ? 'linkOn link32' : 'link32')}}
+ {{/for}}
+
{{:helper.link('Return', 'arrowreturn-1-w', {'tab_select' : 'home'})}}
+
+{{else data.tab == 'bottle'}}
+ {{for data.bottleSpritesAmount}}
+ {{:helper.link('', 'pill bottle' + value, {'bottle_sprite' : value}, null, data.bottleSprite == value ? 'linkOn link32' : 'link32')}}
+ {{/for}}
+
{{:helper.link('Return', 'arrowreturn-1-w', {'tab_select' : 'home'})}}
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/cloning.tmpl b/nano/templates/cloning.tmpl
new file mode 100644
index 0000000000..a927fcc4d9
--- /dev/null
+++ b/nano/templates/cloning.tmpl
@@ -0,0 +1,104 @@
+
+
+{{:data.temp}}
+
+{{if data.menu == 1}}
+
+ Modules
+
+ {{if data.connected}}
+ DNA scanner found.
+ {{else}}
+ DNA scanner not found.
+ {{/if}}
+
+
+ {{if data.podsLen > 0}}
+ {{:data.podsLen}} cloning vat\s found.
+ {{else}}
+ No cloning vats found.
+ {{/if}}
+
+
+
+ Scanner Functions
+
+ {{if data.loading}}
+ Scanning...
+ {{else}}
+ {{:data.scantemp}}
+ {{/if}}
+
+
+ {{if data.connected}}
+
+ {{:helper.link(data.occupant ? 'Scan - ' + data.occupant : 'Scanner unoccupied', 'play', {'scan' : 1}, data.occupant ? null : 'linkOff')}}
+
+
+ {{:helper.link(data.locked ? 'Unlock' : 'Lock', data.locked ? 'locked' : 'unlocked', {'lock' : 1}, null, data.locked ? 'redButton' : null)}}
+
+
+ {{:helper.link('Eject', 'eject', {'eject' : 1}, data.occupant ? null : 'linkOff')}}
+
+ {{else}}
+ No scanner connected!
+ {{/if}}
+
+
+ {{if data.podsLen}}
+ {{for data.pods}}
+ {{:value.pod}}, biomass: {{:value.biomass}}
+ {{/for}}
+ {{/if}}
+
+
+ Database Functions
+
+ {{:helper.link('View Records', 'list', {'menu' : 2})}}
+ {{:helper.link('Eject Disk', 'eject', {'disk' : 'eject'}, data.diskette ? null : 'linkOff')}}
+
+
+{{else data.menu == 2}}
+ Current records
+ {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 1})}}
+
+ {{for data.records}}
+ {{:helper.link(value.name, 'document', {'view_rec' : value.ckey})}}
+ {{/for}}
+
+
+{{else data.menu == 3}}
+ Selected Record
+ {{:helper.link('Back', 'arrowreturn-1-w', {'menu' : 2})}}
+
+ {{if data.activeRecord}}
+ {{:helper.link('Delete Record', 'trash', {'del_rec' : 1}, null, 'redButton')}}
+
+
Name:
+
{{:data.activeRecord.real_name}}
+
+
+ {{:helper.link('Load from disk', 'transfer-e-w', {'disk' : 'load'}, data.disk ? null : 'linkOff')}}
+
+
+
Save:
+ {{:helper.link('UI + UE', 'disk', {'save_disk' : 'ue'}, data.disk ? null : 'linkOff')}}
+ {{:helper.link('UI', 'disk', {'save_disk' : 'ui'}, data.disk ? null : 'linkOff')}}
+ {{:helper.link('SE', 'disk', {'save_disk' : 'se'}, data.disk ? null : 'linkOff')}}
+
+
+ {{:helper.link('Clone', 'play', {'clone' : data.activeRecord.ckey}, data.podsLen ? null : 'linkOff')}}
+
+ {{else}}
+ ERROR: Record not found.
+ {{/if}}
+
+{{else data.menu == 4}}
+ {{:data.temp}}
+ Confirm Record Deletion
+ Scan card to confirm.
+ {{:helper.link('Cancel', 'cancel', {'menu' : 3})}}
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/fax.tmpl b/nano/templates/fax.tmpl
new file mode 100644
index 0000000000..4745a7aeb3
--- /dev/null
+++ b/nano/templates/fax.tmpl
@@ -0,0 +1,55 @@
+
+
+
+
+ Confirm Identity:
+
+ {{:helper.link(data.scanName ? data.scanName : 'Insert Card', 'check', {'scan' : 1})}}
+ {{if data.authenticated}}
+ {{:helper.link('Log Out', 'eject', {'logout' : 1}, null, 'redButton')}}
+ {{else}}
+ {{:helper.link('Log In', 'person', {'auth' : 1}, data.scanName ? null : 'linkOff')}}
+ {{/if}}
+
+{{if data.authenticated}}
+
+
+
+
+
+ Logged in to:
+
+
+ {{:data.bossName}} Quantum Entanglement Network
+
+
+ {{if data.copyItem}}
+ {{if data.cooldown}}
+ Transmitter arrays realigning. Please stand by.
+ {{else}}
+
+
Currently sending:
+
{{:data.copyItemName}}
+
+
+
Sending to:
+ {{:helper.link(data.destination, 'tag', {'dept' : 1})}}
+
+ {{:helper.link('Send', 'signal-diag', {'send' : 1})}}
+ {{/if}}
+ {{else}}
+ Please insert paper to send via secure connection.
+ {{if data.cooldown}}
+ Transmitter arrays realigning. Please stand by.
+ {{/if}}
+ {{/if}}
+{{else}}
+ Proper authentication is required to use this device.
+{{/if}}
+{{if data.copyItem}}
+ {{:helper.link('Remove Item', 'eject', {'remove' : 1})}}
+{{/if}}
+
diff --git a/nano/templates/guest_pass.tmpl b/nano/templates/guest_pass.tmpl
new file mode 100644
index 0000000000..80525f5331
--- /dev/null
+++ b/nano/templates/guest_pass.tmpl
@@ -0,0 +1,59 @@
+
+
+{{if data.mode == 1}}
+
+
+ Activity Log
+
+ {{:helper.link('Print', 'print', {'print' : 1})}} {{:helper.link('Back', 'arrowreturn-1-w', {'mode' : 0})}}
+
+
+ {{for data.log}}
+
+ {{:value}}
+
+ {{/for}}
+{{else}}
+ Guest pass terminal #{{:data.uid}}
+
+ {{:helper.link('View activity log', 'list', {'mode' : 1})}} {{:helper.link('Issure Pass', 'eject', {'action' : 'issue'})}}
+
+
+
+
+ Issuing ID:
+
+ {{:helper.link(data.giver ? data.giver : 'Insert ID', 'person', {'action' : 'id'})}}
+
+
+
+ Issued to:
+
+ {{:helper.link(data.giveName, 'pencil', {'choice' : 'giv_name'})}}
+
+
+
+ Reason:
+
+ {{:helper.link(data.reason, 'pencil', {'choice' : 'reason'})}}
+
+
+
+ Duration (minutes):
+
+ {{:helper.link(data.duration, 'clock', {'choice' : 'duration'})}}
+
+
+ {{for data.area}}
+
+ {{:helper.link(value.area_name, value.on ? 'check' : 'close', {'choice' : 'access', 'access' : value.area}, null, value.on ? 'linkOn' : null)}}
+
+ {{/for}}
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/holodeck.tmpl b/nano/templates/holodeck.tmpl
new file mode 100644
index 0000000000..71d4ad5605
--- /dev/null
+++ b/nano/templates/holodeck.tmpl
@@ -0,0 +1,36 @@
+
+
+Current Loaded Programs:
+{{for data.supportedPrograms}}
+ {{:helper.link(value.name, data.currentProgram == value.program ? 'check' : 'close', {'program' : value.program}, null, data.currentProgram == value.program ? 'linkOn' : null)}}
+{{/for}}
+Please ensure that only holographic weapons are used in the holodeck if a combat simulation has been loaded.
+{{if data.isSilicon}}
+ {{if data.safetyDisabled}}
+ {{if data.emagged}}
+ ERROR: Cannot re-enable Safety Protocols.
+ {{else}}
+ {{:helper.link('Re-Enable Safety Protocols?', 'help', {'AIoverride' : 1}, null, 'linkOn')}}
+ {{/if}}
+ {{else}}
+ {{:helper.link('Re-Enable Safety Protocols?', 'help', {'AIoverride' : 1}, null, 'redButton')}}
+ {{/if}}
+{{/if}}
+
+{{if data.safetyDisabled}}
+ {{for data.restrictedPrograms}}
+ {{:helper.link('Begin ' + value.name, data.currentProgram == value.program ? 'check' : 'close', {'program' : value.program}, null, data.currentProgram == value.program ? 'linkOn' : null)}}
+ {{/for}}
+ Ensure the holodeck is empty before testing.
+ Safety Protocols are DISABLED
+{{else}}
+ Safety Protocols are ENABLED
+{{/if}}
+
+
+
Gravity:
+ {{:helper.link(data.gravity ? 'On ' : 'Off', data.gravity ? 'check' : 'close', {'gravity' : 1}, null, data.gravity ? 'linkOn' : 'redButton')}}
+
\ No newline at end of file
diff --git a/nano/templates/laptop_vendor.tmpl b/nano/templates/laptop_vendor.tmpl
new file mode 100644
index 0000000000..e0de4f7272
--- /dev/null
+++ b/nano/templates/laptop_vendor.tmpl
@@ -0,0 +1,173 @@
+
+
+{{if data.mode == 0}}
+
+ Please choose your laptop customization options.
+ Your comptuer will automatically be loaded with any programs you can use after the transaction is complete.
+ Some programs will require additional components to be installed!
+
+
+
+
+
+
HDD (Required):
+
Added
+
+
+
+
+ Card Reader:
+
+ {{:helper.link('Single (50)', data.cardreader == 1 ? 'check' : 'plus', {'choice' : 'single_add'}, data.cardreader == 1 ? 'selected' : null)}}
+ {{:helper.link('Dual (125)', data.cardreader == 2 ? 'check' : 'plus', {'choice' : 'dual_add'}, data.cardreader == 2 ? 'selected' : null)}}
+ {{:helper.link('None', 'close', {'choice' : 'cardreader_rem'}, data.cardreader == 0 ? 'redButton' : null)}}
+
+
+
+
+ Floppy Drive:
+
+ {{:helper.link('Add (50)', data.floppy == 1 ? 'check' : 'plus', {'choice' : 'floppy_add'}, data.floppy == 1 ? 'selected' : null)}}
+ {{:helper.link('None', 'close', {'choice' : 'floppy_rem'}, data.floppy == 0 ? 'redButton' : null)}}
+
+
+
+
+ Radio card:
+
+ {{:helper.link('Add (50)', data.radionet == 1 ? 'check' : 'plus', {'choice' : 'radio_add'}, data.radionet == 1 ? 'selected' : null)}}
+ {{:helper.link('None', 'close', {'choice' : 'radio_rem'}, data.radionet == 0 ? 'redButton' : null)}}
+
+
+
+
+ Camera Card:
+
+ {{:helper.link('Add (100)', data.camera == 1 ? 'check' : 'plus', {'choice' : 'camnet_add'}, data.camera == 1 ? 'selected' : null)}}
+ {{:helper.link('None', 'close', {'choice' : 'camnet_rem'}, data.camera == 0 ? 'redButton' : null)}}
+
+
+
+
+ Network card:
+
+
+ {{:helper.link('Area (75)', data.network == 1 ? 'check' : 'plus', {'choice' : 'area_add'}, data.network == 1 ? 'selected' : null)}}
+ {{:helper.link('Adjacent (50)', data.network == 2 ? 'check' : 'plus', {'choice' : 'prox_add'}, data.network == 2 ? 'selected' : null)}}
+ {{:helper.link('Powernet (25)', data.network == 3 ? 'check' : 'plus', {'choice' : 'cable_add'}, data.network == 3 ? 'selected' : null)}}
+ {{:helper.link('None', 'close', {'choice' : 'network_rem'}, data.network == 0 ? 'redButton' : null)}}
+
+
+
+
+
+
+
+ Power Source:
+
+ {{:helper.link('Extended (175)', data.power == 1 ? 'check' : 'plus', {'choice' : 'high_add'}, data.power == 1 ? 'selected' : null)}}
+ {{:helper.link('Unreal (250)', data.power == 2 ? 'check' : 'plus', {'choice' : 'super_add'}, data.power == 2 ? 'selected' : null)}}
+ {{:helper.link('Default', data.power == 0 ? 'check' : 'plus', {'choice' : 'power_rem'}, data.power == 0 ? 'selected' : null)}}
+
+
+
+
+
Total:
+
{{:data.total}}
+ {{:helper.link('Vend Laptop', 'cart', {'choice' : 'vend'})}}
+
+
+{{else data.mode == 1}}
+ Cart
+
+
+
+
+
Total:
+
{{:data.total}}
+
+
+
+
Card Reader:
+ {{if data.cardreader == 1}}
+ {{:helper.link('(single) (50)', 'close', {'choice' : 'cardreader_rem'})}}
+ {{else data.cardreader == 2}}
+ {{:helper.link('(double) (125)', 'close', {'choice' : 'cardreader_rem'})}}
+ {{else}}
+
None
+ {{/if}}
+
+
+
+
Floppy Drive:
+ {{if data.floppy == 1}}
+ {{:helper.link('Added (50)', 'close', {'choice' : 'floppy_rem'})}}
+ {{else}}
+
None
+ {{/if}}
+
+
+
+
Radio Card:
+ {{if data.radionet == 1}}
+ {{:helper.link('Added (50)', 'close', {'choice' : 'radio_rem'})}}
+ {{else}}
+
None
+ {{/if}}
+
+
+
+
Camera Card:
+ {{if data.camera == 1}}
+ {{:helper.link('Added (100)', 'close', {'choice' : 'camnet_rem'})}}
+ {{else}}
+
None
+ {{/if}}
+
+
+
+
Network Card:
+ {{if data.network == 1}}
+ {{:helper.link('Area (75)', 'close', {'choice' : 'network_rem'})}}
+ {{else data.network == 2}}
+ {{:helper.link('Adjacent (50)', 'close', {'choice' : 'network_rem'})}}
+ {{else data.network == 3}}
+ {{:helper.link('Powernet (25)', 'close', {'choice' : 'network_rem'})}}
+ {{else}}
+
None
+ {{/if}}
+
+
+
+
Power Source:
+ {{if data.power == 1}}
+ {{:helper.link('Unreal (250)', 'close', {'choice' : 'power_rem'})}}
+ {{else data.power == 2}}
+ {{:helper.link('Extended (175)', 'close', {'choice' : 'power_rem'})}}
+ {{else}}
+
Regular
+ {{/if}}
+
+
+
+
+
+
Please swipe your card and enter your PIN to complete the transaction
+
+
+
+
+ {{:helper.link('Cancel', 'close', {'choice' : 'cancel'}, null, 'redButton')}}
+
+{{else data.mode == 2}}
+
+ Please swipe your card and enter your PIN to finish returning your computer.
+
+
+
+ {{:helper.link('Cancel', 'close', {'choice' : 'cancel'}, null, 'redButton')}}
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/operating.tmpl b/nano/templates/operating.tmpl
new file mode 100644
index 0000000000..c53bd94c65
--- /dev/null
+++ b/nano/templates/operating.tmpl
@@ -0,0 +1,47 @@
+
+
+{{if data.table}}
+ Patient Information:
+ {{if data.victim}}
+
+
Name:
+
{{:data.victim.real_name}}
+
+
Age:
+
{{:data.victim.age}}
+
+
Blood Type:
+
{{:data.victim.b_type}}
+
+
+
+
Health:
+
{{:data.victim.health}}
+
+
Brute Damage:
+
{{:data.victim.brute}}
+
+
Toxins Damage:
+
{{:data.victim.tox}}
+
+
Fire Damage:
+
{{:data.victim.burn}}
+
+
Suffocation Damage:
+
{{:data.victim.oxy}}
+
+
Patient Status:
+
{{:data.victim.stat}}
+
+
Heartbeat Rate:
+
{{:data.victim.pulse}}
+
+ {{else}}
+ No Patient Detected
+ {{/if}}
+{{else}}
+ No Table Detected
+{{/if}}
diff --git a/nano/templates/photocopier.tmpl b/nano/templates/photocopier.tmpl
new file mode 100644
index 0000000000..9c9910e969
--- /dev/null
+++ b/nano/templates/photocopier.tmpl
@@ -0,0 +1,47 @@
+
+
+{{if data.copyItem}}
+
+ {{:helper.link('Remove Item', 'eject', {'remove' : 1})}}
+ {{if data.toner}}
+ {{:helper.link('Copy', 'copy', {'copy' : 1})}}
+
+
+
+ Printing:
+
+
+
+ {{:helper.link('-', null, {'min' : 1}, data.copies == 1 ? 'linkOff' : null)}}
+
{{:data.copies}}
+ {{:helper.link('+', null, {'add' : 1}, data.copies == data.maxCopies ? 'linkOff' : null)}}
+
+
+
+
+
+
Current toner level:
+
{{:data.toner}}u
+
+ {{else}}
+
+ Please insert a new toner cartridge!
+
+ {{/if}}
+{{else data.toner}}
+ Please insert something to copy.
+ {{if data.isSilicon}}
+ {{:helper.link('Print photo from database', 'image', {'aipic' : 1})}}
+ {{/if}}
+
+
Current toner level:
+
{{:data.toner}}u
+
+{{else}}
+
+ Please insert a new toner cartridge!
+
+{{/if}}
\ No newline at end of file
diff --git a/nano/templates/uplink.tmpl b/nano/templates/uplink.tmpl
index ed799677bc..470f27064c 100644
--- a/nano/templates/uplink.tmpl
+++ b/nano/templates/uplink.tmpl
@@ -77,16 +77,17 @@ Used In File(s): \code\game\objects\items\devices\uplinks.dm
{{if data.exploit_exists == 1}}
- Name: {{:data.exploit.name}}
- Sex: {{:data.exploit.sex}}
- Species: {{:data.exploit.species}}
- Age: {{:data.exploit.age}}
- Rank: {{:data.exploit.rank}}
- Home System: {{:data.exploit.home_system}}
- Citizenship: {{:data.exploit.citizenship}}
- Faction: {{:data.exploit.faction}}
- Religion: {{:data.exploit.religion}}
- Fingerprint: {{:data.exploit.fingerprint}}
+ Name: {{:data.exploit.name}}
+ Sex: {{:data.exploit.sex}}
+ Species: {{:data.exploit.species}}
+ Age: {{:data.exploit.age}}
+ Rank: {{:data.exploit.rank}}
+ Home System: {{:data.exploit.home_system}}
+ Citizenship: {{:data.exploit.citizenship}}
+ Faction: {{:data.exploit.faction}}
+ Religion: {{:data.exploit.religion}}
+ Fingerprint: {{:data.exploit.fingerprint}}
+ Other Affiliation: {{:data.exploit.antagfaction}}
Acquired Information:
Notes:
{{:data.exploit.nanoui_exploit_record}}
diff --git a/sound/effects/ding.ogg b/sound/effects/ding.ogg
new file mode 100644
index 0000000000..33516f793f
Binary files /dev/null and b/sound/effects/ding.ogg differ
diff --git a/sound/effects/printer.ogg b/sound/effects/printer.ogg
new file mode 100644
index 0000000000..c9546490f1
Binary files /dev/null and b/sound/effects/printer.ogg differ
diff --git a/sound/voice/ManUp1.ogg b/sound/voice/ManUp1.ogg
index 9239a02e17..6fe58b5270 100644
Binary files a/sound/voice/ManUp1.ogg and b/sound/voice/ManUp1.ogg differ
diff --git a/vorestation.dme b/vorestation.dme
index cf58888b1a..3e10ce5108 100644
--- a/vorestation.dme
+++ b/vorestation.dme
@@ -70,6 +70,7 @@
#include "code\_helpers\type2type_vr.dm"
#include "code\_helpers\unsorted.dm"
#include "code\_helpers\vector.dm"
+#include "code\_onclick\_defines.dm"
#include "code\_onclick\adjacent.dm"
#include "code\_onclick\ai.dm"
#include "code\_onclick\click.dm"
@@ -84,6 +85,7 @@
#include "code\_onclick\hud\action.dm"
#include "code\_onclick\hud\ai.dm"
#include "code\_onclick\hud\alien_larva.dm"
+#include "code\_onclick\hud\fullscreen.dm"
#include "code\_onclick\hud\gun_mode.dm"
#include "code\_onclick\hud\hud.dm"
#include "code\_onclick\hud\human.dm"
@@ -587,8 +589,16 @@
#include "code\game\machinery\embedded_controller\embedded_program_base.dm"
#include "code\game\machinery\embedded_controller\simple_docking_controller.dm"
#include "code\game\machinery\kitchen\gibber.dm"
+#include "code\game\machinery\kitchen\icecream.dm"
#include "code\game\machinery\kitchen\microwave.dm"
#include "code\game\machinery\kitchen\smartfridge.dm"
+#include "code\game\machinery\kitchen\cooking_machines\_cooker.dm"
+#include "code\game\machinery\kitchen\cooking_machines\_cooker_output.dm"
+#include "code\game\machinery\kitchen\cooking_machines\candy.dm"
+#include "code\game\machinery\kitchen\cooking_machines\cereal.dm"
+#include "code\game\machinery\kitchen\cooking_machines\fryer.dm"
+#include "code\game\machinery\kitchen\cooking_machines\grill.dm"
+#include "code\game\machinery\kitchen\cooking_machines\oven.dm"
#include "code\game\machinery\pipe\construction.dm"
#include "code\game\machinery\pipe\pipe_dispenser.dm"
#include "code\game\machinery\pipe\pipelayer.dm"
@@ -926,6 +936,7 @@
#include "code\game\turfs\simulated\wall_icon.dm"
#include "code\game\turfs\simulated\wall_types.dm"
#include "code\game\turfs\simulated\walls.dm"
+#include "code\game\turfs\snow\snow.dm"
#include "code\game\turfs\space\space.dm"
#include "code\game\turfs\space\transit.dm"
#include "code\game\turfs\unsimulated\beach.dm"
@@ -1391,6 +1402,7 @@
#include "code\modules\mob\language\synthetic.dm"
#include "code\modules\mob\living\autohiss.dm"
#include "code\modules\mob\living\damage_procs.dm"
+#include "code\modules\mob\living\death.dm"
#include "code\modules\mob\living\default_language.dm"
#include "code\modules\mob\living\inventory.dm"
#include "code\modules\mob\living\life.dm"